MySQL时间点恢复(PITR)必须依赖binlog,先恢复最近全备,再重放其后至目标时间点的binlog事件;前提包括启用log-bin、binlog_format为ROW/MIXED、保留足够binlog及可用全备,并需准确定位备份位置与目标时间点。

MySQL 时间点恢复(Point-in-Time Recovery,PITR)依赖于二进制日志(binlog),不能单靠备份文件实现。核心思路是:先恢复最近一次全量备份,再重放该备份时间点之后、目标时间点之前的 binlog 事件。
确认前提条件是否满足
时间点恢复不是随时可用的功能,必须提前开启并保留相关日志:
- 已启用 binlog:检查 my.cnf 中有 log-bin 配置(如 log-bin = /var/lib/mysql/mysql-bin),且 MySQL 启动时未禁用;
- binlog 格式为 ROW 或 MIXED:推荐 binlog_format = ROW,避免语句级不一致问题;
- 保留足够长的 binlog 文件:从最近一次全备时间到你想要恢复的时间点之间的所有 binlog 必须存在;
- 有可用的全量备份:例如 mysqldump 备份或物理备份(如 Percona XtraBackup),且知道其对应的确切时间戳或 binlog 位置。
获取关键时间点或位置信息
恢复前需定位两个坐标:备份的结束位置(或时间),以及目标恢复时间点(或对应 binlog 位置):
- 若用 mysqldump 且加了 --master-data=2 或 --dump-slave=2,备份 SQL 文件开头会记录类似 CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000012', MASTER_LOG_POS=198765; —— 这就是备份时刻的 binlog 文件名和位置;
- 若用物理备份(如 xtrabackup),执行 xtrabackup --prepare 后查看 xtrabackup_binlog_info 文件获取 binlog 位置;
- 目标时间点可通过 mysqlbinlog --base64-output=decode-rows -v mysql-bin.000012 | grep -A2 -B2 "2024-05-20 14:30:00" 粗略定位,或更准确地用 --stop-datetime="2024-05-20 14:30:00" 直接截断。
执行恢复操作
分两步:先还原全备,再重放 binlog 到指定时间点:
- 停止 MySQL 服务,清空或重命名原数据目录(如 /var/lib/mysql),确保干净环境;
- 恢复全量备份:如果是 mysqldump,用 mysql -u root -p ;如果是 xtrabackup 物理备份,用 xtrabackup --copy-back --target-dir=/path/to/backup;
- 启动 MySQL(可跳过 binlog 写入):临时在启动命令中加 --skip-log-bin,避免恢复过程产生新 binlog 干扰;
-
重放 binlog:使用 mysqlbinlog 提取并导入,例如:
mysqlbinlog --start-position=198765 --stop-datetime="2024-05-20 14:30:00" /var/lib/mysql/mysql-bin.000012 /var/lib/mysql/mysql-bin.000013 | mysql -u root -p
验证与收尾
恢复完成后务必验证数据一致性:
- 检查关键表行数、业务关键字段值是否符合预期;
- 确认 MySQL 错误日志无报错,binlog 位置正常推进;
- 移除启动参数中的 --skip-log-bin,重启服务使 binlog 生效;
- 建议立即做一次新全备,并记录本次 PITR 的起止时间、binlog 文件及位置,便于后续追溯。










