可以,但需满足两个硬条件:从库未执行stop slave,且主从复制无延迟触发ftwrl;否则会退化为加全局读锁,导致权限报错。

从库用 --single-transaction 备份行不行?
能,但必须满足两个硬条件:从库没在执行 STOP SLAVE、且主从复制没延迟到触发 FTWRL(全局读锁)。--single-transaction 依赖 InnoDB 的 MVCC 快照,而 MySQL 在从库上检测到复制线程暂停或 relay log 落后太多时,会自动退化为加 FLUSH TABLES WITH READ LOCK,这就不是“无锁”了。
常见错误现象:mysqldump: Got error: 1227: Access denied; you need (at least one of) the SUPER or FLUSH_TABLES privilege(s) for this operation —— 这说明它已经 fallback 到锁表模式,而账号没给够权限。
- 检查复制状态:
SHOW SLAVE STATUS\G,确认Slave_SQL_Running: Yes且Seconds_Behind_Master稳定(比如 - 备份前别手动
STOP SLAVE,否则--single-transaction直接失效 - 账号至少要有
REPLICATION CLIENT+SELECT权限,不需要SUPER(锁表才要)
--single-transaction 在从库导出的数据一致性边界在哪?
它只能保证「单个数据库内」的事务一致性,不跨库、不跨实例、也不包含非事务引擎(如 MyISAM 表)——这些会被单独刷盘,时间点和其他 InnoDB 表不同。更关键的是:它不保证和主库逻辑一致,因为 dump 时刻的 binlog position 和从库已执行的 relay log position 是两回事。
使用场景很明确:你需要一个从库本地的、轻量级的、用于开发还原或临时分析的副本,而不是用于主从切换或灾备恢复。
- 如果要还原后接回主库,必须额外记录
SHOW SLAVE STATUS里的Exec_Master_Log_Pos和Master_Log_File,不能只信 dump 文件里的CHANGE MASTER TO注释 - 含 MyISAM 表的库,
--single-transaction会自动失效并警告,转为锁表;此时要么换引擎,要么接受不一致 - 大表
ALTER TABLE或DROP TABLE正在从库重放时,dump 可能卡住或报错Lock wait timeout exceeded
为什么有时候从库 dump 比主库还慢?
不是因为 IO 或 CPU,而是因为从库的查询要等 relay log 应用线程释放 row lock,尤其当 SQL thread 正在写同一张大表时,SELECT 会被阻塞。主库没有这层竞争关系。
性能影响取决于复制负载,而非数据量本身。你看到的“慢”,其实是等待锁的排队时间。
- 观察
SHOW PROCESSLIST,找状态为Waiting for table flush或Locked的 dump 进程 - 临时降低复制压力:比如错峰备份,或用
SET GLOBAL slave_parallel_workers = 0减少并发冲突(仅限短时) - 避免在
relay_log_recovery = ON的实例上直接 dump —— 启动时重建 relay log 期间,--single-transaction会拒绝工作
替代方案:比 --single-transaction 更稳的从库备份思路
真要拿从库做可靠逻辑备份,不如绕开 mysqldump,用 SELECT ... INTO OUTFILE 分表导出,配合 SHOW CREATE TABLE 手动生成建表语句。虽然麻烦,但每张表都是独立快照,不受复制线程干扰,也无需 SUPER 权限。
或者更干脆:用 Percona XtraBackup 做物理备份再转逻辑(xtrabackup --export + innodb_table_export),虽重但可控。
-
mysqldump --single-transaction是“能用”,不是“该用”——它设计初衷是为主库服务的 - 从库上最常被忽略的点:没验证
binlog_format是否为ROW,STATEMENT 格式下某些函数(如NOW())在从库重放时会偏移时间戳,导致 dump 数据和实际从库内容对不上 - 只要从库开启了
read_only = ON,就别指望靠--skip-lock-tables来绕过问题——它根本不起作用











