Files
order_site/docs/pgBackRest备份方案分析.md
2026-08-23 15:24:37 +08:00

193 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# pgBackRest 生产备份方案分析
> 状态:暂缓实施。当前继续使用 `pg_dump -Fc` + OSS manifest 备份方案,待安排维护窗口后再启用 WAL 归档。
>
> 记录日期:2026-08-23
## 结论
PostgreSQL 没有 MySQL binlog 的同名机制,但有等价能力:
```text
基础物理备份 + WAL 归档 = 按时间点恢复(PITR)
```
当前 Compose 是单节点 PostgreSQL。启用 `archive_mode``wal_level` 通常需要重启 PostgreSQL,因此不能承诺绝对零停机。
预计生产维护窗口:
| 阶段 | 是否停机 | 预计耗时 |
| --- | --- | --- |
| 构建 pgBackRest 镜像 | 否 | 几分钟 |
| 创建 stanza、校验 OSS | 否 | 13 分钟 |
| 重启 PostgreSQL 启用 WAL 归档 | 是 | 530 秒 |
| backend/web 等待恢复 | 是 | 2090 秒 |
| 首次全量备份 | 否 | 几分钟到几十分钟 |
| 建议预留维护窗口 | 是 | 2~5 分钟 |
实际时间取决于数据库大小、磁盘恢复速度、容器启动时间和 OSS 网络质量。当前 `pg_dump` 文件约 161 MB,首次物理备份预计不会很大,但仍应按实际 PostgreSQL 数据目录大小估算。
## 当前方案
目前生产使用:
- `pg_dump -Fc` 全库逻辑备份。
- 备份文件上传 OSS。
- manifest 保存大小、SHA-256、迁移记录和创建时间。
- `apps/backend/data` 配置单独打包上传。
- `restore-db.sh --verify` 在临时 PostgreSQL 容器中演练恢复。
该方案可以恢复到某个 dump 的时间点,但不能恢复最近一次 dump 之后的几分钟变更。
pgBackRest 不能替代当前逻辑备份,建议两套并存:
```text
pgBackRest:生产灾难恢复、PITR、分钟级 RPO
pg_dump:逻辑迁移、单表恢复、跨版本恢复、第二套保险
```
## 需要增加的组件
当前 PostgreSQL 镜像没有 pgBackRest,需要构建自定义镜像:
```dockerfile
FROM docker.m.daocloud.io/library/postgres:16-bookworm
RUN apt-get update \
&& apt-get install -y --no-install-recommends pgbackrest ca-certificates \
&& rm -rf /var/lib/apt/lists/*
```
需要增加或挂载:
- `/etc/pgbackrest/pgbackrest.conf`
- `/var/spool/pgbackrest/`
- pgBackRest 日志目录
- OSS 备份凭证
- pgBackRest repository 配置
不能只在正在运行的容器里执行 `apt install pgbackrest`,因为容器重建后会丢失。
## OSS 规划
可以复用当前图片 OSS 桶,但必须使用独立前缀:
```text
backups/postgres/ # 当前 pg_dump
backups/configs/ # 应用配置
backups/pgbackrest/ # 基础备份和 WAL
```
生产更推荐新建独立备份桶,并创建独立 RAM 用户。原因:数据库备份包含订单、用户和后台数据,不能与图片读写权限混用。
建议 OSS 配置:
- 使用 ECS 同地域内网端点,避免公网流量费用。
- 开启版本控制。
- 配置生命周期规则。
- 备份桶保持私有。
- 必要时启用 pgBackRest 仓库加密,并安全保存加密密码。
pgBackRest 使用 OSS S3 兼容接口,最终配置必须通过 `pgbackrest check` 和一次完整备份实测,不能只凭配置文件判断兼容性。
## PostgreSQL 配置
需要启用:
```text
wal_level=replica
archive_mode=on
archive_command=pgbackrest --stanza=order-site archive-push %p
archive_timeout=60
```
说明:
- `wal_level=replica` 通常需要重启。
- `archive_mode=on` 必须重启。
- `archive_command` 可以 reload,但建议统一写入 Compose 配置。
- `archive_timeout=60` 让低写入量时 WAL 最多约 60 秒切换归档一次。
- OSS 不可用时 WAL 会在本地积压,不能手动删除 `pg_wal` 文件。
启用前先检查当前状态:
```bash
docker compose exec postgres psql \
-U postgres -d order_site \
-c "SHOW wal_level; SHOW archive_mode; SHOW archive_command;"
```
如果 `archive_mode` 已经是 `on`,后续可能只需要配置 pgBackRest 和 reload;如果是 `off`,需要完整重启 PostgreSQL。
## 计划中的切换步骤
当前暂不执行。正式实施时按以下顺序:
1. 继续保留并执行现有 `bash deploy/backup-db.sh`
2. 创建独立 OSS 备份桶或规划独立 `backups/pgbackrest/` 前缀。
3. 创建只允许备份前缀的 RAM 用户。
4. 构建包含 pgBackRest 的 PostgreSQL 镜像。
5. 准备 `pgbackrest.conf`,不要把密钥提交到 Git。
6. 在 PostgreSQL 仍在线时执行 `stanza-create`
7. 选择低峰期停止 backend/web。
8. 重启 PostgreSQL,启用 `archive_mode``archive_command`
9. 等待 PostgreSQL 健康检查通过。
10. 执行 `pgbackrest check`
11. 执行第一次 full backup。
12. 检查 OSS 中是否出现基础备份和 WAL 文件。
13. 在临时 PostgreSQL 或测试服务器执行一次 PITR 恢复。
14. 恢复 backend/web,并抽查后台、订单和图片访问。
不要执行以下命令,避免误删当前数据库:
```bash
docker compose down -v
docker volume rm order_site_postgres_data
```
增加 pgBackRest 只需要替换镜像、挂载配置并重启,不需要删除 `postgres_data` 数据卷。
## 备份策略建议
```text
每周:full 基础备份
每天:diff 差异备份
持续:WAL 归档到 OSS
每天:保留当前 pg_dump 逻辑备份
```
WAL 归档不依赖 cron,由 PostgreSQL 的 `archive_command` 持续触发。需要监控:
- WAL 归档失败次数。
- `/var/lib/postgresql/data/pg_wal` 占用空间。
- OSS 上传延迟和失败率。
- 最近一次 full/diff 备份时间。
- 最近一段 WAL 是否已经出现在 OSS。
## 恢复时间预期
pgBackRest PITR 恢复也不是零停机操作。当前单节点架构下,恢复生产数据库需要停止 backend/web,并替换或恢复 PostgreSQL 数据目录。
恢复耗时主要取决于:
- 基础备份大小。
- WAL 数量。
- 磁盘读写速度。
- WAL 回放量。
- PostgreSQL 启动和健康检查时间。
如果基础备份较小、目标时间接近当前时间,预计几分钟;数据库规模扩大后需要重新压测,不能按当前 161 MB dump 固定估计。
## 后续验收清单
- `pgbackrest stanza-create` 成功。
- `pgbackrest check` 成功。
- 第一次 full backup 成功。
- OSS 中能看到基础备份和 WAL。
- PostgreSQL 重启后 `archive_mode=on`
- `pg_stat_archiver` 中归档成功数持续增加。
- OSS 暂时不可用时,WAL 会积压但不会静默丢失。
- 临时环境 PITR 到指定时间成功。
- 恢复后的订单、后台用户、迁移记录和图片引用可用。