mysql数据库备份时的增量备份与全量备份

7次阅读

全量备份是导出数据库某时刻的完整数据和结构,首次备份、灾备基线或 binlog 损坏时必须使用;它不依赖历史状态,恢复直接导入即可。

mysql 数据库备份时的增量备份与全量备份

全量备份是什么,什么时候必须用它

全量备份是把整个数据库(或指定库 / 表)在某一时刻的完整数据和结构导出为 SQL 文件或物理文件。它不依赖任何历史状态,恢复时直接导入即可还原到备份时刻。

  • mysqldump --all-databasesmysqldump mydb 生成的是逻辑全量备份
  • mysqlbackup(MySQL Enterprise Backup)或 Percona XtraBackup 可做物理全量备份,速度快、支持热备

全量备份适合:首次备份、灾备基线、binlog 被清空或损坏后重建恢复点。
不要指望只靠全量备份应对高频更新——每天一次全量,磁盘和网络压力大,恢复窗口也长。

增量备份依赖 binlog,但不是所有场景都适用

MySQL 原生不提供“增量备份”命令,所谓增量,本质是备份自上次全量以来新增的 binlog 文件。它要求:

  • server_id 已设置(非 0)
  • log_bin 开启,且 binlog_format = ROW(推荐,避免语句级不一致)
  • expire_logs_daysbinlog_expire_logs_seconds 设置合理,避免 binlog 被自动清理

常见错误:

  • 备份脚本里只拷贝最新 mysql-bin.000001,却没确认它是否包含全部增量变更
  • 恢复时漏掉中间某段 binlog,导致数据跳变或主键冲突

实操建议:

  • 全备后立即执行 FLUSH BINARY LOGS,让后续增量从新文件开始
  • mysqlbinlog --start-position=xxx --stop-position=yyy 精确截取区间,别直接 cp 整个文件

怎么组合全量 + 增量实现真正可用的备份策略

一个最小可行的日常策略是:每周一次全量 + 每日追加 binlog(从上次全量起始点到当前)。

# 周一全量(记录位点)mysqldump --single-transaction --master-data=2 mydb > full_mon.sql # 输出里含类似:CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000012', MASTER_LOG_POS=198765 

周二至周日,只备份新 binlog

mysqlbinlog --start-position=198765 mysql-bin.000012 > inc_tue.sql

注意:实际需动态获取上一轮结束位置,并覆盖读取范围

关键点:

  • --master-data=2 把位点写进 dump 文件注释,是衔接增量的前提
  • 每次增量前必须确认目标 binlog 是否还存在;SHOW BINARY LOGS 查看列表,SHOW MASTER STATUS 看当前位点
  • 不要混合使用 mysqldump(逻辑)和 xtrabackup(物理)做基线,它们的位点不可互认

容易被忽略的坑:GTID 模式下增量逻辑完全不同

如果开启了 gtid_mode = ON,就不能再靠 MASTER_LOG_FILE/POS 定位,必须用 GTID_SET

  • 全备时加 --set-gtid-purged=ON(默认),dump 文件头部会记录 SET @@GLOBAL.GTID_PURGED='……'
  • 增量回放时,不能用 --start-position,而要用 mysqlbinlog --exclude-gtids='……' 或先解析出 GTID 范围再用 SET GTID_NEXT 手动注入

典型报错:ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty —— 这说明你试图在已有数据的实例上导入带 GTID_PURGED 的 dump,必须先 RESET MASTER(慎用!会清空所有 binlog)。

备份脚本若未区分 GTID / 非 GTID 模式,恢复链大概率断裂。判断方式很简单:查 SELECT @@gtid_mode

text=ZqhQzanResources