⭐ 推荐:社区规则条款 V1.0

数据库备份与恢复方案怎么设计,才能做到不丢数据?

GJ
GJ 资深会员 👑黑卡会员
发布于 2026-10-28 10:54 ·6 浏览 ·0 回复
内容摘要

先按业务确定各库的 RPO 与 RTO 指标,再据此搭建全量、增量和 binlog/WAL 日志归档三层备份,并配置日志保留期与一致性参数,使数据库可恢复到任意时间点且恢复过程可验证。

学完这篇,你能从零设计出一套「RPO 可控、恢复能验证」的数据库备份与恢复方案,并且知道每一步该敲什么命令、该改哪个参数。

第一步:先定 RPO 和 RTO,再谈备份频率

这一步要把「能丢多少数据、能停多久」写成两个数字,做完你会得到一张明确的指标表,后面所有备份动作都从它推出来。RPO(恢复点目标)决定备份间隔和日志保留时长,RTO(恢复时间目标)决定你用物理备份还是逻辑备份。

举个例子:核心业务库定 RPO ≤ 5 分钟、RTO ≤ 30 分钟,那就必须是「每日全量 + 持续 binlog/WAL 归档 + 物理热备」;内部报表库定 RPO ≤ 24 小时,每天一次 mysqldump 就够。把每个库的这两个值写进表格,和业务方确认签字,否则后面一定会在「要不要多花磁盘」上反复扯皮。

注意:RPO 不是「备份多久跑一次」,而是「最后一次可用日志到故障点的最大间隔」。只做每日全量、不归档日志,RPO 实际等于 24 小时。

第二步:搭三层备份结构,全量 + 增量 + 日志

这一步要落地三类备份文件,做完你手上应该有三份可互相衔接的数据。以 MySQL 8.0 为例:


xtrabackup --backup --target-dir=/backup/full/$(date +%F) \
  --user=backup --password='***'

# 每天 02:00 增量备份(基于上一次备份目录)
xtrabackup --backup --target-dir=/backup/inc/$(date +%F) \
  --incremental-basedir=/backup/full/2024-06-02 --user=backup --password='***'

# 小库可用逻辑备份,必须带一致性参数
mysqldump --single-transaction --source-data=2 --flush-logs \
  --routines --triggers --events -ubackup -p db > /backup/db_$(date +%F).sql

PostgreSQL 侧对应的是 pg_basebackup -D /backup/base -Ft -z -P -h 127.0.0.1 -U repl 加 WAL 归档。

注意:mysqldump 不加 --single-transaction 在 InnoDB 大表上会拿锁甚至拖垮线上;--source-data=2(老版本是 --master-data=2)会把 binlog 位点写进文件头,这是后续增量恢复的锚点,别省。

第三步:把日志归档配好并确认保留期

这一步要让「全量之后发生的每一次变更」都有文件可查,做完你能把数据恢复到任意一秒。MySQL 在 my.cnf 里确认:

log_bin = /var/log/mysql/mysql-bin
binlog_format = ROW
binlog_expire_logs_seconds = 604800   # 保留 7 天
sync_binlog = 1

PostgreSQL 在 postgresql.conf 里:

wal_level = replica
archive_mode = on
archive_command = 'cp %p /backup/wal/%f'

配完执行 SHOW BINARY LOGS; 或用 SELECT * FROM pg_stat_archiver; 确认归档任务没有 failed_count 增长。

注意:binlog 保留期必须大于「全量备份周期 + 最长故障发现时间」。全量每周做一次、binlog 只留 3 天,周三出的事故你就只能恢复到周一的全量,中间两天数据直接没了。

第四步:备份文件异地存放并做完整性校验

这一步解决「备份文件本身坏了或机房没了」的问题,做完你至少有一份不在同一台机器、不在同一个机房的副本。用 rsync 或对象存储 CLI 同步到异地,同步后立刻校验:

sha256sum /backup/full/2024-06-02/ibdata1 > /backup/full/2024-06-02.sha256
# 异地拉回后比对
sha256sum -c /backup/full/2024-06-02.sha256

数据库层再补一次可用性校验:逻辑备份用 mysql --force < db.sql 导入到空实例看是否报错,物理备份用 xtrabackup --prepare 跑一遍,看输出有没有 completed OK。

注意:备份任务返回 0 不代表备份可用。磁盘满、权限错、表结构变更都可能在「看似成功」的情况下产出残缺文件,一定要加 prepare 或导入校验。

第五步:每月做一次真实恢复演练

这一步是把备份真正还原成可登录的数据库,做完你会得到一份记录演练耗时和问题的复盘表。做法:在隔离环境起一个临时实例,按「全量 → 增量 → 日志回放到故障点前一秒」走完整链路,记录从开始到业务可连接的总耗时,和第一步定的 RTO 对比。

恢复命令的关键动作是准备阶段合并增量:

xtrabackup --prepare --apply-log-only --target-dir=/backup/full/2024-06-02
xtrabackup --prepare --apply-log-only --target-dir=/backup/full/2024-06-02 \
  --incremental-dir=/backup/inc/2024-06-03
xtrabackup --prepare --target-dir=/backup/full/2024-06-02

只有最后一次 prepare 不加 --apply-log-only,加错了会导致后续增量无法合并。

注意:演练时顺手验证「误删表」场景——用 mysqlbinlog --start-datetime 定位到 DELETE 之前的位点做跳过恢复,这是线上最高频的真实故障,光会全量恢复不够用。

第六步:给备份链路加监控和值班告警

这一步让备份失败在 10 分钟内被发现,做完你不再需要靠人肉记「昨天备份跑了没」。监控三件事:备份任务退出码、备份目录最新文件的时间戳、日志归档的失败计数。用一条 cron 加脚本即可:

find /backup/full -maxdepth 1 -type d -mtime +2 | grep -q . || \
  echo "全量备份超过48小时未更新" | mail -s "备份告警" ops@example.com

同时把恢复手册写成文档放在运维库,写清「找谁要权限、从哪个目录取文件、每一步预计多久」,避免真出事时只有一个人会操作。

小结

  • 先定 RPO/RTO 两个数字,再决定备份频率和技术选型,顺序不能反。
  • 三层结构缺一不可:全量打底、增量省空间、日志补齐最后一段。
  • binlog/WAL 保留期必须覆盖整个全量周期,否则中间数据无法回放。
  • 备份文件要有异地副本和 sha256 校验,还要做 prepare 或导入验证。
  • 每月真实演练一次,重点练「误删数据按位点跳过恢复」,并用演练耗时对标 RTO。
  • 备份失败靠监控发现,不靠记忆;恢复手册要写到别人照着能做。
本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2661.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 0

还没有回复,来抢沙发~