mysqldump加--master-data卡住是因为其默认触发flush tables with read lock,需获取全局mdl锁,而未提交事务、长查询或dml会阻塞该锁;--single-transaction无法绕过此锁,且lock_wait_timeout对其无效。

mysqldump加--master-data为什么会卡住
因为--master-data=1或--master-data=2默认触发FLUSH TABLES WITH READ LOCK,这个操作必须获取全局 MDL 锁(Metadata Lock),而只要存在未提交事务、长查询或正在执行的 DML,锁就拿不到,mysqldump就会无限等待。
常见现象包括:mysqldump卡在“Dumping data for table…”前不动;SHOW PROCESSLIST里状态是Waiting for table metadata lock;错误日志出现Lock wait timeout exceeded。
-
--master-data=1和=2行为完全一致,区别仅在于 binlog 位点是否以注释形式写入 dump 文件 - 即使加了
--single-transaction,只要同时用了--master-data,FTWRL 仍会执行——--single-transaction无法绕过这个锁 -
lock_wait_timeout参数对它无效:这个参数只控制单条语句等 MDL 的上限(默认≈1年),不是mysqldump自身的超时机制
怎么避开FTWRL但还能拿到binlog位点
核心思路是放弃--master-data,改用不触发全局锁的方式手动或自动记录位点。前提是全库为 InnoDB 引擎,且无 MyISAM 表(否则无法规避 FTWRL)。
- 用
--dump-slave=2(MySQL 5.6+)或--source-data=2(8.0.22+):它们基于当前事务快照输出 binlog 位置,不加 FTWRL - 手动分两步:先执行
mysql -e "SHOW MASTER STATUS\G" | grep -E "File|Position"记下位点,再用--single-transaction备份,最后把位点追加到 dump 文件末尾 - 绝对不要混用
--master-data和--single-transaction——这不是互补,而是自相矛盾
--single-transaction失效的三个典型场景
--single-transaction只对 InnoDB 表生效,一旦环境不满足,就会悄悄退化为 FTWRL 全局锁,业务照样停写。
- 库中存在任意 MyISAM 表:哪怕只有一张,
--single-transaction直接失效 - 备份开始前有运行超数秒的未提交事务:
mysqldump会卡在Waiting for table flush,本质是在等 undo log 可见性稳定 - 误加
--lock-all-tables或--lock-tables:这两个参数会强制覆盖--single-transaction,退化为锁表行为
MySQL 8.0+ 可用更轻量的LOCK TABLES FOR BACKUP
这是比 FTWRL 更细粒度的原生命令,只阻塞 DDL 和 MyISAM 表写入,InnoDB 表读写完全不受影响,持锁时间通常在毫秒级。
- 执行前必须确认版本:
SELECT VERSION();,低于 8.0 不支持 - 脚本中可显式调用:
mysql -e "LOCK TABLES FOR BACKUP;"→ 执行mysqldump→ 立即mysql -e "UNLOCK TABLES;" - 它仍会阻塞
CREATE TABLE、DROP INDEX等 DDL,所以 DDL 操作务必避开备份窗口 - 注意:它不解决跨库一致性,多数据库备份仍需额外协调
INFORMATION_SCHEMA.INNODB_TRX看trx_started,超过 30 秒的事务几乎总是元凶;而修复它,往往比换备份工具更有效。











