灾备恢复
本文涵盖的内容
本文描述 AuraBoot 的灾难恢复策略:需要备份哪些内容、如何验证恢复可行,以及出现问题时的完整操作步骤。两个核心术语贯穿全文。RTO(Recovery Time Objective,恢复时间目标)是从故障声明到服务恢复的最大允许时长。RPO(Recovery Point Objective,恢复点目标)是可接受的最大数据丢失量,以时间衡量。本文中的所有决策——备份频率、复制拓扑、演练节奏——均源于下方各部署层级的 RTO/RPO 目标。
RTO 与 RPO 分级
| 部署层级 | 典型配置 | RTO 目标 | RPO 目标 |
|---|---|---|---|
| 单节点 | 单台主机,每日 pg_dump,无备库 | < 2 小时 | < 24 小时 |
| HA 集群 | 主库 + 流式复制备库 + WAL 归档 | < 30 分钟 | < 5 分钟 |
| 多地域 | HA 集群 + 跨地域 WAL 或副本 | < 10 分钟 | < 1 分钟 |
HA 集群层级是平台默认的生产拓扑。该层级 P0 故障(服务全不可用)的 MTTR 目标为 < 15 分钟。单节点部署以 RTO/RPO 换取简单性,该取舍仅适用于开发和预发布环境。
四类必须保护的资产
PostgreSQL 数据是所有应用状态的权威存储:租户、用户、元数据模型、页面 Schema、命令定义、插件配置,以及每一张动态业务表(mt_*)。必须同时使用逻辑备份(pg_dump,便携性强)和物理基础备份(pg_basebackup,支持快速 PITR)。没有任何其他方式能替代丢失或损坏的 PostgreSQL 备份。
**对象存储(MinIO / S3 兼容)**保存上传的文件、附件、报表导出和爬虫产物。对象存储对应用层而言是只写的——文件写入后,应用只通过键值读取。通过桶复制或定期同步到独立存储端点进行备份。不要依赖应用数据库来重建哪些文件存在;将对象存储视为独立的持久化资产单独管理。
Redis 状态保存分布式锁、会话令牌、限流桶和 L2 元数据缓存。Redis 数据本质上是短暂的:会话过期、锁释放、缓存从 PostgreSQL 重建。冷重启时 Redis 为空会导致预热期延迟峰值(典型元数据集约需 1.5 秒),但不会产生数据丢失。Sentinel 或集群拓扑覆盖 Redis 高可用;不需要为灾备目的对 Redis 做快照。
密钥与配置——环境变量、application-prod.yml 覆盖配置、TLS 证书和加密密钥——必须存放在密钥管理系统或等效的版本化存储中,而不只是服务器文件系统上。恢复了 PostgreSQL 但丢失了 ab_cloud_config 加密密钥的恢复不是成功的恢复。将密钥视为独立的备份轴,制定专属的轮换和恢复流程。
PostgreSQL 备份策略
AuraBoot 使用两种互补的备份方法。每日逻辑备份(pg_dump)速度快且便于移植。每周物理基础备份(pg_basebackup)结合持续 WAL 归档,可将数据库恢复到保留窗口内的任意时间点(PITR)。
WAL 归档——首先启用:
# postgresql.conf
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /var/wal-archive/%f && cp %p /var/wal-archive/%f'
wal_keep_size = 1GB
checkpoint_completion_target = 0.9
checkpoint_timeout = 5min
max_wal_size = 1GB在依赖 PITR 之前,验证归档进程健康:
psql -U auraboot -d aura_boot -c "SELECT * FROM pg_stat_archiver;"
# failed_count 必须为 0;last_archived_time 必须是最近时间每周物理全备:
PGPASSWORD="$REPLICATION_PASSWORD" pg_basebackup \
-h "$DB_HOST" \
-U replicator \
--pgdata=/var/backups/auraboot/weekly/basebackup-$(date +%Y%m%d) \
--format=tar \
--gzip \
--compress=9 \
--wal-method=stream \
--checkpoint=fast \
--progress每日逻辑备份(便携、可验证):
pg_dump \
-h "$DB_HOST" -U auraboot -d aura_boot \
--format=custom --compress=9 \
--file=/var/backups/auraboot/daily/aura_boot-$(date +%Y%m%d-%H%M%S).dump
# 完整性检查——列出内容而不实际恢复
pg_restore --list /var/backups/auraboot/daily/aura_boot-*.dump > /dev/null保留策略:
| 备份类型 | 本地保留 | 异地保留 |
|---|---|---|
每日 pg_dump | 7 天 | 对象存储 30 天 |
每周 pg_basebackup | 4 周 | 3 个月 |
| WAL 归档 | 直到被基础备份覆盖后再保留 7 天 | 与异地存储同步 |
PITR 恢复到目标时间点:
# 1. 停止应用服务
systemctl stop auraboot && systemctl stop postgresql
# 2. 解压目标时间前最近的基础备份
rm -rf /var/lib/postgresql/data/*
tar -xzf /var/backups/auraboot/weekly/basebackup-20260410/base.tar.gz \
-C /var/lib/postgresql/data/
chown -R postgres:postgres /var/lib/postgresql/data
chmod 700 /var/lib/postgresql/data
# 3. 配置 PITR(PostgreSQL 12+)
cat >> /var/lib/postgresql/data/postgresql.conf <<EOF
restore_command = 'cp /var/wal-archive/%f %p'
recovery_target_time = '2026-04-11 14:30:00'
recovery_target_action = 'promote'
EOF
touch /var/lib/postgresql/data/recovery.signal
# 4. 启动并观察 WAL 重放进度
systemctl start postgresql
tail -f /var/log/postgresql/postgresql-$(date +%Y-%m-%d).log对象存储与文件备份
在主对象存储端点和地理位置分离的备用端点之间启用桶复制。至少每晚执行一次同步:
# 通用 S3 兼容同步(根据所用工具调整)
mc mirror --overwrite --remove primary/auraboot-files secondary/auraboot-files-backup对象存储丢失后,可以从 PostgreSQL 重建的内容:ab_file 中的文件元数据记录。无法重建的内容:实际的文件字节。这种不对称意味着,无论 PostgreSQL 多健康,在没有备份的情况下丢失对象存储就是永久性数据丢失。
不要将本地磁盘 MinIO 用于生产持久化。本地 MinIO 仅适合开发环境和单节点预发布环境。生产环境应将 MinIO 配置为分布式模式,或将平台指向已启用复制功能的外部 S3 兼容服务。
跨地域故障切换流程
按顺序执行以下步骤。不要跳过复制延迟检查——在提升复制落后几分钟的备库之前,必须先评估并接受该 RPO 损失。
-
检测并定性故障。 确认主库不可达:
pg_isready -h <主库IP> -p 5432返回无响应。在提升备库之前,通过pg_stat_replication检查复制延迟。 -
检查复制延迟:
psql -h <备库IP> -U auraboot -d aura_boot -c \ "SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::INT AS lag_seconds;" -
提升备库:
psql -h <备库IP> -U auraboot -c "SELECT pg_promote();" # 验证:pg_is_in_recovery() 必须返回 false psql -h <备库IP> -U auraboot -d aura_boot -c "SELECT pg_is_in_recovery();" -
切换 DNS 或负载均衡器上游,将
db.internal指向已提升备库的 IP。如果直接使用连接字符串环境变量,在每个应用节点上更新DATASOURCE_URL。 -
重启应用服务并验证健康状态:
systemctl restart auraboot curl -s http://localhost:6443/api/health | python3 -m json.tool -
验证数据完整性(见下方「恢复后数据验证」章节)。
-
通知相关人员并记录事件。 记录实际故障切换时长和提升时的复制延迟,作为事后 RTO/RPO 实测数据。
恢复演练检查清单
每季度进行一次完整恢复演练。未经测试的恢复等同于没有备份。每次演练覆盖以下项目:
- 在隔离主机上执行 PITR,目标时间点为演练窗口前 2 小时
- 验证
recovery.signal已被消费,PostgreSQL 已退出恢复模式 - 从最近的
pg_dump文件全量恢复到aura_boot_drill_$(date +%Y%m%d)数据库 - 插件重新导入:导入至少一个生产插件包,确认返回
success: true - 元数据缓存预热:启动应用连接到恢复后的数据库,确认
CacheWarmupRunner无报错完成 - Redis 冷启动:清空 Redis,重启应用,测量前 10 个请求的延迟(预热开销不应超过 3 秒)
- 冒烟验证命令:
curl /api/health,获取租户列表,执行一个动态列表查询 - 记录从「开始恢复」到「冒烟验证通过」的墙钟时间,即实测 RTO;与本层级目标对比
- 将结果记录在演练报告模板中,将发现的差距记录为跟进事项,指定负责人和截止时间
恢复后数据验证
在宣布恢复完成并重开生产流量之前,执行以下检查。
-- 核心表行数——与预期基线对比
SELECT 'ab_user' AS tbl, COUNT(*) AS rows FROM ab_user
UNION ALL
SELECT 'ab_tenant', COUNT(*) FROM ab_tenant
UNION ALL
SELECT 'ab_meta_model', COUNT(*) FROM ab_meta_model
UNION ALL
SELECT 'ab_page_schema', COUNT(*) FROM ab_page_schema
UNION ALL
SELECT 'ab_command_definition', COUNT(*) FROM ab_command_definition
ORDER BY tbl;
-- 动态业务表存在性(每个插件发布 mt_* 表)
SELECT COUNT(*) AS dynamic_table_count
FROM information_schema.tables
WHERE table_name LIKE 'mt_%' AND table_schema = 'public';
-- 审计日志连续性——间隔不应超过预期写入频率的 2 倍
SELECT MAX(changed_at) AS last_audit_entry,
NOW() - MAX(changed_at) AS staleness
FROM ab_data_change_log;
-- 活跃租户可正常解析
SELECT name, status FROM ab_tenant WHERE status = 'active' LIMIT 5;需要断言的关键不变量:
ab_tenant至少有一条active记录。ab_meta_model数量与恢复前一致(插件模型不会在恢复时重新创建,它们从 dump 文件中恢复)。ab_data_change_log的最新时间戳在恢复点的预期 RPO 窗口内。- 活跃插件引用的所有
mt_*表都存在于information_schema.tables中。
如果任何本不应为零的计数为零,立即停止并排查,不要在此之前恢复流量。部分恢复比彻底失败更危险。
常见陷阱
| 陷阱 | 危害 |
|---|---|
| WAL 归档磁盘写满,归档进程静默暂停 | pg_stat_archiver.failed_count 持续增加;未触发告警的情况下 PITR 窗口缩减至零 |
pg_basebackup 未加 --wal-method=stream | 基础备份数据一致,但备份起止之间的 WAL 间隙未捕获 |
| 恢复目标主机的 PostgreSQL 大版本不同 | pg_restore 可能成功,但目录格式不兼容;始终保持版本一致 |
| 密钥未入库——加密密钥只在服务器文件系统上 | 恢复后数据库 + 密钥丢失 = 所有加密列均不可读 |
| 从未进行过恢复演练 | 第一次真实恢复耗时是预估的 3 倍,因为存在未知的操作细节 |
| 未确认复制延迟就提升备库 | 接受了未经测量的更大 RPO 损失 |
| 将 Redis Sentinel 自动切换等同于 PostgreSQL 故障切换 | Redis 会话丢失导致用户被登出;应提前规划宽限期提示 |
恢复后未验证 ab_data_change_log 连续性 | 审计链静默断裂;合规审计和事故调查失去追溯依据 |
后续步骤
- 备份与恢复 — 完整备份脚本、cron 配置及恢复 Runbook
- 可观测性 — 备份成功率、复制延迟和 WAL 归档健康的指标与告警
- 性能调优 — RTO 受 PostgreSQL WAL 重放速度影响;在真正需要之前完成调优
- 负载均衡 — 故障切换过程中的 DNS 和上游切换模式
企业版说明 — 托管式跨地域自动故障切换(含自动 DNS 提升)、带防篡改审计链的签名备份产物溯源(SHA-256 清单),以及基于真实恢复演练遥测数据的 RTO/RPO SLA 实时仪表板,均为企业版功能。社区版可完整使用本文档中描述的所有备份机制和操作手册;区别在于托管编排层和合规级别的产物签名,而非底层的 PostgreSQL 与 WAL 工具本身。