Files
baiyue-firstleg/deploy/sql/数据库迁移操作手册.md
T
2026-09-23 17:47:50 +08:00

159 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据库迁移操作手册
本文是开发、测试和发布人员的日常操作入口。设计原则和生产边界见仓库文档 [数据库版本迁移与 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-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` 分配和标签归档尚待接入,不因写入本手册就视为已自动执行。
## 日常开发:新建和修改迁移
以下命令均从 `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 的数据库阶段、环境锁和构建/部署解耦;
- 功能分支同步检查、合并后候选验证、生产 `release-N` 自动编号及发布标签归档;
- 真实测试环境部署与生产晋级。
因此现在可以开始编写和评审迁移文件,但不能把离线检查通过当作测试或生产发布通过。