DBAtlas · 数据库运维图谱

Schema 迁移 CI/CD(Flyway/Liquibase)

症状

目标:用带版本号的迁移文件管理数据库 schema 变更;在 CI/CD 中使用 Flyway 或 Liquibase 自动但可控地应用这些变更。

1. 创建带版本号的迁移文件(Vxxx__name.sql)

将每个 schema 变更写入一个带递增版本号的命名文件;Flyway 的约定是 V<version>__<description>.sql(例如 V1__initial_schemas.sql、V2__orders_table.sql)。这些文件保存在 Git 中,并按版本顺序应用。已应用的迁移会记录在跟踪表中(Flyway 中为 flyway_schema_history),因此每个迁移只运行一次。

PostgreSQL

-- V2__orders_table.sql
CREATE TABLE orders (
  id       bigserial PRIMARY KEY,
  amount    numeric(12,2) NOT NULL,
  created_at   timestamptz DEFAULT now()
);

2. 用校验和保证不可变性

Flyway/Liquibase 会存储每个已应用迁移的校验和。若之后编辑已应用的文件,校验和将不再匹配,工具会报错。规则:切勿编辑已应用的迁移;用新的版本文件进行修正。这保证所有环境(dev/staging/prod)拥有相同的历史。

PostgreSQL

# repair on checksum mismatch (use with care):
flyway repair
# the right way: add the change in a new Vx file

3. 为现有数据库设置基线(baseline)

将迁移工具接入已有数据但没有迁移历史的数据库时,使用 baseline;它将当前状态视为“起始版本”,不会尝试重新创建现有对象。baselineVersion 之后的迁移会被应用。在从零构建的环境中无需 baseline;迁移从 V1 开始运行。

PostgreSQL

flyway baseline -baselineVersion=1 -baselineDescription="existing schema"

4. 在 CI 流水线中自动迁移

在 CI 步骤中运行迁移工具,将变更自动应用到测试和预发布数据库;migrate 命令只运行新的(未应用的)文件,且是幂等的。先将迁移应用到临时/一次性数据库并进行验证,可在有问题的 SQL 到达生产环境之前将其拦截。schema 必须在部署应用代码之前完成迁移(采用向后兼容的变更)。

PostgreSQL

# CI step (Flyway)
flyway -url=jdbc:postgresql://staging/appdb \
  -user=ci -password=$PW migrate

MySQL

flyway -url=jdbc:mysql://staging/appdb \
  -user=ci -password=$PW migrate

5. 为生产环境添加人工审批关卡

测试/预发布环境自动执行,但生产环境的 migrate 应要求人工审批;在 CI/CD 中添加“审批关卡”(人工审批)步骤。审批之前,用 'flyway info' 或 'liquibase status' 展示将要运行哪些迁移。应用到生产环境之前务必做一次新的备份,以便出问题时可以回退。

PostgreSQL

# what will run before approval?
flyway info
# liquibase equivalent:
liquibase status --verbose

6. 定义可逆性和回退策略

Flyway Community 没有自动 undo;应采用只向前迁移的原则:不是撤销错误,而是编写一个新的迁移来修正它。Liquibase changeset 可以定义 rollback 块,并用 'liquibase rollback' 回退。最稳妥的策略:保持变更小而向后兼容,在高风险操作(删除列)之前做备份,并准备书面的回退方案。

PostgreSQL

-- Liquibase rollback example (inside a changeset)
--changeset dev:2
CREATE TABLE orders (...);
--rollback DROP TABLE orders;
在 DBAtlas 中打开 →