MySQL 三大存儲引擎支援不同鎖級別:MyISAM(表鎖)、BDB(頁鎖)、InnoDB(行鎖/表鎖)。理解鎖特性與調度機制,是高併發優化的基石。
| 鎖類型 | 開銷 | 加鎖速度 | 死鎖 | 粒度 | 衝突概率 | 併發度 | 典型引擎 |
|---|---|---|---|---|---|---|---|
| 表鎖 | 小 | 快 | 無 | 大 | 最高 | 最低 | MyISAM, MEMORY |
| 行鎖 | 大 | 慢 | 有 | 小 | 最低 | 最高 | InnoDB |
| 頁鎖 | 中 | 中 | 有 | 中 | 中 | 中 | BDB |
SHOW STATUS LIKE 'table%';
-- Table_locks_immediate: 立即獲取鎖的次數
-- Table_locks_waited: 等待鎖的次數(值高說明爭用嚴重)
SELECT 自動加。兼容讀鎖,阻塞寫鎖UPDATE/DELETE/INSERT 自動加。阻塞所有讀寫場景 A:長時間讀操作期間
SELECT:立即執行UPDATE:等待讀鎖釋放場景 B:長時間寫操作期間
SELECT:等待寫鎖釋放UPDATE:等待寫鎖釋放受 concurrent_insert 參數控制:
| 值 | 行為 |
|---|---|
| 0 | 禁用併發插入 |
| 1(默認) | 表無空洞(無刪除)時,允許讀時尾部插入 |
| 2 | 無論是否有空洞,均允許尾部併發插入 |
MySQL 默認 寫優先於讀。可調整:
--low-priority-updates:讀優先SET LOW_PRIORITY_UPDATES = 1:當前連接更新降級LOW_PRIORITY / HIGH_PRIORITY警告:盲目設讀優先可能導致長查詢「餓死」寫入。根治方案是讀寫分離(主從架構)。
SELECT ... LOCK IN SHARE MODE,兼容 S 鎖,阻塞 X 鎖SELECT ... FOR UPDATE、UPDATE/DELETE/INSERT,阻塞 S/X 鎖-- 有索引:行鎖
SELECT * FROM t1 WHERE uid = 'xxx' FOR UPDATE;
-- 無索引:退化為表鎖
SELECT * FROM t1 WHERE unindexed_col = 'xxx' FOR UPDATE;
結論:行鎖必須命中索引,否則升級為表鎖,併發度驟降。
REPEATABLE READ 隔離級別下,InnoDB 使用 Next-Key Lock(記錄鎖 + 間隙鎖)防止幻讀。
innodb_lock_wait_timeout(默認 50s)控制等待超時ERROR 1213 (HY000) 重試-- 查看當前進程與鎖狀態
SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS;
-- 殺死阻塞進程
KILL <thread_id>;
-- 手動鎖表(慎用)
LOCK TABLES t1 WRITE;
INSERT INTO t1 VALUES (2, 'xxx');
UNLOCK TABLES;
鎖是數據庫併發控制的核心。MyISAM 表鎖簡單但併發低;InnoDB 行鎖複雜但支撐高併發。實戰中:選對引擎、建對索引、縮短事務、用好隔離級別、上讀寫分離,是鎖優化的五大法寶。