2026-09-19 17:30:20 +08:00
|
|
|
|
# 数据库迁移操作手册
|
|
|
|
|
|
|
|
|
|
|
|
本文是开发、测试和发布人员的日常操作入口。设计原则和生产边界见仓库文档 [数据库版本迁移与 Jenkins 自动发布方案](../../../docs/数据库版本迁移与Jenkins自动发布方案.md);当前阶段的初始化事实见本目录 [README.md](README.md)。
|
|
|
|
|
|
|
|
|
|
|
|
## 先分清两类 SQL
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 位置 | 用途 | 能否在已有业务库重复执行 |
|
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
| 空库初始化 | `deploy/sql/头程数据库统一增量-MySQL8.sql`、`海外区域统一增量-MySQL8.sql` | 初始化一个不存在或获授权清空的区域数据库 | 不能 |
|
|
|
|
|
|
| 版本迁移 | `deploy/sql/migrations/{cn|overseas}/<schema>/V<数字>__<说明>.sql` | 机制启用后对已有数据库逐步升级 | 由 Flyway 按历史自动跳过已成功版本 |
|
|
|
|
|
|
|
|
|
|
|
|
当前测试分支只完成了版本迁移的离线工具和目录骨架。没有冻结基线、没有具体业务变更时,不要复制初始化 SQL 生成 `V1`,也不要连接测试或生产数据库试跑。
|
|
|
|
|
|
|
2026-09-23 17:47:50 +08:00
|
|
|
|
## 编号与功能分支规则(2026-09-22 确认)
|
|
|
|
|
|
|
|
|
|
|
|
SQL 编号统一保持 **`V1、V2、V3、V4、V5……`**,不使用时间戳。每个数据库独立计数,由工具生成下一个整数;数字变长不需要重置或重新编号。
|
|
|
|
|
|
|
|
|
|
|
|
- 有数据库逻辑变更才新增迁移;普通提交、重复测试和重复部署不增加 SQL 编号。
|
|
|
|
|
|
- 同一未冻结、未在保留历史环境执行的变更可以反复编辑;成功执行后不改内容、不改编号,修复新增迁移。失败候选的受控修订仍按方案第 13.2.1 节处理。
|
|
|
|
|
|
- 功能分支从最新 `main` 创建;进入共享测试前先拉取并合并最新 `main`,解决代码和同库编号冲突。只允许调整尚未冻结、未在保留历史环境执行的草稿。
|
|
|
|
|
|
- 两人并行开发,共享测试、合并和发布依次进行。前一功能完成发布或处理失败后,下一功能同步 main 再进入测试;若前一功能留下未合并 SQL 或未决失败,先处理测试起点,不能直接继续验收。
|
|
|
|
|
|
- 测试后 main 又变化,必须重新同步和验证。合并 main 后构建正式候选并再次自动验证,生产使用这份正式候选,不重新构建或修改 SQL。
|
|
|
|
|
|
|
|
|
|
|
|
**生产发布版本另外记为 `release-1、release-2……`,不与 SQL 编号绑定。** 例如 `release-12` 中 Auth 是 `V3`、Order 是 `V7`;只有代码变化也可以发布 `release-13`,SQL 编号保持不变。
|
|
|
|
|
|
|
|
|
|
|
|
目标流程由 Jenkins 为新的生产候选自动分配发布编号;成功后更新当前生产版本并记录 Git 标签、完整提交、镜像 digest 和 SQL 清单。失败编号保留且不复用,同一制品重试沿用原编号;修改制品后分配新编号并重新验证。main 是已合并代码,生产实际版本以成功发布记录为准;发布失败时还需核对各库、各服务的实际状态,不能假定全部未变。
|
|
|
|
|
|
|
|
|
|
|
|
当前工具只依据当前分支的迁移目录生成整数编号;跨分支冲突预检、main 同步门禁、`release-N` 分配和标签归档尚待接入,不因写入本手册就视为已自动执行。
|
|
|
|
|
|
|
2026-09-19 17:30:20 +08:00
|
|
|
|
## 日常开发:新建和修改迁移
|
|
|
|
|
|
|
|
|
|
|
|
以下命令均从 `baiyue-firstleg` 根目录执行,PowerShell 和 Bash 都可以使用 Node 命令。
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 确认所属区域和 schema
|
|
|
|
|
|
|
|
|
|
|
|
打开 [migration-scopes.json](migration-scopes.json),只选择已登记的区域和 schema。服务没有数据库时不创建空迁移;例如 `gateway` 不对应 schema。
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
node deploy/sql/scripts/db-migrations.mjs check
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 自动创建迁移文件
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
node deploy/sql/scripts/db-migrations.mjs new `
|
|
|
|
|
|
--region CN `
|
|
|
|
|
|
--schema baiyue_auth `
|
|
|
|
|
|
--description add_login_audit
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
工具会读取该 schema 当前最大编号并创建下一个文件,例如:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
deploy/sql/migrations/cn/baiyue_auth/V1__add_login_audit.sql
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
开发者只输入区域、schema 和说明,不输入版本号。说明中的英文字母、数字和下划线会用于文件名;只有中文说明时文件名使用 `change`,完整中文说明仍保留在 SQL 头部。并发创建使用独占文件创建,不覆盖已有文件。
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 填写 SQL 和断言
|
|
|
|
|
|
|
|
|
|
|
|
在生成的文件中完成实际 SQL,并补充文件头的前置、后置检查。一个文件只修改一个 schema,不写 `USE`、`CREATE DATABASE`、跨 schema 限定名或真实业务数据。
|
|
|
|
|
|
|
|
|
|
|
|
同一文件在开发阶段可以反复编辑,但一旦在保留历史的环境成功执行或进入冻结候选,就不能再改。没有成功记录但测试候选已失败时,只有方案第 13.2.1 节的受控修订流程可以保留原编号修正。
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 提交前离线检查
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
node deploy/sql/scripts/db-migrations.mjs check
|
|
|
|
|
|
node --test deploy/sql/scripts/db-migrations.test.mjs scripts/script-documentation-contract.test.mjs
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`check` 会验证范围映射、文件名、重复版本、跨 schema 引用、跨库控制语句,以及可选的受保护文件清单。它不连接数据库,也不证明 SQL 语义正确。
|
|
|
|
|
|
|
|
|
|
|
|
## 生成测试候选
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 只选择本次要发布的服务
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
node deploy/sql/scripts/db-migrations.mjs plan `
|
|
|
|
|
|
--services auth,iam `
|
|
|
|
|
|
--regions CN `
|
|
|
|
|
|
--out .codex-tmp-release-manifest.json
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`plan` 自动生成逐库目标、完整迁移文件列表和 SHA-256。它只包含选中服务及评审确认的 schema;同一提交中其他服务的 SQL 不会被自动带入。没有迁移文件的允许 schema 目标为 `0.0.0`,范围外 schema 不生成目标。
|
|
|
|
|
|
|
|
|
|
|
|
生成的 manifest 是制品,不是开发者长期维护的源码文件。不要手改、提交或在测试与生产之间重新生成;测试通过后应复用同一个 manifest、SQL 包和镜像 digest。
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 查看只读执行计划
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
node deploy/sql/scripts/db-migrations.mjs run `
|
|
|
|
|
|
--manifest .codex-tmp-release-manifest.json `
|
|
|
|
|
|
--dry-run
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
当前阶段 `run` 只支持 `--dry-run`,用于确认要执行哪些库和版本。真实 Flyway 执行、测试数据库凭据、环境锁和 Jenkins 阶段属于后续阶段 C,尚未由本命令启用。不要自行设置开关连接真实数据库。
|
|
|
|
|
|
|
|
|
|
|
|
## 测试环境的目标流程
|
|
|
|
|
|
|
|
|
|
|
|
完成基线登记和阶段 C 接入后,测试部署按以下顺序自动完成:
|
|
|
|
|
|
|
|
|
|
|
|
1. 构建并冻结代码、SQL manifest 和全部目标镜像。
|
|
|
|
|
|
2. 获取测试环境锁,核验实例身份、基线和当前 Flyway 历史。
|
|
|
|
|
|
3. 对允许迁移的 schema 做全量预检;任何库失败都不开始其他库的写入。
|
|
|
|
|
|
4. Flyway 按完整版本链执行待迁移版本,成功版本自动跳过。
|
|
|
|
|
|
5. 严格复验历史、结构和必要种子。
|
|
|
|
|
|
6. 只有数据库阶段全部通过,才部署同一批应用镜像。
|
|
|
|
|
|
7. 同一候选重复执行时只执行数据库尚未成功的版本,不重复执行成功 SQL。
|
|
|
|
|
|
|
|
|
|
|
|
测试环境验证至少包括空库到目标、上一发布版本到目标、带合成数据升级、重复部署、失败阻断应用部署和跨区域部分成功。测试报告必须绑定 manifest、SQL 哈希、镜像 digest 和测试起点。
|
|
|
|
|
|
|
|
|
|
|
|
## 生产晋级
|
|
|
|
|
|
|
|
|
|
|
|
生产不重新生成 SQL,也不重新编号。只选择已经通过测试的原候选制品,执行器只处理生产当前缺少的成功迁移;已成功的版本自动跳过。生产数据库高于候选目标、存在未纳入清单的成功迁移、失败记录、校验和变化或起点与测试演练不一致时,发布直接阻断。
|
|
|
|
|
|
|
|
|
|
|
|
生产迁移成功后才部署同批镜像。应用回滚不执行旧 SQL;只有经过兼容性记录证明的旧镜像才允许回滚。数据库逆向回滚依赖受控备份恢复或新的向前修复迁移。
|
|
|
|
|
|
|
|
|
|
|
|
## 失败时怎么处理
|
|
|
|
|
|
|
|
|
|
|
|
| 情况 | 处理方式 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| `check` 失败 | 修正范围、文件名或 SQL 引用后重新检查;不能用忽略参数跳过 |
|
|
|
|
|
|
| 测试迁移失败、从未成功且未进生产 | 按方案 13.2.1 撤销旧候选、确认无残留和排队任务后,允许修订同一编号;旧制品只读保留,新候选重新完成空库、升级和数据测试 |
|
|
|
|
|
|
| 任一环境已成功执行该版本 | 不修改原文件、不复用编号修订;创建新的向前修复迁移 |
|
|
|
|
|
|
| 生产迁移失败或部分 DDL 已提交 | 停止应用部署,保留失败历史和证据,进入专项恢复;不能简单加版本号掩盖状态 |
|
|
|
|
|
|
| 国内成功、海外失败 | 保留国内成功结果,停止整批应用部署,先按区域恢复或补齐证据;不重放国内成功版本 |
|
|
|
|
|
|
| Jenkins 超时、取消或重启 | 先确认数据库会话和真实历史,状态未确认前禁止重试或清理制品 |
|
|
|
|
|
|
|
|
|
|
|
|
## 日常维护规则
|
|
|
|
|
|
|
|
|
|
|
|
### 代码和目录
|
|
|
|
|
|
|
|
|
|
|
|
- `migration-scopes.json` 是区域、schema、服务归属和顺序的低频配置;增加服务、改数据库归属或调整依赖时才修改,并由两名开发者一起评审。
|
|
|
|
|
|
- `migrations/` 是上线迁移唯一事实来源;不要把模块 `resources/db/`、历史脚本或临时 SQL 当作发布目录。
|
|
|
|
|
|
- 版本号只在同一 schema 内递增,废弃编号不重新分配给其他业务目的;不同 schema 可以使用相同编号。
|
|
|
|
|
|
- 成功迁移、冻结候选、发布 manifest、失败原文和修订记录都必须长期留档;普通构建清理不能删除它们。
|
|
|
|
|
|
- 不提交生成的 manifest、日志、凭据、连接串或真实数据;Jenkins 制品保存 SQL、manifest 和镜像 digest。
|
|
|
|
|
|
|
|
|
|
|
|
### 什么时候需要新增迁移
|
|
|
|
|
|
|
|
|
|
|
|
新增或修改表、列、索引、约束、默认值、触发器、必要系统种子,以及会改变数据库读写要求的 Mapper/持久化 SQL,都要在评审中确认是否需要迁移。需要时用 `new` 创建;不需要时记录具体理由并补受影响数据库读写测试,不能只因为没有 SQL 文件就默认通过。
|
|
|
|
|
|
|
|
|
|
|
|
### 谁负责什么
|
|
|
|
|
|
|
|
|
|
|
|
变更开发者负责 SQL 语义、前后断言、数据影响和代码关联;另一名开发者检查范围、兼容性和测试证据;发布执行人只选择已通过测试的候选并触发自动流程。任何人都不应直接登录服务器手工执行生产 SQL。
|
|
|
|
|
|
|
|
|
|
|
|
## 当前实现边界
|
|
|
|
|
|
|
|
|
|
|
|
当前测试分支已经可以使用 `new`、`check`、`plan` 和 `run --dry-run`,并有对应离线合同测试。以下事项仍未启用:
|
|
|
|
|
|
|
|
|
|
|
|
- 生产或测试数据库基线登记;
|
|
|
|
|
|
- Flyway 实际执行和历史表校验;
|
|
|
|
|
|
- Jenkins 的数据库阶段、环境锁和构建/部署解耦;
|
2026-09-23 17:47:50 +08:00
|
|
|
|
- 功能分支同步检查、合并后候选验证、生产 `release-N` 自动编号及发布标签归档;
|
2026-09-19 17:30:20 +08:00
|
|
|
|
- 真实测试环境部署与生产晋级。
|
|
|
|
|
|
|
|
|
|
|
|
因此现在可以开始编写和评审迁移文件,但不能把离线检查通过当作测试或生产发布通过。
|