InnoDB 存儲引擎實現了多種粒度的鎖機制,其中行級鎖是支撐高並發事務處理的核心。根據鎖定範圍與模式,主要分為三類:
僅鎖定索引中具體的一條記錄。例如 SELECT * FROM t WHERE id = 10 FOR UPDATE 會在主鍵 id=10 的聚簇索引記錄上加排他記錄鎖,阻止其他事務修改或刪除該行。
鎖定索引記錄之間的「開區間」,不包含邊界值本身。其目的是防止幻讀:在可重複讀隔離級別下,若事務 A 查詢 WHERE id > 10 AND id < 20,InnoDB 會在 (10, 20) 間隙加共享間隙鎖,阻止事務 B 插入 id=15 的新行。
記錄鎖與間隙鎖的組合,鎖定範圍為「半開半閉區間」,即 (下界, 上界]。InnoDB 預設使用 Next-Key Lock 解決幻讀問題。例如主鍵值為 10、20、30 時,Next-Key Lock 覆蓋範圍包括:(-∞, 10]、(10, 20]、(20, 30]、(30, +∞)。
| SQL 類型 | 鎖模式 | 說明 |
|---|---|---|
SELECT ... FOR UPDATE | Next-Key Lock (X) | 掃描到的所有索引記錄均加排他 Next-Key 鎖 |
INSERT ... VALUES | Record Lock (X) | 僅對插入行加排他記錄鎖,不阻塞間隙前插入;唯鍵衝突時對衝突記錄加共享鎖 |
INSERT ... SELECT | Record Lock (X) / Next-Key Lock (S) | 目標表加排他記錄鎖;源表若開啟 binlog 則加共享 Next-Key 鎖 |
UPDATE ... WHERE | Next-Key Lock (X) | 搜尋條件命中的每條記錄加排他 Next-Key 鎖 |
DELETE ... WHERE | Next-Key Lock (X) | 同 UPDATE,掃描到的記錄加排他 Next-Key 鎖 |
| 外鍵檢查 | Record Lock (S) | 插入/更新/刪除父子表時,對被引用記錄加共享行鎖 |
InnoDB 引入專用 AUTO-INC 表鎖模式:只在語句執行期間持有,不等到事務結束,大幅提升高並發插入性能。已初始化的自增值讀取無需加鎖。
READ COMMITTED 隔離級別 + binlog_format=ROW 降低間隙鎖使用Innodb_row_lock_waits、Innodb_row_lock_time_avg 等指標,及時發現鎖爭用