當執行表檢查、修復、備份或大量資料變更時,必須防止 MySQL 服務線程與維護工具(myisamchk/isamchk)或其他客戶端同時存取同一張表,避免資料損壞或結果不一致。MySQL 提供兩層鎖定機制:內部鎖(服務層邏輯鎖)與 外部鎖(檔案系統層鎖)。
-- 鎖定
LOCK TABLES tbl_name {READ | WRITE} [, tbl_name {READ | WRITE}] ...
-- 解鎖
UNLOCK TABLES
LOCK TABLES、連線關閉、線程結束均自動釋放。READ:myisamchk 檢查表、mysqldump 一致性備份。WRITE:myisamchk -r 修復表、OPTIMIZE TABLE、大量批次更新。fcntl/flock)防止多進程同時修改同一資料檔。--skip-locking / skip_external_locking=ON),因部分檔案系統(NFS、SMB)鎖不可靠。SHOW VARIABLES LIKE 'skip_external_locking'; → OFF 表啟用,ON 表禁用。mysqladmin flush-tables 刷新並關閉表檔。myisamchk 檢查/修復,服務與工具透過檔案鎖協作。flush-tables 讓服務感知新索引檔。-- 1. 客戶端加 READ 鎖 + 刷新
mysql -u root -p db_name
LOCK TABLE tbl_name READ;
FLUSH TABLES;
-- 2. 執行檢查
myisamchk tbl_name
# 或 isamchk tbl_name
-- 3. 釋放鎖
UNLOCK TABLES;
原理: READ 鎖防寫不防讀,FLUSH TABLES 強制服務關閉檔案描述符、刷新緩衝區,讓 myisamchk 看到最新磁碟狀態。
-- 1. 客戶端加 WRITE 鎖 + 刷新
mysql -u root -p db_name
LOCK TABLE tbl_name WRITE;
FLUSH TABLES;
-- 2. 備份原檔 + 執行修復
cp tbl_name.* /backup/dir/
myisamchk --recover tbl_name
# 或 isamchk --recover tbl_name
-- 3. 再次刷新 + 釋放鎖
FLUSH TABLES;
UNLOCK TABLES;
cp tbl_name.* 留存回滾點。LOCK TABLES ... WRITE 搭配 FLUSH TABLES,並在低峰期執行。innodb_force_recovery 或線上備份工具(xtrabackup、mysqlbackup)。OPTIMIZE TABLE、ANALYZE TABLE 已支援線上 DDL,大幅降低鎖表需求。理解內/外部鎖差異、掌握檢查修復標準協議,是 DBA 守護資料完整性的基本功。隨著 InnoDB 成為預設引擎、線上 DDL 普及,傳統鎖表操作逐漸退出歷史舞台,但對 MyISAM 存量系統、緊急搶修場景,本文協議仍是「救命稻草」。