--single-transaction仅对InnoDB表有效,MyISAM表仍会触发FLUSH TABLES WITH READ LOCK导致写入阻塞;混合引擎下必须改用--lock-all-tables或物理备份工具。

--single-transaction只对InnoDB表生效,MyISAM必须换方案
加了--single-transaction也不等于“全库无锁备份”。它仅在InnoDB/XtraDB引擎下起作用,背后依赖MVCC和REPEATABLE READ隔离级别创建一致性快照。一旦库中混有MyISAM表(比如系统库mysql里的user、proc表),这些表仍会触发FLUSH TABLES WITH READ LOCK,导致写入卡顿。
常见错误现象:备份过程中业务出现短暂但明显的写延迟,监控看到Threads_running飙升、Waiting for table flush堆积。
- 确认引擎类型:
SELECT table_schema, table_name, engine FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','performance_schema','sys'); - 若存在MyISAM表,必须二选一:
--lock-all-tables(全局锁,停写时间长)或改用物理备份(如xtrabackup) - 混合引擎下硬加
--single-transaction+--master-data=2,会导致MyISAM部分数据不一致,恢复后查不到刚插入的记录
--single-transaction与--master-data=2共用时的锁行为
很多人以为加了--single-transaction就彻底没锁了,其实--master-data=2会引入一个极短但关键的全局读锁——只为读取SHOW MASTER STATUS的binlog位置。这个锁在获取完位置后立刻释放,通常FLUSH TABLES WITH READ LOCK。
容易踩的坑:
- 备份前已有运行超30秒的事务(如未提交的大批量UPDATE),
FLUSH TABLES WITH READ LOCK会一直等待,进而阻塞所有DML,MySQL看起来“卡死” -
--single-transaction和--lock-all-tables互斥,同时出现会直接报错:mysqldump: Got error: 1256: Cannot use --single-transaction with --lock-all-tables - 使用
--master-data=2时,--single-transaction自动接管锁逻辑,无需再手动加--lock-tables
autocommit=1是前提,否则快照会失效
--single-transaction依赖会话级事务自动提交机制。如果连接时autocommit=0(比如某些ORM或客户端默认配置),执行START TRANSACTION WITH CONSISTENT SNAPSHOT后,后续查询不会自动进入新快照,而是沿用旧事务上下文,导致导出数据可能滞后于实际状态。
验证方法:
- 连接后执行:
SELECT @@autocommit;,必须返回1 - 避免在命令中显式设置
SET autocommit=0,也不要依赖脚本里预设的会话变量 - 远程备份时,注意MySQL客户端版本兼容性:5.7+默认
autocommit=1,但老版本或自定义my.cnf可能覆盖
备份期间禁止DDL操作
即使全是InnoDB表,--single-transaction也无法隔离DDL语句。在dump进行中执行ALTER TABLE、DROP TABLE、TRUNCATE TABLE等操作,会导致该表的快照不可用,轻则导出空表或结构错乱,重则整个dump文件损坏无法恢复。
典型表现:
- 备份文件里某张表的
CREATE TABLE语句缺失,或字段顺序与线上不符 - 恢复时报错:
ERROR 1146 (42S02): Table 'db.t' doesn't exist,但原库明明存在 - 用
mysqlbinlog检查binlog发现,dump过程中恰好有ALTER事件被记录,但dump未捕获其影响
生产环境执行备份窗口内,应提前协调DBA或运维暂停DDL变更,这点比参数本身更关键——再正确的--single-transaction也防不住并发DDL。











