← 中文资源

简体中文版本

在 CI 中测试迁移回滚

在一次性数据库上执行、回滚并重新应用每个迁移,回滚路径出错或结构漂移时让构建失败。

阅读英文原文

概述

多数团队只验证前进路径,回滚路径往往在事故中才第一次执行。回滚报错、留下孤立索引,或删掉上一个版本仍在读取的列,都会把普通的发布问题变成故障。要信任回滚,必须定期在接近生产的数据形状上真实执行它。

步骤

  1. 在一次性数据库上执行全部迁移并保存结构基线:
createdb app_migrate_test
DATABASE_URL=postgres://localhost/app_migrate_test pnpm migrate:up
pg_dump --schema-only --no-owner app_migrate_test > before.sql
  1. 回滚一步再重新应用,确认版本回到原点:
pnpm migrate:down && pnpm migrate:up
  1. 重新导出结构并比较,忽略 owner 与注释等噪声:
pg_dump --schema-only --no-owner app_migrate_test > after.sql
diff -u before.sql after.sql
  1. 在回滚后的结构上启动上一个版本的应用,调用健康检查与一个读接口,确认旧版本仍可运行。
  2. 在 CI 中从空库逐个迁移执行整个循环,遇到第一个失败即停止。

验证

整个循环后 diff 应无结构差异;若出现序列值或 owner 差异,应先规范化导出再比较。N-1 版本的健康检查与读接口都应返回 200。故意让某个 down 迁移漏建索引,CI 应在该迁移处失败并指出文件。

注意事项

  • 数据转换、删除列、删除枚举值等迁移本质上不可逆,应在文件中明确标记并要求备份与恢复演练。
  • 结构比较需要规范化,否则大量误报会让任务被忽略。
  • 回滚成功不代表数据没丢,破坏性变更必须单独验证备份。
  • 优先使用 expand-and-contract:先加新结构、双写、回填、切换读,再在后续版本删除旧结构。
  • 每次使用全新数据库执行,避免上一次循环的残留掩盖问题。