7.2 KiB
7.2 KiB
name, description
| name | description |
|---|---|
| database-migration | 设计、审查、执行和验证 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 一样回滚,必须准备执行前备份或可逆的反向迁移。
典型目录结构:
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条件执行SELECT或COUNT(*),确认目标主键集合和预计行数。 - 检查应用代码先后兼容性:旧版本代码不能因新字段、索引或约束而报错,新版本代码不能在迁移完成前读取不存在的字段。
5. 执行与观测
- 只使用项目已有的客户端、驱动或迁移工具;密码通过环境变量或安全凭据输入,不写入命令行、脚本和日志。
- 对可事务化的 DML 使用事务,提交前核对影响行数和关键结果;异常时回滚当前事务并停止后续批次。
- 对不可事务化或可能隐式提交的 DDL,按单个变更执行,记录开始时间、结束时间、执行结果和实际影响。
- 长耗时迁移必须分批、可暂停、可重试;重试前先判断上一次是否已提交,禁止盲目重复执行。
- 关键日志格式至少包含:
taskId、reference、environment、migrationVersion、phase、status、affectedRows、durationMs和fallback。禁止记录敏感凭据和完整业务数据。 - 失败时给出明确兜底提示:停止后续迁移、保留现场日志、确认事务状态、检查锁和备份,再决定重试或执行反向迁移。
6. 验证与交付
- 验证表、字段、索引、约束、字符集和默认值与预期一致。
- 验证迁移记录只出现一次,关键数据行数、唯一性、关联完整性和业务不变量保持正确。
- 对回填抽样检查前后值;对大表使用聚合校验,避免输出敏感原始数据。
- 运行受影响的后端测试、查询测试和必要的 API 只读验证;确认应用日志无迁移相关异常。
- 输出迁移版本、执行环境、实际影响行数、验证结果、是否提交、回滚方式、遗留风险和后续清理事项。
- 若只生成文件而未执行,明确标注“未连接数据库、未执行写操作、待 DBA 审批”。
回滚规范
- 结构变更提供可执行的反向 SQL,或说明只能通过备份恢复、影子表切换或补偿迁移回滚。
- 数据迁移保留原值或生成可定位的补偿条件;不能用猜测值覆盖原数据。
- 回滚前重新确认目标环境、迁移版本、影响范围和备份时间点;回滚后重复执行结构和数据校验。
- 任何删除文件、删除数据、清空表或恢复数据库的操作都必须二次确认,并记录操作日志、备份位置和恢复步骤。
常见风险
- 版本号冲突或执行顺序错误:先扫描所有迁移文件并核对已执行记录。
- 加字段或改类型导致锁表:评估表规模和 MySQL 在线 DDL 能力,必要时拆分窗口或采用影子表方案。
- 回填重复执行:设计幂等条件,例如只处理目标字段为空且满足业务条件的记录。
- 字符集或时区不一致:执行前检查连接、表和列的字符集,以及
@@time_zone。 - 迁移成功但应用失败:优先保持旧代码可兼容,回滚应用版本;不要直接回滚已提交的 DDL,除非已验证反向迁移。