MySQL 的鎖機制是其并發控制的核心,直接影響數據庫的性能、一致性與可用性。本文將從底層原理、鎖的分類、實現機制、鎖的粒度、鎖的兼容性、死鎖處理、InnoDB 的行鎖實現、MVCC 與鎖的關系等多個維度,進行硬核、深度解析,適用于希望深入理解 MySQL 并發控制機制的開發者與 DBA。
一、MySQL 鎖機制概覽
MySQL 的鎖機制主要由存儲引擎層實現,不同引擎的鎖策略不同:
- MyISAM:僅支持表級鎖(Table-level Locks)
- InnoDB:支持行級鎖(Row-level Locks)、表級鎖、意向鎖、間隙鎖、臨鍵鎖等,是目前最復雜的鎖系統
我們以 InnoDB 為主進行深度剖析。
二、InnoDB 鎖的類型與分類
1. 按粒度劃分
鎖類型 | 粒度 | 說明 |
---|---|---|
表級鎖 | Table Lock | 鎖整張表,開銷小,但并發低 |
行級鎖 | Row Lock | 鎖具體行,高并發,開銷大 |
頁級鎖 | Page Lock | 鎖一頁(如 16KB),介于表與行之間(BDB 支持,InnoDB 不用) |
InnoDB 實現的是邏輯行級鎖,物理上通過索引項加鎖實現。
2. 按模式劃分(共享鎖 vs 排他鎖)
鎖類型 | 別名 | SQL 語法 | 兼容性 |
---|---|---|---|
共享鎖(S Lock) | 讀鎖 | SELECT ... LOCK IN SHARE MODE | 多個 S 鎖可共存 |
排他鎖(X Lock) | 寫鎖 | SELECT ... FOR UPDATE 或 UPDATE/DELETE | 僅一個 X 鎖,不與 S/X 兼容 |
兼容性矩陣:
請求 \ 持有 | S(共享) | X(排他) |
---|---|---|
S | ? 兼容 | ? 不兼容 |
X | ? 不兼容 | ? 不兼容 |
3. 意向鎖(Intention Locks)
目的:提高表級鎖與行級鎖的兼容性檢測效率。
- IX(Intention Exclusive):事務打算在某些行上加 X 鎖
- IS(Intention Shared):事務打算在某些行上加 S 鎖
意向鎖的規則:
- 意向鎖是表級鎖,但表示的是對行加鎖的“意圖”
- 意向鎖之間完全兼容(IS 與 IX 可共存)
- 真正的沖突發生在行鎖之間
示例:
-- 事務 T1
BEGIN;
SELECT * FROM t WHERE id = 1 FOR UPDATE; -- 加 IX + 行 X 鎖
此時其他事務若想對整表加 X 鎖(如 LOCK TABLES t WRITE
),會檢測到 IX,拒絕加鎖。
4. 行鎖的實現方式:記錄鎖(Record Lock)
- 鎖住索引上的單個記錄
- 如果表沒有主鍵,InnoDB 會隱式創建一個 6 字節的
ROWID
作為聚簇索引,行鎖基于此
-- 假設 id 是主鍵
SELECT * FROM t