内容提要
Flyway的validate命令仅校验迁移文件与历史记录的完整性,不检查实际数据库结构,因此无法检测手动ALTER TABLE等外部变更导致的schema漂移。真正的漂移检测需付费版或Liquibase的diff工具,但多数团队未使用。结论:validate通过不代表数据库与迁移一致。
延伸解读
validate 的边界:文件校验而非 schema 校验
Flyway validate 的核心是比较迁移文件的校验和与历史表中的记录,确保文件未被篡改且与已应用的迁移一致。它只读取 flyway_schema_history 表,不检查实际的表、列、索引或约束。因此,手动 ALTER TABLE、外部添加索引或删除约束都不会被检测到。理解这一点有助于避免误将 validate 通过视为数据库与迁移一致的证据。
漂移检测的可用性与成本
真正的 schema 漂移检测在 Flyway 中属于付费的 Enterprise 功能(如 check -drift),或通过 Redgate 的 Pipelines 提供 Community Drift Check(仅限 PostgreSQL)。Liquibase 的开源版提供 diff 和 diff-changelog,但 diff-changelog 输出需要人工审查,且将漂移检测集成到 CI 的严重性标志是 Pro 功能。因此,多数团队实际上没有运行漂移检测,导致漂移检测“技术上可用,实践上缺失”。
修复命令的局限
Flyway repair 同样不修复 schema,它只更新历史表,重新对齐校验和并移除失败的迁移记录。这属于历史簿记,与 validate 的管辖范围相同。因此,当出现 schema 漂移时,repair 无法解决问题,只能修正历史记录。理解这一点有助于避免在漂移事件中错误地依赖 repair。
Q&A
Flyway validate 命令具体检查什么?
Flyway validate 主要检查迁移文件的完整性:它会重新计算本地迁移文件的校验和,并与 flyway_schema_history 表中存储的校验和进行比对,同时检查已应用的迁移是否仍然存在、是否有待处理的迁移。它不检查实际的数据库结构。
为什么 Flyway validate 通过不代表数据库与迁移一致?
因为 validate 只读取 flyway_schema_history 表,不检查实际的表、列、索引或约束。因此,手动执行 ALTER TABLE、其他工具添加索引或删除约束等外部变更都不会被检测到,导致数据库结构与迁移描述不一致,但 validate 仍然通过。
Flyway 有哪些真正的漂移检测功能?
Flyway 提供 check -drift 命令(企业版)用于比较目标数据库与迁移应产生的状态,并生成报告;还可以在部署时保存快照,下次运行检测外部变更。社区版有 Community Drift Check(仅限 PostgreSQL),但需要通过 Redgate 的 Flyway Pipelines 查看结果。
Liquibase 的 diff 和 diff-changelog 有什么作用?
Liquibase 的 diff 命令比较两个数据库或数据库与快照之间的差异,diff-changelog 则生成解决这些差异的变更集。两者都在开源版本中可用,但 diff-changelog 的输出需要人工检查,且将差异转化为 CI 退出代码等操作便利功能是 Pro 版特性。
Flyway 的 repair 命令能修复 schema 漂移吗?
不能。repair 命令只更新 flyway_schema_history 表,例如重新对齐校验和、删除失败的迁移记录,它不修改实际的数据库结构。
如何检测数据库 schema 漂移?
可以使用 Flyway 的企业版漂移检测功能(如 check -drift)或 Liquibase 的 diff 工具。此外,文章提到可以用 pg_dump 构建自定义的漂移检查,并集成到 CI 中。