鎖是資料庫並發控制的核心同步機制,用於滿足互斥存取需求。MySQL 按鎖粒度分為三大類:行級鎖(InnoDB)、表級鎖(MyISAM/MEMORY)、頁級鎖(BDB)。本文系統梳理三者特性、InnoDB 行鎖實現細節與死錯應對策略。
| 鎖類型 | 支援引擎 | 粒度 | 開銷 | 加鎖速度 | 死鎖 | 衝突概率 | 併發度 |
|---|---|---|---|---|---|---|---|
| 行級鎖 | InnoDB | 單行 | 最大 | 最慢 | 會發生 | 最低 | 最高 |
| 表級鎖 | MyISAM, MEMORY, InnoDB | 整表 | 最小 | 最快 | 不會 | 最高 | 最低 |
| 頁級鎖 | BDB | 一組相鄰行 | 中等 | 中等 | 會發生 | 中等 | 中等 |
SELECT ... LOCK IN SHARE MODE,兼容 S 鎖,阻塞 X 鎖。UPDATE/DELETE/SELECT ... FOR UPDATE,互斥 S/X 鎖。InnoDB 是透過索引項加鎖,而非直接鎖資料行(Oracle 鎖資料塊)。意味著:
實戰警示:未命中索引的 UPDATE/DELETE 會鎖全表,併發度驟降,極易引發鎖等待風暴。
LOCK TABLES t READ,多讀兼容,阻塞寫。LOCK TABLES t WRITE,互斥所有鎖。MyISAM/MEMORY 僅支援表鎖;InnoDB 在未走索引、DDL、鎖升級等場景會使用表鎖。
折衷方案:一次鎖定一頁(通常 16KB,含多行)。BDB 預設頁鎖,可退化為表鎖。現已較少使用,了解即可。
Next-Key Lock = 記錄鎖 + 間隙鎖,防止幻讀(RR 隔離級別預設)。
-- 事務 A UPDATE t SET v=1 WHERE pk=1; -- 鎖主鍵 1 UPDATE t SET v=2 WHERE pk=2; -- 等待主鍵 2 -- 事務 B UPDATE t SET v=3 WHERE pk=2; -- 鎖主鍵 2 UPDATE t SET v=4 WHERE pk=1; -- 等待主鍵 1 → 死鎖
或跨索引死鎖:事務 A 鎖主鍵等二級索引,事務 B 鎖二級索引等主鍵。
SHOW ENGINE INNODB STATUS 可查看最近死鎖詳情。理解鎖粒度與引擎支援矩陣是效能調優基石。InnoDB 行鎖「依賴索引」特性決定了:索引設計即鎖設計。死鎖不可完全消除,但透過統一存取順序、縮短事務、必要時升級粒度,可將影響降至最低。