Files
training/.codex/skills/database-migration/SKILL.md
2026-07-28 19:31:07 +08:00

110 lines
7.2 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.

---
name: database-migration
description: 设计、审查、执行和验证 MySQL 数据库结构迁移与数据迁移,覆盖建表、改表、字段变更、索引调整、数据回填、版本命名、备份、回滚和迁移记录。用户要求新增或修改数据库表结构、编写迁移 SQL、升级现有数据、执行数据库迁移或排查迁移失败时使用。
---
# 数据库迁移
## 目标
在不丢失数据、不中断业务或明确控制影响范围的前提下,完成可审查、可验证、可回滚的数据库结构或数据变更。优先遵循项目现有的迁移工具、目录结构、命名方式和发布流程;本项目默认由数据库管理员人工执行 SQL应用启动不会自动修改表结构。
## 工作流程
### 1. 收集上下文
- 阅读项目根目录及相关子目录的 `AGENTS.md``README.md``.env.example` 和数据库配置。
- 检查 `sql/``sql/migrations/`、Flyway 或 Liquibase 配置,以及现有迁移文件的命名和执行顺序。
- 阅读受影响的实体、Mapper、Service、接口 DTO、测试和查询代码确认旧结构的所有使用方。
- 从目标数据库只读检查当前环境、数据库名、表结构、索引、约束、字符集和数据量。不要仅根据代码或迁移文件推测线上结构。
- 为本次任务生成任务 ID并保留用户提供的需求引用或工单号作为关联引用。日志只记录任务 ID、目标环境、迁移版本、阶段和结果不记录密码、令牌、完整连接串或敏感数据。
### 2. 评估变更
先明确并向用户说明以下内容:
- 目标数据库和环境,禁止把开发库、测试库和生产库混淆。
- 变更类型:结构迁移、数据迁移、兼容性迁移,或多阶段发布。
- 预计影响的表、字段、索引、约束、数据行数、锁等待和停机窗口。
- 是否需要备份、回填、双写、灰度、校验和后续清理。
- 正向迁移失败和已提交后回滚的具体方式。
涉及 `DROP``TRUNCATE`、无条件 `DELETE`、大范围 `UPDATE`、删除字段、删除索引、修改字段类型或破坏兼容性的约束变更时,必须先展示脱敏后的精确 SQL、目标范围、预计影响行数和回滚方案等待用户明确确认后再执行。用户未明确授权时只生成脚本和检查结果不执行写操作。
### 3. 编写迁移文件
- 使用项目已有的版本格式;本项目优先使用 `sql/migrations/V<版本>__<英文描述>.sql`,版本必须唯一且可排序。
- 新建或最终修改表结构时,同步维护 `sql/<大写表名>.sql`,表名使用大写和下划线。
- 表名、字段、索引和约束必须有清晰的中文注释;迁移文件中的说明性注释也使用中文。
- 迁移文件只包含本次变更,避免夹带无关格式化、重命名或数据清理。
- 动态表名或列名不能使用参数绑定时,只允许使用经过白名单校验的标识符并使用 MySQL 反引号;用户输入的值必须参数化,禁止拼接 SQL。
- 对新增字段优先采用“先加可空或带默认值字段、发布兼容代码、回填并校验、最后收紧约束”的多阶段方案。
- 大表回填应按主键范围或固定批次执行,设置合理超时,记录每批影响行数;禁止无条件全表更新。
- 明确 MySQL DDL 的隐式提交风险。不能假设 `ALTER TABLE``RENAME TABLE` 等 DDL 能像普通 DML 一样回滚,必须准备执行前备份或可逆的反向迁移。
典型目录结构:
```text
sql/
USERS.sql
migrations/
V2__add_user_status.sql
```
### 4. 执行前检查
按顺序完成并记录检查结果:
```sql
SELECT DATABASE() AS current_database,
USER() AS connected_user,
VERSION() AS mysql_version;
SHOW TABLES;
SHOW CREATE TABLE `目标表`;
SELECT TABLE_NAME, TABLE_ROWS
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME IN ('目标表');
```
- 再次核对目标环境、迁移版本是否已执行、脚本是否幂等或明确禁止重复执行。
- 检查备份可用性、恢复演练状态、磁盘空间、长事务、锁等待和业务低峰窗口。
- 使用 `EXPLAIN` 或等价方式评估回填、校验和索引变更的执行计划。
- 执行数据变更前,用与变更完全一致的 `WHERE` 条件执行 `SELECT``COUNT(*)`,确认目标主键集合和预计行数。
- 检查应用代码先后兼容性:旧版本代码不能因新字段、索引或约束而报错,新版本代码不能在迁移完成前读取不存在的字段。
### 5. 执行与观测
- 只使用项目已有的客户端、驱动或迁移工具;密码通过环境变量或安全凭据输入,不写入命令行、脚本和日志。
- 对可事务化的 DML 使用事务,提交前核对影响行数和关键结果;异常时回滚当前事务并停止后续批次。
- 对不可事务化或可能隐式提交的 DDL按单个变更执行记录开始时间、结束时间、执行结果和实际影响。
- 长耗时迁移必须分批、可暂停、可重试;重试前先判断上一次是否已提交,禁止盲目重复执行。
- 关键日志格式至少包含:`taskId``reference``environment``migrationVersion``phase``status``affectedRows``durationMs``fallback`。禁止记录敏感凭据和完整业务数据。
- 失败时给出明确兜底提示:停止后续迁移、保留现场日志、确认事务状态、检查锁和备份,再决定重试或执行反向迁移。
### 6. 验证与交付
- 验证表、字段、索引、约束、字符集和默认值与预期一致。
- 验证迁移记录只出现一次,关键数据行数、唯一性、关联完整性和业务不变量保持正确。
- 对回填抽样检查前后值;对大表使用聚合校验,避免输出敏感原始数据。
- 运行受影响的后端测试、查询测试和必要的 API 只读验证;确认应用日志无迁移相关异常。
- 输出迁移版本、执行环境、实际影响行数、验证结果、是否提交、回滚方式、遗留风险和后续清理事项。
- 若只生成文件而未执行,明确标注“未连接数据库、未执行写操作、待 DBA 审批”。
## 回滚规范
- 结构变更提供可执行的反向 SQL或说明只能通过备份恢复、影子表切换或补偿迁移回滚。
- 数据迁移保留原值或生成可定位的补偿条件;不能用猜测值覆盖原数据。
- 回滚前重新确认目标环境、迁移版本、影响范围和备份时间点;回滚后重复执行结构和数据校验。
- 任何删除文件、删除数据、清空表或恢复数据库的操作都必须二次确认,并记录操作日志、备份位置和恢复步骤。
## 常见风险
- 版本号冲突或执行顺序错误:先扫描所有迁移文件并核对已执行记录。
- 加字段或改类型导致锁表:评估表规模和 MySQL 在线 DDL 能力,必要时拆分窗口或采用影子表方案。
- 回填重复执行:设计幂等条件,例如只处理目标字段为空且满足业务条件的记录。
- 字符集或时区不一致:执行前检查连接、表和列的字符集,以及 `@@time_zone`
- 迁移成功但应用失败:优先保持旧代码可兼容,回滚应用版本;不要直接回滚已提交的 DDL除非已验证反向迁移。