Docker API 网关升级前怎么备份?数据库一致性与恢复演练
升级前找全卷、数据库与配置依赖,区分 SQLite WAL 和 PostgreSQL 导出的备份边界,在隔离环境核对账户、余额和路由,并处理恢复截点之后的新写入。
升级 Docker API 网关前,先回答三个问题:用户、余额和渠道配置存在哪里;备份能恢复到哪个时间点;恢复出来的网关是否会误用生产密钥或继续接收付款。容器能启动、压缩包能解开,都不等于业务可恢复。
本文面向自己维护网关的小团队,给出升级前备份与隔离恢复的验收顺序。SQLite 和 PostgreSQL 是两种不同的处理分支,不代表任何特定网关同时支持它们。使用其他数据库或托管服务时,应按实际产品、版本和服务商的备份文档选择方法。本文没有执行真实生产恢复或付费 API 测试。
1. 先找出数据的位置,而不是只保存镜像
对照部署配置、容器实际挂载和应用的数据库连接配置,做一张清单。检查配置时不要把密码、完整连接串或环境变量输出到公开日志。
| 要保留的内容 | 需要确认什么 | 漏掉后的典型问题 |
|---|---|---|
| 网关镜像与部署配置 | 原镜像摘要、版本、启动参数、Compose 文件、挂载关系 | 找不到升级前的可运行组合 |
| 数据库 | 引擎及版本、实际库名、卷或宿主机路径、是否在外部服务器 | 只备份网关目录,账户和余额却在另一台机器 |
| 应用配置与密钥依赖 | 渠道配置位置、加密主密钥的保管位置、密钥恢复负责人 | 数据恢复了,加密的渠道凭据仍无法解密 |
| 其他持久化数据 | 上传文件、对象存储、队列等是否参与业务状态 | 数据库有记录,对应文件或待处理任务丢失 |
Docker 卷独立于容器的生命周期,卷和 bind mount 的位置也不能混为一谈。[1] 把容器提交成镜像的 docker commit 明确不包含挂载卷中的数据。[2] 因此,保存镜像只是保留程序版本,不能替代数据库备份。
不要假设名为“cache”的组件一定可以丢弃:先确认它是否保存尚未结算的任务或其他不可重建状态。只记录真正使用的组件,不给小站强加不存在的依赖。升级期间不要把删除卷当作清理旧容器的常规步骤。
2. 按数据库选择一致性方法
SQLite:不要在持续写入时只复制一个 .db 文件。 在 WAL 模式下,已提交的数据可能还在 -wal 文件里;SQLite 官方说明,主库与 WAL 分离可能造成事务丢失或损坏。[4] 一边写入一边依次复制多个文件,也不能自动保证它们属于同一时刻。
优先使用应用支持、基于 SQLite Online Backup API 的备份方式;官方也列出了 VACUUM INTO 等在线备份方法。[3] 具体工具、运行用户、源路径、目标权限和失败处理要以实际版本说明为准,不直接把陌生命令套在生产库上。如果选择停机复制,必须正常停止所有会写这个库的进程,确认数据库已关闭,再按 SQLite 的规则复制一致的数据集合;不要手工删除 WAL 来“让备份变干净”。
PostgreSQL:逻辑导出和目录打包不是同一种备份。 pg_dump 可以在数据库并发使用时生成一致的单库导出,但不保存集群全局的角色和表空间;这些对象需要通过 pg_dumpall 或受控的配置重建方案单独处理。[5][6] 还要记录扩展及其版本,避免恢复时缺少依赖。
导出时确认库名、连接目标、权限、输出格式、退出状态及警告。SQL 文本通常由 psql 恢复,归档格式由 pg_restore 恢复;不要把两种文件交给同一条未经确认的恢复命令。旧主版本的 pg_dump 不能导出更新主版本的服务器,导出结果也不保证能导入旧主版本。[5]
这里的逻辑导出适合讨论一次升级前的可恢复副本,不等于完整的生产灾备方案。持续归档、物理备份与时间点恢复应另行设计;官方将 SQL 导出、文件系统级备份和持续归档区分为不同方法。[7] 正在运行的数据库目录不能因为被 Docker 挂载,就自动变成可直接打包的一致备份。
3. 给备份写清“恢复截点”
开始前约定两项业务目标:最多能接受丢失多久的数据,以及最多能停服多久。备份任务结束时间不一定是数据覆盖时间,尤其不能把文件修改时间当作最后一笔交易的证明。
升级窗口可以按下面顺序安排:
- 暂停新业务写入入口,等待在途请求与计费处理收敛;盘点支付回调、定时任务和后台工作人员等其他写入来源。
- 为无法暂停的外部事件准备可靠的记录、重放或对账办法。不要假定支付平台一定会按你需要的期限重试,也不要直接丢弃回调。
- 执行已选定的数据库备份,同时保存匹配的部署配置和依赖清单。记录数据库快照或停写截点、任务开始结束时间,以及最后确认纳入的业务记录。
- 检查工具退出状态、警告、文件大小和可读性,为副本记录校验摘要;再把副本保存到独立于原主机故障域的位置,验证能够取回和解密。
- 在恢复演练通过之前,不把这份文件标记为“已验证可恢复”。
校验摘要只能帮助检查文件是否发生变化,不能证明数据库内部一致,也不能证明备份包含了正确的库。数据库、文件存储和队列若分别取快照,仍需检查它们的业务关联;单库一致性不等于整个系统在同一截点。
4. 在隔离环境恢复,并核对业务状态
演练环境使用新目录、新卷和独立数据库。启动应用之前核对最终生效的连接目标与挂载路径,确保不会把生产卷挂进去;仅改容器名称远远不够。默认阻断对生产数据库、付费上游、支付和邮件等服务的外连,关闭定时任务、回调处理和消息消费,保留受控的本地模拟入口。
先用备份对应的原网关版本恢复,验证旧环境可重建;再用另一份可丢弃的恢复副本演练升级和数据库迁移,避免改坏唯一的恢复样本。实际凭据若在备份中,应受限保管;演练对接使用替代配置和测试凭据,不在截图或报告里展示原密钥。
| 检查项 | 怎样验收 | 不能只看什么 |
|---|---|---|
| 数据库恢复 | 恢复过程无未解释错误,关键表、索引、约束、角色与扩展符合预期 | 文件能解压 |
| 账户与权限 | 抽样检查管理员与普通用户的权限边界,确认禁用状态仍生效 | 登录页能打开 |
| 余额与账单 | 按同一截点核对账户余额、关键交易标识和结算状态 | 总行数看起来差不多 |
| 路由与密钥 | 核对渠道配置,验证受保护凭据的恢复条件,模拟请求走预期路由 | 渠道名称还在 |
| 恢复耗时 | 从取得备份到完成业务验收计时,并记录人工步骤 | 仅数据库导入耗时 |
本地模拟可以检查鉴权、路由与本地计费逻辑,但不能证明真实上游的额度、可用性或真实支付回调都正常。完成演练后记录未验证范围。备份含有用户信息与可能的密钥材料,应加密、限制读取、管理保留期限;加密密钥不能只有一份且只放在原主机上。
5. 回滚时处理备份之后的新写入
程序回到旧镜像,不代表数据库也能回退。新版本可能执行不兼容的结构迁移,旧程序是否能读新结构必须看具体项目的迁移说明。没有明确支持时,不能只替换镜像就宣称回滚成功。
下面是假设场景,不是实测:15:00 停写并取得一致备份;15:10 升级后重新开放写入;15:25 发现问题。直接恢复 15:00 的备份,会丢失 15:10—15:25 期间只保存在本库里的新增或修改。外部已经完成的付款和付费调用,并不会因为你恢复旧库而撤销。
发生这种情况,先重新限制写入、保留故障时数据库与审计证据,再按已经演练的迁移恢复或数据补偿方案处理。以交易标识核对新增充值、扣费及未完成请求,防止重复入账或重复扣款。不要在唯一的故障库上临时试拼 SQL,也不要对无法确认结果的付费请求直接批量重放。
如果不能可靠补齐这些记录,就应在升级前延长停写窗口,先完成迁移验收再开放写入,或另行设计更完整的恢复机制。停机时长与数据丢失风险需要提前选定,不能靠一个备份压缩包同时解决。
6. 出现这些现象,先停止升级
- 备份来自哪个库、哪个卷无法确认:回到部署清单核对,不能凭文件名猜。
- SQLite 副本缺少最近记录:检查备份方式、WAL 和实际截点,不手动删除生产 WAL。
- PostgreSQL 恢复报角色、扩展或权限错误:核对全局对象与版本依赖,不把“忽略错误后能启动”当通过。
- 恢复后余额不一致:先确认比较的是同一截点,再查在途请求、回调与跨系统记录,不直接手改余额抹平差异。
- 演练容器能访问真实付费上游或生产库:停止演练应用,修正连接和网络隔离,再从干净副本重试。
升级验收记录至少应包含:原版本与目标版本、数据位置、备份方法与截点、可取回的加密副本、恢复步骤和耗时、业务抽样结果、未验证范围、回滚负责人及开放写入的条件。缺少关键项时,推迟升级比留下一个无法验证的“成功备份”更可控。
延伸阅读:网关服务器容量评估、正式上线前检查清单。前者处理容量,后者处理上线配置;本篇专门处理升级时的数据恢复。
7. 一手资料与适用边界
资料核对日期:2026-10-16。以下链接用于核对存储与数据库机制;实际操作应选择自己安装版本的文档。本文不提供某个网关品牌的通用升级命令,也没有声称验证任何生产环境的恢复能力。