6 个月预付 −28% · 1 年预付 −50%比较方案
PrivacyNodes
发布工程

保持数据库变更跨发布兼容

将应用回滚和数据回滚视为独立的决策。增量式模式变更可以保留一条返回兼容代码的路径。在同一发布中重命名或删除数据,可能在应用得到验证之前就切断该路径。

PrivacyNodes 工程笔记 · 已审核 · 3 分钟阅读

梳理每个读取方和写入方

在隔离的模式和具有代表性的脱敏数据上开展工作。你需要当前和下一版应用、对迁移框架的了解、经过评审的备份策略,以及对长事务的可见性。要纳入工作进程、计划任务、报表和较旧的应用实例。API 可能更新很快,而长时间运行的工作进程仍在写入旧列。

我们的示例报表服务将导出标签存储在 label 并希望使用 display_name。这是一个设计示例,不是通用的可运行 SQL。在选择迁移语法或锁设置之前,请确认你确切的 PostgreSQL 版本和框架。

在不弃用旧表示的前提下进行扩展

首先引入新的可空字段。部署一个兼容性版本,在一个事务中同时写入两个值,并在数据不完整时按所需的回退逻辑读取。定义当客户在回填期间编辑记录时会发生什么。重试不得创建第二个逻辑导出。

PostgreSQL ALTER TABLE 操作会获取锁,锁的级别取决于子命令。一个小变更可能排在长事务后面等待,然后阻碍其他工作。在演练期间审查具体操作并观察等待情况;增量式并不意味着无锁。

技术参考: PostgreSQL ALTER TABLE · PostgreSQL 显式锁定.

让兼容性边界清晰可见

示例发布兼容性矩阵
模式与写入方读取方行为恢复决策
仅存在 label支持旧代码先添加新字段
两个字段;仅写旧字段的写入方仍然存在将 label 作为权威读取暂不切换读取方
所有写入方双写;已验证回填新字段可以成为权威仅回滚到兼容的双写代码
旧字段已删除任何代码都不得引用 label旧产物不兼容

针对缺失值的回退无法检测非空但过时的新值。在切换读取方之前,先弃用仅写旧字段的写入方并验证一致性。在读取方切换后回滚到仅写旧字段的代码,可能会重新产生分歧。请保留兼容性版本作为经过评审的恢复产物。

以有界、可重启的工作进行回填

找到需要复制的行,同时不覆盖较新的客户编辑。使用稳定的排序、并发安全的更新条件和根据工作负载选择的批次大小。持久化进度,以便失败时可以在已知边界处恢复。监控写入量、锁等待、请求延迟以及存在时的复制情况。

没有一种批次大小对所有应用都安全。在演练中,将小批量与正常流量进行比较,然后选择暂停或停止规则。如果某个批次失败,在重试之前检查已提交的内容。无限重试循环可能将可恢复的不匹配变成持续的数据库压力。

检查语义,而不仅是已填充的行

验证缺失值、具有代表性的标签、新记录以及对现有导出的更新。统计非空行可能看起来正确,而值却是从错误的来源复制的。针对部分填充的数据测试兼容性产物,并演练在部署前启动的工作进程。

记录模式版本、迁移修订版、完成标准和互不兼容的组合。在删除任一项之前,先检查回退使用情况和一致性。如果检查失败,停止回填或推进,保留证据,并选择兼容的产物或经过评审的前向修复。不要声称应用回滚可以重建已提交的数据。

在另一次经过评审的发布中弃用旧字段

当回填和观察期满足你的标准后,移除旧的读取和写入。除交互式路由外,也要检查不频繁的任务。删除旧字段应属于后续变更,并有其自身的恢复决策,这样发布问题就不会迫使你将代码修复与数据重建合并在一起。

如果弃用后出现坏数据,停止进一步损害,并使用恢复计划或经批准的修复。不要仅仅因为工具提供了回滚按钮就执行破坏性的向下迁移。将矩阵附加到 发布记录 并演练 数据恢复 然后再更改生产环境。有用的结果是明确的兼容性边界,而不是零停机保证。

官方参考

本文档已针对本文进行审核。示例是规划练习,不是已在 PrivacyNodes 服务器上测试过的命令。请查阅你所安装版本的文档。