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

7.2 KiB
Raw Blame History

name, description
name description
database-migration 设计、审查、执行和验证 MySQL 数据库结构迁移与数据迁移,覆盖建表、改表、字段变更、索引调整、数据回填、版本命名、备份、回滚和迁移记录。用户要求新增或修改数据库表结构、编写迁移 SQL、升级现有数据、执行数据库迁移或排查迁移失败时使用。

数据库迁移

目标

在不丢失数据、不中断业务或明确控制影响范围的前提下,完成可审查、可验证、可回滚的数据库结构或数据变更。优先遵循项目现有的迁移工具、目录结构、命名方式和发布流程;本项目默认由数据库管理员人工执行 SQL应用启动不会自动修改表结构。

工作流程

1. 收集上下文

  • 阅读项目根目录及相关子目录的 AGENTS.mdREADME.md.env.example 和数据库配置。
  • 检查 sql/sql/migrations/、Flyway 或 Liquibase 配置,以及现有迁移文件的命名和执行顺序。
  • 阅读受影响的实体、Mapper、Service、接口 DTO、测试和查询代码确认旧结构的所有使用方。
  • 从目标数据库只读检查当前环境、数据库名、表结构、索引、约束、字符集和数据量。不要仅根据代码或迁移文件推测线上结构。
  • 为本次任务生成任务 ID并保留用户提供的需求引用或工单号作为关联引用。日志只记录任务 ID、目标环境、迁移版本、阶段和结果不记录密码、令牌、完整连接串或敏感数据。

2. 评估变更

先明确并向用户说明以下内容:

  • 目标数据库和环境,禁止把开发库、测试库和生产库混淆。
  • 变更类型:结构迁移、数据迁移、兼容性迁移,或多阶段发布。
  • 预计影响的表、字段、索引、约束、数据行数、锁等待和停机窗口。
  • 是否需要备份、回填、双写、灰度、校验和后续清理。
  • 正向迁移失败和已提交后回滚的具体方式。

涉及 DROPTRUNCATE、无条件 DELETE、大范围 UPDATE、删除字段、删除索引、修改字段类型或破坏兼容性的约束变更时,必须先展示脱敏后的精确 SQL、目标范围、预计影响行数和回滚方案等待用户明确确认后再执行。用户未明确授权时只生成脚本和检查结果不执行写操作。

3. 编写迁移文件

  • 使用项目已有的版本格式;本项目优先使用 sql/migrations/V<版本>__<英文描述>.sql,版本必须唯一且可排序。
  • 新建或最终修改表结构时,同步维护 sql/<大写表名>.sql,表名使用大写和下划线。
  • 表名、字段、索引和约束必须有清晰的中文注释;迁移文件中的说明性注释也使用中文。
  • 迁移文件只包含本次变更,避免夹带无关格式化、重命名或数据清理。
  • 动态表名或列名不能使用参数绑定时,只允许使用经过白名单校验的标识符并使用 MySQL 反引号;用户输入的值必须参数化,禁止拼接 SQL。
  • 对新增字段优先采用“先加可空或带默认值字段、发布兼容代码、回填并校验、最后收紧约束”的多阶段方案。
  • 大表回填应按主键范围或固定批次执行,设置合理超时,记录每批影响行数;禁止无条件全表更新。
  • 明确 MySQL DDL 的隐式提交风险。不能假设 ALTER TABLERENAME TABLE 等 DDL 能像普通 DML 一样回滚,必须准备执行前备份或可逆的反向迁移。

典型目录结构:

sql/
  USERS.sql
  migrations/
    V2__add_user_status.sql

4. 执行前检查

按顺序完成并记录检查结果:

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 条件执行 SELECTCOUNT(*),确认目标主键集合和预计行数。
  • 检查应用代码先后兼容性:旧版本代码不能因新字段、索引或约束而报错,新版本代码不能在迁移完成前读取不存在的字段。

5. 执行与观测

  • 只使用项目已有的客户端、驱动或迁移工具;密码通过环境变量或安全凭据输入,不写入命令行、脚本和日志。
  • 对可事务化的 DML 使用事务,提交前核对影响行数和关键结果;异常时回滚当前事务并停止后续批次。
  • 对不可事务化或可能隐式提交的 DDL按单个变更执行记录开始时间、结束时间、执行结果和实际影响。
  • 长耗时迁移必须分批、可暂停、可重试;重试前先判断上一次是否已提交,禁止盲目重复执行。
  • 关键日志格式至少包含:taskIdreferenceenvironmentmigrationVersionphasestatusaffectedRowsdurationMsfallback。禁止记录敏感凭据和完整业务数据。
  • 失败时给出明确兜底提示:停止后续迁移、保留现场日志、确认事务状态、检查锁和备份,再决定重试或执行反向迁移。

6. 验证与交付

  • 验证表、字段、索引、约束、字符集和默认值与预期一致。
  • 验证迁移记录只出现一次,关键数据行数、唯一性、关联完整性和业务不变量保持正确。
  • 对回填抽样检查前后值;对大表使用聚合校验,避免输出敏感原始数据。
  • 运行受影响的后端测试、查询测试和必要的 API 只读验证;确认应用日志无迁移相关异常。
  • 输出迁移版本、执行环境、实际影响行数、验证结果、是否提交、回滚方式、遗留风险和后续清理事项。
  • 若只生成文件而未执行,明确标注“未连接数据库、未执行写操作、待 DBA 审批”。

回滚规范

  • 结构变更提供可执行的反向 SQL或说明只能通过备份恢复、影子表切换或补偿迁移回滚。
  • 数据迁移保留原值或生成可定位的补偿条件;不能用猜测值覆盖原数据。
  • 回滚前重新确认目标环境、迁移版本、影响范围和备份时间点;回滚后重复执行结构和数据校验。
  • 任何删除文件、删除数据、清空表或恢复数据库的操作都必须二次确认,并记录操作日志、备份位置和恢复步骤。

常见风险

  • 版本号冲突或执行顺序错误:先扫描所有迁移文件并核对已执行记录。
  • 加字段或改类型导致锁表:评估表规模和 MySQL 在线 DDL 能力,必要时拆分窗口或采用影子表方案。
  • 回填重复执行:设计幂等条件,例如只处理目标字段为空且满足业务条件的记录。
  • 字符集或时区不一致:执行前检查连接、表和列的字符集,以及 @@time_zone
  • 迁移成功但应用失败:优先保持旧代码可兼容,回滚应用版本;不要直接回滚已提交的 DDL除非已验证反向迁移。