关于 review-migration
review-migration 是用于评估数据库结构迁移在真实环境中安全性的技能,重点关注分阶段变更、锁与表重写风险、部署兼容性及回滚或前向修复方案。
主要功能
- 01识别数据库与表规模风险
- 02分离结构变更和数据回填
- 03评估锁与表重写风险
- 04规划部署顺序与兼容性
- 05规划回滚或前向修复
- 06为高风险变更制定分阶段方案
适用场景
- 01部署前审查迁移
- 02规划大表结构变更
- 03安全移除或重命名列
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ igmarin/ rails-agent-skills --skill review-migration安装后在 Claude Code 中输入/review-migration确认已加载。
附带文件PATTERNS.md
详细介绍
迁移审查
当 schema 变更必须在真实环境中保证安全时,使用此技能。
硬性门槛
DO NOT combine schema change and data backfill in one migration.
DO NOT add NOT NULL on a column that hasn't been fully backfilled.
DO NOT drop columns before all code references are removed.
核心流程
- 识别数据库和表规模风险。
- 将 schema 变更与数据回填分开。
- 检查索引、约束、默认值和重写的锁行为。
- 规划应用代码与迁移代码之间的部署顺序。
- 规划回滚或前向修复策略。
如果项目使用 strong_migrations,请遵循它。如果没有使用,请手动应用相同的安全规则。
安全模式与常见错误
| 操作 | 安全模式 | 常见错误 | 失败原因 |
|---|---|---|---|
| 添加列 | 先可空,稍后回填,最后强制 NOT NULL | 在大表上执行 add_column :t, :col, :string, null: false, default: "x" | 表重写 + 锁(PG < 11) |
| 添加索引(大表) | algorithm: :concurrently(PG)/ :inplace(MySQL)+ disable_ddl_transaction! | 不带 algorithm: :concurrently 执行 add_index :users, :email | 共享锁阻塞写入 |
| 回填数据 | 在迁移事务之外运行批处理作业,节流以减少复制延迟 | 在迁移中执行 User.update_all(...) | 事务锁在整个持续期间被持有 |
| 重命名列 | 添加新列,复制数据,迁移调用方,删除旧列 | 直接重命名列 | 在部署期间破坏正在运行的应用 |
| 添加 NOT NULL | 回填确认所有行都有值之后 | 在回填完成之前强制 NOT NULL | 在缺少值的行上失败或加锁 |
| 添加外键 | 清理孤立记录之后 | 未清理孤立记录就添加外键 | 迁移时违反约束 |
| 删除列 | 先移除代码引用,部署,然后删除列 | 在代码仍读取该列时删除列 | 运行时出现 unknown attribute 错误 |
对于每一步,明确说明预期的锁或表重写风险;如果可忽略,请说明原因。
在过渡期间部署能同时容忍旧 schema 和新 schema 的代码。
代码示例
并发索引(Rails / PostgreSQL):
class AddIndexOnUsersEmail < ActiveRecord::Migration[7.1]
disable_ddl_transaction!
def change
add_index :users, :email, algorithm: :concurrently
end
end
disable_ddl_transaction!是必需的 — 并发索引创建无法在事务内运行。
可空优先列与延迟 NOT NULL(Rails):
# Step 1 — Deploy: add nullable column
class AddConfirmedAtToUsers < ActiveRecord::Migration[7.1]
def change
add_column :users, :confirmed_at, :datetime
end
end
# Step 2 — Backfill outside migration (background job or script)
User.in_batches(of: 1_000) do |batch|
batch.update_all(confirmed_at: Time.current)
sleep(0.05) # throttle to reduce replication lag
end
# Step 3 — Deploy: enforce NOT NULL only after all rows are filled
class ChangeConfirmedAtNotNull < ActiveRecord::Migration[7.1]
def change
change_column_null :users, :confirmed_at, false
end
end
类型变更发布(5 步):
- 将新的类型化列添加为可空。
- 从应用代码同时写入旧列和新列。
- 在迁移事务之外分批回填。
- 在一致性检查通过后从新列读取。
- 停止写入旧列,然后在后续部署中删除它。
输出风格
- 先列出风险。
- 对于每个风险,包括:迁移步骤、可能的失败模式、明确的锁/表重写风险、更安全的发布方式、回滚或前向修复说明。
- 确保包含向后兼容步骤。
- 对于列重命名、类型变更和唯一约束,始终包含明确的分阶段模式。如果不适用,请标记为
Not applicable并解释原因。 - 语言 — 除非明确要求,否则必须使用英语。
集成
| 技能 | 何时串联 |
|---|---|
| code-review | 在审查包含迁移的 PR 时 |
| implement-background-job | 对于 schema 变更后运行的回填作业 |
| security-check | 当迁移暴露或移动敏感数据时 |
评论
支持 Markdown