优先选mysqldump,除非mysql版本为5.7.8+且明确需要并行导出或细粒度过滤;它兼容性好、参数稳定、调试方便,而mysqlpump在旧版本或特殊库名下易静默失败,且不支持--single-transaction与--master-data同时使用。

MySQL全量备份用mysqldump还是mysqlpump?
优先选 mysqldump,除非你用的是 MySQL 5.7.8+ 且明确需要并行导出或更细粒度的过滤。它兼容性好、参数稳定、调试方便;mysqlpump 在部分旧版本或含特殊字符库名时会静默失败,且不支持 --single-transaction 和 --master-data 同时使用——这对后续增量恢复很关键。
全量备份必须加这几个参数:
-
--single-transaction:保证一致性快照(仅对 InnoDB 有效) -
--routines和--events:否则存储过程和事件不会被导出 -
--master-data=2:记录备份时刻的 binlog 文件名与位置,这是衔接增量恢复的唯一锚点 -
--triggers:默认开启,但显式写上更稳妥
示例命令:
mysqldump -u root -p'xxx' --all-databases --single-transaction --master-data=2 --routines --events --triggers > /backup/full_$(date +\%Y\%m\%d_\%H\%M).sql
增量备份靠解析binlog,但别直接用mysqlbinlog读活跃日志
直接解析正在写的 binlog 文件(比如 mysql-bin.000001)会导致内容不完整或重复——因为事务可能只写了一半。正确做法是:等 MySQL 自动滚动出新 binlog 后,立刻归档上一个文件。
用 FLUSH BINARY LOGS 触发滚动,再结合 SHOW BINARY LOGS 找到待归档的旧文件:
- 脚本里先执行
mysql -e "FLUSH BINARY LOGS" - 再查出倒数第二个文件名:
mysql -Nse "SHOW BINARY LOGS" | tail -n 2 | head -n 1 | awk '{print $1}' - 用
mysqlbinlog --base64-output=DECODE-ROWS -v解析它,并压缩存档
注意:--base64-output=DECODE-ROWS 能把 ROW 格式日志转成可读 SQL;不加这个参数,你会看到一堆 ### UPDATE ... SET @1=... @2=...,没法人工核对。
自动清理策略必须区分全量与增量,且依赖时间戳而非文件数
按保留“最近 7 个全量备份”这种逻辑容易出错——如果某天全量没跑成功,后续所有增量都失去上下文。应该让每个全量备份带时间戳,并只保留「最近 N 天内最新的一次全量 + 对应的所有增量」。
实操建议:
- 全量备份文件名强制含
full_YYYYMMDD_HHMM.sql格式 - 增量文件名对应为
incr_YYYYMMDD_HHMM_binlog.000001.sql.gz - 清理脚本先找最新全量时间戳,再删掉早于该时间戳 N 天的所有全量 + 增量
- 别用
find /backup -name "*.sql" -mtime +7 -delete——它不认语义,会误删正在用的增量
恢复时最容易漏掉的一步:SET SQL_LOG_BIN = 0
无论是导入全量还是重放增量 SQL,如果不关掉二进制日志,操作本身会被再次记录进 binlog,导致循环写入、主从错乱、甚至磁盘爆满。
在恢复前必须执行:
mysql -e "SET SQL_LOG_BIN = 0;",并且确保你的备份 SQL 文件开头没有
SET SQL_LOG_BIN = 1; 这类语句(mysqldump 默认不写,但某些定制脚本会加)。另外,增量恢复必须严格按时间顺序执行,且每个 mysqlbinlog 输出的 SQL 文件里,第一行通常是 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; ——这不是注释,是必要前置设置,删了会导致 GTID 恢复失败。











