新项目优先选mysqlpump,生产环境mysql版本低于5.7.8则必须用mysqldump;两者核心差异在于并发粒度与对象隔离能力,mysqlpump支持库/表/引擎级并行导出且可跳过视图错误,mysqldump为单线程且遇依赖缺失即报错退出。

全量备份到底该用 mysqldump 还是 mysqlpump?
直接结论:新项目优先选 mysqlpump,但生产环境若 MySQL 版本低于 5.7.8,必须退回 mysqldump。两者核心差异不在“能不能备”,而在并发粒度和对象隔离能力。
mysqlpump 支持按库、按表、甚至按存储引擎并行导出,且能跳过视图定义失败导致的中断;mysqldump 是单线程,遇到视图依赖缺失或函数权限不足会直接报错退出。
- 备份时加
--set-gtid-purged=OFF(GTID 环境下避免恢复冲突) - 务必指定
--single-transaction(InnoDB 表一致性前提),但注意它对 MyISAM 无效 - 不要用
--all-databases直接打包,应显式列出业务库名,排除information_schema、performance_schema等系统库
增量备份只能靠 binlog 吗?怎么确认它真在工作?
是的,MySQL 原生只靠 binlog 实现增量。但很多人配了 log-bin 却没开 binlog_format=ROW,结果恢复时发现 UPDATE 语句重放失败——因为 STATEMENT 格式下某些函数(如 NOW()、UUID())无法精确还原。
验证 binlog 是否生效,别只看配置文件,执行:SHOW VARIABLES LIKE 'log_bin'; —— 必须为 ONSHOW MASTER STATUS; —— 能查到当前文件名和 position 才算真正启用
- 定期用
mysqlbinlog --base64-output=DECODE-ROWS -v binlog.000001抽样检查内容是否含 ROW event - 设置
expire_logs_days = 7(至少覆盖最长恢复窗口),但注意它不触发实时清理,需配合PURGE BINARY LOGS - 备份 binlog 文件本身要带时间戳,例如
cp /var/lib/mysql/binlog.* /backup/binlog_$(date +%Y%m%d_%H%M%S)/
恢复时为什么 “SET SQL_LOG_BIN=0” 不够用?
因为 SET SQL_LOG_BIN=0 只禁用当前会话的 binlog 写入,但如果你用 source 导入大 SQL 文件,中途网络断开或客户端崩溃,会导致部分数据写入而 binlog 缺失,主从延迟或 GTID 不一致就从此开始。
真正安全的做法是:停写 + 全局禁 binlog + 指定库恢复。
- 先执行
SET GLOBAL sql_log_bin = OFF;(影响所有新连接) - 用
mysql -D mydb 方式导入,而非进入 mysql 客户端后 <code>source - 恢复完成后,立刻
FLUSH LOGS;切新 binlog,并用SHOW MASTER STATUS记下起始 position,供后续增量追平 - 如果用了 GTID,恢复前要
RESET MASTER(清空 GTID_EXECUTED),否则可能因 UUID 冲突拒绝执行
设计恢复策略时最容易被忽略的三个点
第一是备份文件校验:mysqldump 输出的 SQL 文件末尾未必有 COMMIT;,若中间出错截断,你根本不知道缺了多少表;第二是时间点精度:mysqlbinlog --stop-datetime 在高并发下可能跨事务,必须结合 --stop-position 配合事务边界定位;第三是权限还原:备份脚本通常不包含 GRANT 语句,恢复后应用账号很可能连不上库。
建议把这三个动作固化进恢复 checklist:
- tail -n 20 backup.sql | grep "Dump completed" 确认结束标记
- 用 mysqlbinlog --verbose 找到目标事务的 COMMIT 行,取其前一行的 end_log_pos
- 单独导出权限:mysqldump --no-data --no-create-info --skip-triggers mysql user db user_privileges










