binlog不是备份,仅支持基于全量备份的增量恢复;必须配合定期全量备份(如xtrabackup或mysqldump)、保留对应binlog位点及合理过期策略,才能实现RPO≤1分钟、RTO≤30分钟的可靠恢复。
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 获取精确位点当单库超过 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 同步)。
更关键的是:备份后不验证 = 不知道是否有效。每月至少执行一次恢复演练:
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
一个稳健的策略是:每周日凌晨跑一次 xtrabackup 全量,每天凌晨基于上周全量做一次增量,同时开启 binlog 并保留 7 天。这样可实现 RPO ≤ 1 分钟(取决于 binlog 刷盘频率),RTO 控制在 30 分钟内(10G 增量备份解压+应用约 5–8 分钟)。
容易被忽略的细节:
innodb_log_file_size 过小会导致 xtrabackup prepare 阶段极慢,甚至 OOM;建议与 innodb_buffer_pool_size 匹配(例如 buffer pool 16G,log file size 设为 2G × 2)--defaults-file 参数,导致读不到 ~/.my.cnf 中的密码,备份静默失败;务必在脚本开头加 set -e 和日志重定向xtrabackup 也严格绑定 MySQL 主版本,8.0 备份不能用 2.4 版本恢复真正卡住恢复的往往不是技术方案,而是备份文件损坏、位点跳变、权限缺失或忘记关闭 sql_log_bin 导致恢复过程又写了一堆 binlog。