flush tables with read lock 仅适用于myisam等非事务表备份、已停写且无延迟的从库离线备份,或需强一致性快照且可接受数分钟只读窗口的场景;它不等待长事务结束,阻塞后续dml/ddl及commit,与--single-transaction适用前提完全不同。

不要在主库上直接用 FLUSH TABLES WITH READ LOCK 做备份,除非你清楚它会让整个库停写数分钟甚至更久。
什么时候真得用 FLUSH TABLES WITH READ LOCK
只在以下明确场景中考虑使用:
- 备份目标是 MyISAM 或其他不支持事务的存储引擎表 —— 因为
--single-transaction对它们无效 - 你正在从一个已停止写入流量的从库做离线全量逻辑备份,且该从库没有延迟、不承担读请求
- 你需要一份强一致性快照(比如审计、合规归档),且能接受数分钟级别的只读窗口
注意:FLUSH TABLES WITH READ LOCK 不会等待正在执行的长事务结束,它只阻塞后续的 DML/DDL,但已开启的事务仍可继续提交——这意味着锁生效前的并发更新可能还没落盘,备份结果未必“绝对一致”,只是“锁住之后不再变”。
FLUSH TABLES WITH READ LOCK 和 --single-transaction 的本质区别
二者不是替代关系,而是适用前提完全不同:
-
--single-transaction依赖 InnoDB 的 MVCC 和可重复读隔离级别,启动一个事务后获取一致性视图,期间允许其他事务正常读写 -
FLUSH TABLES WITH READ LOCK是物理层强制拦截,所有线程的INSERT/UPDATE/DELETE/ALTER TABLE全部挂起,连COMMIT都会被卡住 - 如果库中混用 InnoDB 和 MyISAM 表,
--single-transaction只保 InnoDB 一致,MyISAM 仍需FTWRL或停写保障
执行 mysqldump --single-transaction 时,MySQL 实际不会加全局锁;而显式执行 FLUSH TABLES WITH READ LOCK 后,哪怕只执行 1 秒就 UNLOCK TABLES,中间任何未完成的 DML 都会阻塞到解锁那一刻。
容易被忽略的三个坑
实际操作中最常栽跟头的地方:
- 在主库上执行后忘记及时
UNLOCK TABLES,或者客户端异常断开但 DBA 没监控到——锁会一直挂着,业务写请求全部堆积,连接数暴涨 - 误以为加了
FTWRL就能安全做ALTER TABLE:其实不行,DDL 本身需要 MDL 写锁,而FTWRL已经占着全局读锁,DDL 会直接被拒绝或无限等待 - 用
FTWRL备份从库时没确认Seconds_Behind_Master = 0,结果备份的是落后主库几分钟的数据,且备份期间 relay log 停止应用,延迟越拉越大
真正稳妥的做法往往是组合策略:对 InnoDB 表用 --single-transaction,对非事务表单独处理(如停写 + FTWRL + 快速 dump),再通过 pt-table-checksum 校验一致性。全局锁不是银弹,而是兜底手段。











