首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

深度解析 MySQL FLUSH TABLES WITH READ LOCK (FTWRL) 原理、影響與備份最佳實踐

     編輯:MySQL 綜合教學

深度解析 MySQL FLUSH TABLES WITH READ LOCK (FTWRL) 原理、影響與備份最佳實踐

FLUSH TABLES WITH READ LOCK (FTWRL) 是 MySQL 獲取一致性邏輯備份 (如 mysqldump --master-data) 的核心命令。它通過持有全局元數據鎖 (MDL) 阻塞寫入、關閉表緩存、阻塞事務提交,確保備份數據與 Binlog 位點一致。但因其「殺傷力」極大,輕易導致主庫業務掛起、從庫複製延遲。本文深度拆解其三階段執行流程、阻塞場景、主備切換風險,並對比 Percona 等優化方案。

一、 FTWRL 三大核心步驟

  1. 上全局讀鎖 (lock_global_read_lock):獲取 MDL_key::GLOBAL 共享鎖,阻塞所有 DDL、DML 寫入操作 (SELECT 不受影響)。
  2. 清理表緩存 (close_cached_tables):遍歷 table_def_cache,關閉所有未使用的表對象;對正在使用的表,更新全局版本號並等待引用計數歸零 (MDL_wait::timed_wait)。
  3. 上全局 COMMIT 鎖 (make_global_read_lock_block_commit):獲取 LOCK_commit 排他鎖,阻塞活躍事務提交,確保 Binlog 位點不再前進。

二、 各階段對業務的影響與阻塞鏈

階段阻塞對象典型現象風險等級
全局讀鎖所有 UPDATE/INSERT/DELETE/DDL寫入請求堆積,show processlist 顯示 Waiting for global read lock★★★★☆
關閉表緩存訪問同一表的所有 SELECT/UPDATE大查詢未結束導致後續會話 Waiting for table flush,**連 SELECT 也被阻塞**★★★★★
全局 COMMIT 鎖活躍事務 COMMIT長事務提交卡住,Binlog 位點固定★★★★☆

關閉表緩存導致「全庫掛起」的經典鏈路

會話 A: SELECT * FROM huge_table ... (大查詢執行中)
會話 B: FLUSH TABLES WITH READ LOCK (進入 close_cached_tables)
   -> 更新 table_def_cache 版本號
   -> 發現 huge_table 仍被 A 引用 (ref_count>0),加入等待隊列
會話 C: SELECT * FROM huge_table ... (正常查詢)
   -> 發現版本號變化,判定舊版本失效,同樣加入等待隊列
結果: B 和 C 均處於 "Waiting for table flush",直到 A 結束釋放引用。

三、 主備切換場景的隱形殺手:SET GLOBAL read_only=1

主備切換時需將舊主設為只讀防止雙寫。read_only=1 內部同樣執行:

  1. lock_global_read_lock() 阻塞新寫入
  2. make_global_read_lock_block_commit() 阻塞活躍事務提交

**無 close_cached_tables 步驟,但同樣會被長事務/大查詢卡住導致設置失敗。** 切換腳本必須預判並處理超時、強殺長事務邏輯。

四、 FTWRL 在不同備份工具中的角色

備份類型典型工具是否需 FTWRL核心依賴
邏輯備份mysqldump --single-transaction --master-data**需要** (獲取一致性 Binlog 位點)InnoDB MVCC + FTWRL 階段 1&3
邏輯備份mysqldump --lock-all-tables --master-data**需要** (MyISAM 無 MVCC)FTWRL 全階段
物理備份xtrabackup / MySQL Enterprise Backup**不需要**複製數據文件 + 拷貝 Redo Log (LSN)

關鍵洞察:對純 InnoDB 環境,FTWRL 前兩階段其實多餘

  • InnoDB MVCC 保證 --single-transaction 可讀一致性視圖,無需全局讀鎖阻塞寫入。
  • InnoDB Redo Log 保證崩潰恢復,無需 close_cached_tables 強刷脏頁。
  • **唯一剛需**是階段 3:阻塞事務提交以獲取一致性 Binlog 位點 (用於搭建從庫)。

五、 官方與 Percona 的優化演進

  1. MySQL 5.5:mysqldump 單表鎖定,備份完一張表釋放該表鎖,但已備份表鎖不釋放,直到結束。
  2. MySQL 5.6:引入 InnoDB Savepoint,備份完一張表即釋放該表鎖,大幅降低鎖持有時間 (Bug#71017)。
  3. Percona Backup Locks (5.6+):引入 LOCK TABLES FOR BACKUP,僅阻塞 DDL、非事務表寫入,**不阻塞 InnoDB DML、不關閉表緩存、不阻塞 COMMIT**,專為物理/邏輯備份設計,極大降低業務影響。
    參考:Percona Blog

六、 生產環境最佳實踐建議

  1. 首選物理熱備:xtrabackup --slave-info --safe-slave-backup,無鎖、可增量、恢復快。
  2. 邏輯備份必加參數:mysqldump --single-transaction --master-data=2 --quick --max_allowed_packet=1G。
  3. 從庫備份**:在只讀從庫執行 FTWRL,避免主庫業務受影響;監控 Seconds_Behind_Master 防延遲過大。
  4. 避開業務高峰**:低峰期執行,設置 innodb_max_dirty_pages_pct 降低刷盤壓力。
  5. 監控鎖等待**:performance_schema.metadata_locks、sys.schema_table_lock_waits 實時告警。

七、 總結

FTWRL 是一把「雙刃劍」:它是獲取一致性 Binlog 位點的唯一標準手段,但其全局鎖、關閉表緩存、阻塞提交三重機制極易引發生產事故。理解其內部流程、識別阻塞鏈、根據存儲引擎選擇備份策略 (物理優於邏輯、從庫優於主庫、Backup Locks 優於 FTWRL),是 DBA 進階的必修課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved