你的Postgres迁移真的安全吗?

Is your Postgres migration safe or not safe?

在Postgres数据库维护中,一次看似无害的迁移操作可能导致服务中断。safe-not-safe工具通过解析migration.sql,利用libpg_query和wasm技术,精准识别潜在风险。它能检测出如常量列默认值、并发索引构建、约束验证等安全模式,避免锁表、重写和发布风险。对于开发者而言,这不仅是代码检查,更是生产环境稳定性的保障。无需复杂配置,一行命令即可判断迁移是否安全,让数据库变更不再提心吊胆。

现代Postgres版本中,字面量默认值仅涉及元数据更新,不会重写现有行。
  1. orf

    这类基于规则的迁移安全检查很简单,但远非完备。

    问题在于,某些迁移的安全性取决于数据库的状态,而仅凭 DDL 语句无法体现这一点。例如,修改列类型可能是无操作(no-op),也可能是独占锁定的表重写,这完全取决于列的原始类型。

    如果你修改的列是外键,还可能引发其他陷阱,导致多张表被锁定。

    几年前我曾深入钻研过这个问题,并构建了一个系统 [1],用于在给定迁移与实时模式之间进行内省,让 Postgres 直接告诉你它打算做什么 [2]。

    如果能内置更好的支持(比如针对 DDL 语句的 EXPLAIN?),那就太好了,但我觉得这个方向比静态规则集更安全、更准确。

    安全性还取决于被修改表的大小/活跃度(即重写空表是没问题的)。拥有对数据库执行的锁和操作的准确描述,能让你与生产指标集成,从而真正确定整个数据库集群在现实世界中的安全性,而不是靠猜。

  2. agubelu

    我们算是运气不错,不太需要为此担心,因为我们用于模式管理的工具 [1] 消除了大多数增量模式变更对迁移的需求。

    它拒绝自动生成可能具有破坏性的迁移,因此你必须手动编写这些迁移,而这个工具在这种情况下会很有用。不过,既然这类迁移是例外而非常态,我们会审查得更仔细。

  3. fabianlindfors

    虽然有用,但我认为像这样的迁移 linter 并不能让人足够安心。我维护了一个零停机模式迁移工具好几年了,它试图涵盖所有可能让你“自己挖坑自己跳”的情况:https://github.com/fabianlindfors/reshape

    它确保迁移不会锁定数据库,但更重要的是,它支持在部署期间同时兼容新旧模式,并自动在两者之间同步数据,从而实现应用的零停机发布。它还处理回填(backfills)以及其他通常在使用标准 SQL 命令时需要多次独立部署才能完成的操作。

同日更多故事

2026-09-26