MySQL 鎖機制總結(二):核心概念與 InnoDB 鎖體系
前言
MySQL 採用插件式存儲引擎架構,鎖機制分為 Server 層鎖 與 存儲引擎層鎖。本文聚焦 InnoDB,系統介紹核心鎖概念。
1. 基本並發控制策略
| 策略 | 核心思想 | 優點 | 缺點 | MySQL 採用 |
| 悲觀鎖 | 假設衝突常發生,先加鎖再訪問 | 數據強一致性 | 並發度低、易死鎖 | ✓(主流 DBMS 均採用) |
| 樂觀鎖 | 假設衝突少,讀寫不加鎖,提交時用版本號/時間戳檢查 | 高並發、無死鎖 | 衝突重試開銷大、業務邏輯複雜 | 應用層實現(版本號欄位) |
| MVCC | 多版本並發控制,讀不加鎖,讀寫不衝突 | 讀寫並行、快照隔離 | 存儲開銷、寫寫仍需鎖 | ✓(InnoDB 核心機制) |
2. 兩階段鎖協議 (2PL)
- 加鎖階段:事務開始 → 可獲取鎖、不可釋放鎖
- 解鎖階段:事務提交/回滾 → 釋放所有鎖、不可獲取新鎖
- 保證調度可串行化,是數據庫實現隔離性的理論基礎
3. 意向鎖
- 表級鎖,表示「意圖」在表中某行加共享鎖(IS)或排他鎖(IX)
- 目的:快速判斷表鎖與行鎖衝突,避免掃描全表行鎖
- 兼容性:IS/IX 與 表 S/X 互斥,IS/IX 之間兼容
4. 表鎖與行鎖
| 鎖類型 | 粒度 | 模式 | 典型場景 |
| 表鎖 | 表 | S, X, IS, IX | DDL、全表掃描、顯式 LOCK TABLES |
| 行鎖 (Record Lock) | 單行記錄 | S (共享), X (排他) | WHERE 命中唯一索引的精確查詢/更新 |
| 間隙鎖 (Gap Lock) | 索引間隙 | S, X | RR 隔離級別範圍查詢,防止幻讀 |
| 臨鍵鎖 (Next-Key Lock) | 記錄+間隙 | S, X | RR 隔離級別默認行鎖 = 記錄鎖 + 間隙鎖 |
| 插入意向鎖 | 間隙 | X | INSERT 前獲取,多事務同間隙插入不阻塞(除非同值) |
5. 元數據鎖 (MDL, Metadata Lock)
- 保護表結構、視圖、觸發器等元數據
- DML(SELECT/INSERT/UPDATE/DELETE)獲取 MDL_S(共享)
- DDL(ALTER/DROP/CREATE INDEX)獲取 MDL_X(排他)
- 防止 DDL 與並發 DML 衝突(如 ALTER TABLE 時阻塞新查詢)
- MySQL 5.5+ 引入,8.0 優化了 MDL 子系統
6. 自增鎖 (AUTO-INC Lock)
- 專用表級鎖,保護
AUTO_INCREMENT 計數器
- 三種模式由
innodb_autoinc_lock_mode 控制(0/1/2),影響並發插入性能
- 8.0 默認模式 2(Interleaved),無自增鎖,性能最佳但可能有間隙
7. 死鎖
- 多事務循環等待對方持有的鎖
- InnoDB 自動檢測並回滾代價最小的事務(權重:修改行數、鎖數、事務權重)
SHOW ENGINE INNODB STATUS 查看最近死鎖詳情
- 預防:固定加鎖順序、縮短事務、避免長事務、合理索引減少掃描範圍
InnoDB 行鎖實現關鍵點
- 鎖是加在索引記錄上,非索引列更新會升級為表鎖
- RR 隔離級別默認 Next-Key Lock,RC 級別僅 Record Lock(需配合
innodb_locks_unsafe_for_binlog)
- 鎖等待超時由
innodb_lock_wait_timeout 控制(默認 50s)