MySQL 優化系列 (五):MyISAM 表鎖深度解析與並發調優實戰
MyISAM 僅支援**表級鎖**,無行鎖、無交易。理解其鎖模式、相容性、並發插入條件與調度優先權,對維護舊系統、讀密集場景仍具價值。本文系統整理 MyISAM 鎖機制核心知識點。
鎖模式與相容性
| 鎖類型 | 別名 | 適用操作 | 相容性 |
| 讀鎖 | Shared Lock (S-Lock) | SELECT | 讀-讀 **相容**;讀-寫 **互斥** |
| 寫鎖 | Exclusive Lock (X-Lock) | INSERT/UPDATE/DELETE | 寫-讀 **互斥**;寫-寫 **互斥** |
結論:MyISAM **讀寫串行**,寫操作獨佔整張表。
自動加鎖行為
SELECT 前自動加**讀鎖** (涉及所有表)
INSERT/UPDATE/DELETE 前自動加**寫鎖**
- 無需用戶干預,語句結束自動釋放
顯式鎖表:LOCK TABLES
-- 讀鎖 (允許並發插入需加 LOCAL)
LOCK TABLES tbl_name READ LOCAL;
-- 寫鎖
LOCK TABLES tbl_name WRITE;
-- 釋放
UNLOCK TABLES;
- 限制:鎖定後**只能存取已鎖定的表**,不可存取未鎖表
- 無鎖升級:MySQL 一次性獲取語句需的所有鎖,**無死鎖**
- 重複別名需重複鎖:
LOCK TABLES t AS a READ, t AS b WRITE
並發插入
MyISAM 在**特定條件**下支援「查詢與插入並發」:
concurrent_insert 值 | 行為 |
| 0 (NEVER) | 完全禁止並發插入 |
| 1 (AUTO, 預設) | 表**無空洞** (無刪除/更新導致碎片) 時,允許**表尾並發插入** |
| 2 (ALWAYS) | **無論是否有空洞**,皆允許表尾並發插入 |
空洞指:DELETE、UPDATE 變長欄位導致資料檔案中間出現空洞。OPTIMIZE TABLE 可整理消除空洞。
鎖調度優先權 (讀寫競爭時誰先得鎖)
預設:**寫優先於讀** (MySQL 認為寫請求更重要)。可調整:
| 方法 | 效果 |
啟動參數 --low-priority-updates | 全域降低寫優先權,讀優先 |
SET LOW_PRIORITY_UPDATES = 1 | 當前連線降低寫優先權 |
語句加 LOW_PRIORITY | 單條 INSERT/UPDATE/DELETE 降低優先權 |
語句加 HIGH_PRIORITY | 單條 SELECT/INSERT 提高優先權 |
語句加 DELAYED | INSERT/REPLACE 放入隊列延遲寫入 (極高並發寫入優化) |
max_write_lock_count | 寫鎖達此值暫時降低寫優先權,給讀機會 |
實務調優建議
- 讀多寫少:啟用
low-priority-updates、concurrent_insert=2、定期 OPTIMIZE TABLE
- 寫入高峰:使用
INSERT DELAYED (日誌類)、批次 INSERT、考慮遷移 InnoDB
- 長時間查詢阻塞寫入:拆分大查詢、加
HIGH_PRIORITY 給關鍵寫入
- 監控指標:
Table_locks_waited (等待鎖次數)、Table_locks_immediate (立即獲得鎖次數)
時代背景: MyISAM 為 5.5 前預設引擎。現代應用**強烈建議遷移 InnoDB** 獲得行鎖、交易、MVCC、崩潰恢復等核心能力。MyISAM 僅適合純只讀、全文搜尋 (5.6 前)、極簡日誌等邊緣場景。
- 上一篇文章: MySQL 日期時間函數查詢速查:NOW、CURDATE、DATE_FORMAT 等常用用法
- 下一篇文章: MySQL 更新中文欄位報錯 1366 Incorrect string value 徹底解決:四層編碼統一
Copyright ©
程式碼之家 All Rights Reserved