鎖是資料庫並發控制的核心機制。MySQL 不同儲存引擎支援不同粒度的鎖:MyISAM/MEMORY 表鎖、BDB 頁鎖、InnoDB 行鎖。本文系統梳理鎖類型、相容矩陣、死鎖成因與處理、鎖升級與調優策略,構建完整的 MySQL 鎖知識體系。
| 儲存引擎 | 鎖粒度 | 死鎖可能 | 並發特性 |
|---|---|---|---|
| MyISAM | 表鎖 | ❌ 無 | 讀讀並發、讀寫互斥、寫寫互斥 |
| MEMORY | 表鎖 | ❌ 無 | 全記憶體、鎖開銷極低 |
| BDB | 頁鎖 (8KB) | ✅ 可能 | 介於表鎖/行鎖間 |
| InnoDB | 行鎖 (預設) | ✅ 可能 | 高並發、支援事務隔離 |
| InnoDB | 表鎖 (LOCK TABLES) | ❌ 無 | 顯式鎖表時退化為表鎖 |
| 當前鎖 \ 請求鎖 | READ LOCK | WRITE LOCK |
|---|---|---|
| 無鎖 | ✅ 兼容 | ✅ 兼容 |
| READ LOCK | ✅ 兼容 | ❌ 阻塞 |
| WRITE LOCK | ❌ 阻塞 | ❌ 阻塞 |
[mysqld]
# 降低寫鎖優先級,讓讀請求插隊
low_priority_updates = 1
# 或會話級
SET LOW_PRIORITY_UPDATES = 1;
# 單條語句指定
INSERT LOW_PRIORITY INTO ...
UPDATE LOW_PRIORITY ...
SELECT HIGH_PRIORITY ...
# 閾值觸發讀請求提權
max_write_lock_count = 100 # 連續 100 次寫鎖後暫時提升讀優先級
-- Session A -- Session B
BEGIN; BEGIN;
UPDATE account SET bal=bal-100 WHERE id=1; -- 鎖 id=1
UPDATE account SET bal=bal+100 WHERE id=2; -- 鎖 id=2
UPDATE account SET bal=bal+100 WHERE id=2; -- 等待 id=2
UPDATE account SET bal=bal-100 WHERE id=1; -- 等待 id=1 → 死鎖
SHOW ENGINE INNODB STATUS\G 查看 LATEST DETECTED DEADLOCK 詳細資訊ERROR 1213 (HY000): Deadlock found 重試邏輯(指數退避 + 隨機抖動)**無索引 = 表鎖**。所有 WHERE/JOIN/ORDER BY 條件欄位必須有索引,EXPLAIN 驗證 type != ALL。
多表操作**統一按表名/主鍵順序**加鎖,應用層封裝統一存取路徑。
| 隔離級別 | 鎖行為 | 適用場景 |
|---|---|---|
| READ UNCOMMITTED | 不加鎖讀 | 極少用 |
| READ COMMITTED | Record Lock,無 Gap Lock | 高並發、無幻讀需求 |
| REPEATABLE READ (預設) | Next-Key Lock | 一般業務、防幻讀 |
| SERIALIZABLE | 表鎖/範圍鎖 | 極高一致性需求 |
高並發場景建議 READ COMMITTED + binlog_format=ROW,大幅減少 Gap Lock 衝突。
UPDATE ... SET val=val+1, version=version+1 WHERE id=? AND version=?-- 當前鎖等待
SELECT * FROM performance_schema.data_locks;
SELECT * FROM sys.schema_table_lock_waits;
SELECT * FROM sys.innodb_lock_waits;
-- 歷史死鎖
SHOW ENGINE INNODB STATUS\G
-- 表鎖統計
SHOW STATUS LIKE 'Table_locks%';
-- Table_locks_immediate: 立即獲得
-- Table_locks_waited: 等待過的
-- 獲取命名鎖 (阻塞至取得或超時)
SELECT GET_LOCK('order_process_123', 10); -- 返回 1 成功
-- 業務邏輯
...
-- 釋放
SELECT RELEASE_LOCK('order_process_123');
用於**分散式業務邏輯互斥**(如訂單處理、排程單例),不依賴資料表記錄。
MySQL 鎖機制的核心矛盾:**一致性 vs 並發度**。InnoDB 行鎖配合 MVCC 實現了高並發下的 ACID,但也帶來了死鎖、Gap Lock 衝突、熱點行競爭等複雜現象。掌握**加鎖規則、索引設計、事務縮短、隔離級別選擇、監控體系**五大支柱,才能駕馭鎖而非被鎖困住。