FLUSH TABLES WITH READ LOCK 会阻塞所有写入、暂停 binlog 写入并导致主从复制中断,仅适用于秒级物理备份且需满足无长事务、从库已追平等严格条件。

全局读锁不是常规运维手段,FLUSH TABLES WITH READ LOCK 会阻塞所有写入并让主库无法推进 GTID/ binlog 位置,线上慎用。
为什么 FLUSH TABLES WITH READ LOCK 会让复制中断
这个命令不只是“锁表”,它会暂停整个实例的 DML 和 DDL,同时还会阻塞 binlog 写入(直到锁释放),导致从库 IO 线程拉不到新事件。如果你在主库执行它,从库的 Seconds_Behind_Master 会立刻飙升,且无法靠重连恢复——必须等锁释放、主库 binlog 续上才行。
- MySQL 5.7+ 中,即使启用了
gtid_mode=ON,该锁也不会推进gtid_executed,从库重连后仍会卡在旧位置 - 执行期间
SHOW PROCESSLIST里会出现状态为Waiting for global read lock的线程,但你找不到谁在等——其实是所有后续写操作都在排队 - 如果搭配
mysqldump --single-transaction使用,两者语义冲突:--single-transaction依赖 MVCC,而 FTWRL 是全局强一致锁,没必要也不该混用
FLUSH TABLES WITH READ LOCK 的唯一合理场景
仅适用于需要物理备份(如 cp 或 rsync 数据文件)且无法停机时,且必须满足:实例无活跃长事务、无大事务正在写入、已确认从库已追平(SELECT MASTER_POS_WAIT() 返回非 NULL)、备份过程极短(秒级)。
- 执行前务必先
SHOW MASTER STATUS记下File和Position(GTID 模式下记Executed_Gtid_Set) - 锁住后立即开始拷贝
datadir下的文件,不要做任何其他操作(包括SHOW类查询,某些版本会因元数据锁等待而卡住) - 备份完成后立刻
UNLOCK TABLES,延迟每多一秒,主从差距就扩大一秒
替代方案:用 mysqldump + 一致性快照更安全
绝大多数逻辑备份需求根本不需要 FTWRL。mysqldump --single-transaction --master-data=2 能在不锁表前提下拿到一致位点,原理是开启一个 REPEATABLE READ 事务并执行 SHOW MASTER STATUS,适合 InnoDB 表。
-
--single-transaction对非 InnoDB 表无效,遇到 MyISAM 表会自动退化为加表级锁,此时需单独处理 -
--master-data=2把位点写进 dump 文件注释里,=1则直接执行CHANGE MASTER TO,生产环境建议用 2 避免误执行 - 如果实例有大事务(比如未提交的 UPDATE),
--single-transaction会等它结束才开始 dump,可能卡住,此时应先KILL掉可疑连接
容易被忽略的细节:FTWRL 不等于“备份完成”
很多人执行完 FLUSH TABLES WITH READ LOCK 就以为可以慢慢备份了,其实锁只保证“表结构和数据静态”,但 ib_logfile、mysql-bin.*、relay-log 这些关键文件仍在变化或被持有句柄,直接拷贝可能损坏。
- 物理备份必须包含
ibdata1(共享表空间)、所有.ibd、ib_logfile*和当前mysql-bin.*—— 缺一不可 -
FLUSH LOGS可以强制滚动 binlog,方便只备份到某一个文件,但要在 FTWRL 之前做,否则会被阻塞 - 执行
UNLOCK TABLES后,立刻FLUSH LOGS并记录新 binlog 名称,才能确保备份与日志能衔接










