MySQL 增量备份依赖 binlog,不是 mysqldump 能解决的
mysqldump 默认是全量导出,不带增量能力。真正做增量备份,必须开启并正确配置
binlog,它是 MySQL 记录所有写操作(
INSERT、
UPDATE、
DELETE、
DROP等)的二进制日志。没有开启
log-bin,就不存在“增量”这个概念。
检查是否启用:
SHOW VARIABLES LIKE 'log_bin';—— 返回
ON才可继续。
常见疏漏点:
my.cnf里加了
log-bin=mysql-bin,但没重启 MySQL,配置未生效 磁盘空间不足导致
binlog自动停止写入(
SHOW BINARY LOGS;查看实际存在哪些文件) 设置了
expire_logs_days过小(如 1 天),旧 binlog 被自动清理,导致无法回溯到某次全备之后的全部变更
全备 + binlog 截断是标准增量方案
所谓“增量备份”,实际是定期做一次全量备份(如每天凌晨用
mysqldump或
mysqlpump),再持续归档新生成的
binlog文件。恢复时:先还原全备,再按顺序重放该时间点之后的所有 binlog。
关键操作步骤:
--master-data=2(或
--dump-slave=2如果是备库),让 dump 文件里自带
CHANGE MASTER TO语句,记录备份时刻的
binlog filename和
position备份后立即执行
FLUSH BINARY LOGS;,让后续写入写入新文件,便于归档边界清晰 用
cp或
rsync定期拷贝新增的
binlog文件(如
mysql-bin.000012)到备份目录,**不要用
mysqlbinlog --read-from-remote-server实时拉取**——网络中断或权限问题会导致丢日志
mysqlbinlog 解析与重放有编码和 GTID 陷阱
直接用
mysqlbinlog解析 binlog 再导入,看似简单,实则容易失败: 如果原库用了
utf8mb4,而
mysqlbinlog默认以
latin1解析,中文会乱码甚至报错 —— 必须加
--base64-output=DECODE-ROWS -v(行模式)或显式指定
--character-sets-dir开启
gtid_mode=ON后,不能靠 position 恢复,必须用
SET GTID_NEXT='xxx';或用
mysqlbinlog --skip-gtids导出(跳过原有 GTID,避免主键冲突)
mysqlbinlog输出含
SET @@SESSION.GTID_NEXT语句时,若目标实例已存在同 GTID,会报错
ERROR 1840 (HY000)—— 此时需先
RESET MASTER;(仅限测试环境)或用
--exclude-gtids过滤
生产环境建议用 xtrabackup + binlog 组合
mysqldump全备会锁表(即使加
--single-transaction,对 DDL 仍可能阻塞),而
Percona XtraBackup支持真正的热备,且能自动生成备份时刻的
xtrabackup_binlog_info文件,明确记录对应 binlog 位置。
实操要点:
xtrabackup --backup --target-dir=/data/backup/$(date +%F)备份完成后,立刻执行
mysql -e "FLUSH BINARY LOGS;",然后
cp新增 binlog 到备份目录旁 恢复时:
xtrabackup --prepare→
rsync回数据目录 → 启动 MySQL → 用
mysqlbinlog从
xtrabackup_binlog_info记录的位置开始重放
真正难的不是工具调用,而是 binlog 的生命周期管理:什么时候删旧日志、如何验证归档完整性、是否跨机房同步 binlog 文件——这些环节一出问题,增量链就断了。
