鎖是資料庫實現並發控制的核心機制。MySQL 採用插件式儲存引擎架構,不同引擎支援不同粒度的鎖:
| 鎖類型 | 粒度 | 開銷 | 加鎖速度 | 死鎖風險 | 並發度 | 適用場景 |
|---|---|---|---|---|---|---|
| 表鎖 | 整張表 | 最小 | 最快 | 無 | 最低 | 以讀為主、少量索引條件更新(Web 應用) |
| 頁鎖 | 資料頁 | 中等 | 中等 | 有 | 中等 | 折衷方案,較少見 |
| 行鎖 | 單行記錄 | 最大 | 最慢 | 有 | 最高 | 大量並發索引條件更新、OLTP 系統 |
-- 加讀鎖(共享鎖)
LOCK TABLES t9 READ;
-- 加寫鎖(排他鎖)
LOCK TABLES t9 WRITE;
-- 查看鎖狀態
SHOW GLOBAL STATUS LIKE 'table_locks%';
-- Table_locks_immediate: 立即獲取鎖次數
-- Table_locks_waited: 等待鎖次數(越高爭用越嚴重)
-- 解鎖
UNLOCK TABLES;
系統變數 concurrent_insert:
LOCK TABLES t9 READ LOCAL 可在滿足並發插入條件時允許其他 Session 表尾插入。
MyISAM 寫鎖優先於讀鎖:即使讀請求先到達等待隊列,後到的寫請求會插隊到讀請求之前。大量更新會導致查詢「餓死」。
low-priority-updates=1:降低更新優先級SET LOW_PRIORITY_UPDATES=1INSERT/UPDATE/DELETE LOW_PRIORITY ...max_write_lock_count:讀鎖達到閾值時暫時降低寫優先級SELECT ... LOCK IN SHARE MODESELECT ... FOR UPDATE、UPDATE、DELETE、INSERT-- 查看最近死鎖資訊
SHOW ENGINE INNODB STATUS\G
-- 關鍵配置
innodb_lock_wait_timeout = 50 -- 鎖等待超時(秒)
innodb_deadlock_detect = ON -- 死鎖檢測(預設開啟)
SELECT ... FOR UPDATE NOWAIT/SKIP LOCKED(8.0+)減少等待Innodb_row_lock_waits:等待次數Innodb_row_lock_time_avg:平均等待時間Innodb_row_lock_time_max:最大等待時間Table_locks_waited(MyISAM):表鎖等待次數