MySQL 的鎖機制根據鎖定粒度可分為三個層級:頁級鎖、表級鎖與行級鎖。不同儲存引擎支援的鎖層級各不相同:
BDB 引擎,鎖定粒度介於表與行之間,較少見。MyISAM、MEMORY 及早期的 ISAM 採用此機制,鎖定整張表,實作簡單但並發性能較低。InnoDB 為典型代表,鎖定單筆資料,並發性能最佳,是現代應用最常用的選擇。LOCK 等待狀態。MySQL 透過寫入隊列與讀取隊列協調並發存取:
可透過 LOW_PRIORITY 與 HIGH_PRIORITY 調整隊列優先順序。
-- 客戶端 1:執行耗時查詢
SELECT COUNT(*) FROM content GROUP BY content;
-- 客戶端 2:嘗試更新(被阻塞 30 秒)
UPDATE content SET content = 'I love you' WHERE id = 444;
-- Query OK, 1 row affected (30.68 sec)
-- 終止客戶端 1 後,再次更新(僅 20 毫秒)
UPDATE content SET content = 'I hate you' WHERE id = 444;
-- Query OK, 1 row affected (0.02 sec)
解析:客戶端 1 持有讀鎖,導致客戶端 2 的更新請求進入寫鎖隊列;讀鎖釋放(SHOW PROCESSLIST 顯示 COPY TO TMP TABLE 結束)後,更新始得執行。
在 Replication 架構下,可為 Master 與 Slave 配置不同鎖策略(前提是 SQL 已經過優化),以達到最佳效能平衡。