全量备份到底该用 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';—— 必须为
ON
SHOW 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
