binlog不是备份,仅支持基于全量备份的增量恢复;必须配合定期全量备份(如xtrabackup或mysqldump)、保留对应binlog位点及合理过期策略,才能实现RPO≤1分钟、RTO≤30分钟的可靠恢复。

二进制日志(binlog)不是备份,但它是增量恢复的唯一依据
MySQL 的 binlog 记录的是所有对数据产生修改的 SQL 语句(或行变更事件),它本身不保存数据库快照,也不包含表结构、用户权限等元数据。如果你只开启了 binlog 而没有定期全量备份,一旦发生误删库或磁盘损坏,你连“从哪一天开始重放”都不知道——binlog 只能向前滚动,不能向后回退到某个时间点之前的完整状态。
实际使用中必须满足两个前提才能用 binlog 恢复:一是有某次 mysqldump 或 mysqlpump 生成的全量逻辑备份(带 --master-data=2 或 --source-data=2),二是该备份时刻对应的 binlog 文件和位置(File 和 Position)仍保留在磁盘上。
-
binlog格式建议设为ROW(binlog_format = ROW),避免因函数、临时表、非确定性语句导致主从不一致或恢复失败 - 务必配置
expire_logs_days(如7)或binlog_expire_logs_seconds(MySQL 8.0.28+),否则磁盘会被撑爆;但值不能小于全量备份周期,否则中间段日志被自动清理,断掉恢复链 - 不要依赖
FLUSH LOGS手动切换日志来“归档”,它不保证事务完整性;应配合xtrabackup的--slave-info或mysqldump --single-transaction --master-data=2获取精确位点
物理备份(xtrabackup)比逻辑备份(mysqldump)更适合大库和高可用场景
当单库超过 50GB,mysqldump 导出耗时长、锁表风险高(即使加 --single-transaction,DDL 仍可能阻塞)、恢复时重放 SQL 效率低。而 Percona XtraBackup 是针对 InnoDB 的热备份工具,直接拷贝数据文件,支持压缩、流式传输、增量备份,并能准确记录备份结束时的 binlog 位置。
关键实操点:
- 全量备份命令示例:
xtrabackup --backup --target-dir=/backup/full_$(date +%F_%H-%M) --user=root --password=xxx
- 增量备份必须基于上一次全量或增量备份目录,且需指定
--incremental-basedir;多次增量不能“叠罗汉”,推荐“全量 + 最新一次增量”组合恢复 - 恢复前必须执行
xtrabackup --prepare(两次:第一次 apply log,第二次 rollback uncommitted),否则数据文件处于不一致状态,mysqld启动会报错InnoDB: Database page corruption - 备份用户需具备
RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT权限,仅SELECT不够
备份文件必须脱离数据库主机存储,且验证恢复流程
把 mysqldump 输出或 xtrabackup 目录存到同一台机器的另一块磁盘,等于没备份——主机宕机、误格式化、勒索软件都可能一并清除。真正的备份要落地到独立存储:NFS 共享目录(挂载时加 noac 避免缓存问题)、对象存储(如 S3,用 aws s3 cp 或 rclone)、或专用备份服务器(通过 rsync --delete-after 同步)。
更关键的是:备份后不验证 = 不知道是否有效。每月至少执行一次恢复演练:
- 在隔离环境(非生产)拉起 MySQL 实例,还原全量备份 + 应用 binlog 到故障前一秒
- 检查
SHOW MASTER STATUS位点是否连续,对比关键表COUNT(*)和校验和(如SELECT MD5(GROUP_CONCAT(...))) - 特别注意
GTID模式下的恢复:SET GLOBAL gtid_purged = '...'必须严格匹配备份时的gtid_executed,否则START SLAVE报错Could not execute Write_rows event on table
混合策略:全量 + 增量 + binlog 归档,缺一不可
一个稳健的策略是:每周日凌晨跑一次 xtrabackup 全量,每天凌晨基于上周全量做一次增量,同时开启 binlog 并保留 7 天。这样可实现 RPO ≤ 1 分钟(取决于 binlog 刷盘频率),RTO 控制在 30 分钟内(10G 增量备份解压+应用约 5–8 分钟)。
容易被忽略的细节:
-
innodb_log_file_size过小会导致xtrabackupprepare 阶段极慢,甚至 OOM;建议与innodb_buffer_pool_size匹配(例如 buffer pool 16G,log file size 设为 2G × 2) - 备份脚本里漏写
--defaults-file参数,导致读不到~/.my.cnf中的密码,备份静默失败;务必在脚本开头加set -e和日志重定向 - 跨版本恢复(如 MySQL 5.7 备份恢复到 8.0)不被支持;
xtrabackup也严格绑定 MySQL 主版本,8.0 备份不能用 2.4 版本恢复
真正卡住恢复的往往不是技术方案,而是备份文件损坏、位点跳变、权限缺失或忘记关闭 sql_log_bin 导致恢复过程又写了一堆 binlog。










