防止 mysqld 服務進程與維護工具(myisamchk)或多客戶端之間對同一張表的並發讀寫衝突,避免資料不一致或索引損壞。
| 維度 | 內部鎖定 | 外部鎖定 |
|---|---|---|
| 實作層級 | MySQL 服務層 | 作業系統檔案鎖(fcntl/lockf) |
| 適用引擎 | 所有引擎 | 僅 MyISAM/ISAM |
| 跨平台 | 是 | 視檔案系統支援度(NFS 常失效) |
| 預設狀態 | 永遠啟用 | Linux 預設關閉(skip-locking=ON) |
| 操作介面 | SQL: LOCK TABLES / UNLOCK TABLES | 啟動參數 --external-locking |
mysql -e "LOCK TABLES tbl_name READ; FLUSH TABLES;"
myisamchk tbl_name
mysql -e "UNLOCK TABLES;"
mysql -e "LOCK TABLES tbl_name WRITE; FLUSH TABLES;"
cp tbl_name.* /backup/dir/
myisamchk --recover tbl_name # 或 OPTIMIZE TABLE tbl_name
mysql -e "FLUSH TABLES; UNLOCK TABLES;"
關鍵點:修復後必須再次 FLUSH TABLES,讓服務重新載入新索引檔(.MYI),否則服務繼續使用舊快取導致查詢錯誤。
# 啟用外部鎖定啟動
mysqld --external-locking
# 查看狀態
mysqladmin variables | grep skip_locking
# skip_locking = OFF 表示外部鎖定生效
skip_locking=OFF:可直接運行 myisamchk,服務與工具協作鎖定。前置需 mysqladmin flush-tables。skip_locking=ON:外部鎖定失效,必須停服務 或改用內部鎖定協議。LOCK TABLES。ALGORITHM=INPLACE)無需鎖表。mysqldump --single-transaction 或 XtraBackup(物理熱備)。LOCK TABLES ... WRITE 會阻塞所有寫入,謹慎使用。innodb_trx。