mcpField
D
db-migration-safety

db-migration-safety

github.com/hainrixz数据与数据库2170 次安装4 天前更新
代码仓库

关于 db-migration-safety

db-migration-safety 是在迁移执行前检查 SQL 或 ORM 迁移文件的静态审查技能,供迁移审计器和编写 Agent 使用。它关注回滚能力、锁、表重写、破坏性操作及模式漂移,只提出修复建议,不执行迁移。

主要功能

  1. 01检查回滚方案与扩展-收缩流程
  2. 02识别阻塞锁和全表重写风险
  3. 03标记破坏性操作与非空约束问题
  4. 04检查枚举变更和模式漂移
  5. 05提供安全改写及验证方法

适用场景

  1. 01执行前审查数据库迁移文件
  2. 02发现可能阻塞热表的 SQL
  3. 03为非空字段变更规划数据回填
  4. 04检查迁移历史与模式定义是否一致

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hainrixz/claude-db --skill db-migration-safety

安装后在 Claude Code 中输入/db-migration-safety确认已加载。

详细介绍

db-migration-safety (M22) — 迁移 lint 契约

M22 会在执行候选迁移前,将其作为静态产物进行 lint。migration-safety auditor 和 db-migration-writer Agent 都遵循此契约。为 Performance & Scale(Almacenamiento/operability 类别)提供数据。具有破坏性且不可逆的迁移,在性能轴上的严重程度上限为 sev-5。

检查内容(lint 契约)

  1. 可逆性 — 存在可用的 down/回滚,或变更遵循 expand-contract(在不同部署中依次执行 add-new → backfill → switch → drop-old)。没有 down 的一次性破坏性步骤,是此处严重程度最高的问题。
  2. 锁级别 — 语句是否会对热点表加阻塞锁?在 Postgres 中:添加带有易变默认值的列(11 之前)、ALTER COLUMN TYPE、添加不带 NOT VALID 的 CHECK/FK、创建非 CONCURRENTLY 索引,都会获取 ACCESS EXCLUSIVE 锁/阻塞写入。优先使用 CREATE INDEX CONCURRENTLY、ADD CONSTRAINT ... NOT VALID,然后执行 VALIDATE CONSTRAINT。
  3. 表重写 — 导致整张表重写的变更(某些 ALTER COLUMN TYPE、旧版本引擎上添加带易变默认值的 NOT NULL 列)→ 在大表上耗时且长时间持锁。
  4. 破坏性操作 — DROP COLUMN、DROP TABLE、TRUNCATE、撤销 DROP NOT NULL、删除仍被已部署代码读取的列。破坏性操作且不可逆 = sev 5(性能严重程度上限)。
  5. 添加到已有数据表的 NOT NULL 列没有默认值 → 会失败或加锁;必须提供回填计划。
  6. 枚举变更 — 长期需要关注的问题:枚举值无法移除或重新排序(不支持移除;重命名/重新排序会破坏依赖项),因此,取值会变化的集合应使用查找表,而不是原生枚举。ALTER TYPE ... ADD VALUE 只能追加,并且在 PG12+ 中可在事务内执行(只有更早版本的 PG 禁止在事务中执行)。标记枚举变更;建议使用查找表。
  7. 架构漂移 — 声明式产物(schema.prisma / structure.sql / snapshot)与迁移历史不一致(某列只存在于其中一方)→ 发出方向性警告。

Tier-0 静态检查

解析迁移 SQL/ORM 迁移文件(scripts/parse-schema.mjs、parse-orm-python.py)。扫描以下内容: DROP TABLE|DROP COLUMN|TRUNCATE;ALTER COLUMN .* TYPE;不带 DEFAULT 的 ADD COLUMN .* NOT NULL;缺少 CONCURRENTLY 的 CREATE INDEX;缺少 NOT VALID 的 ADD CONSTRAINT(FK/CHECK);ALTER TYPE .* ADD VALUE/枚举值移除或重新排序;缺少 down/回滚代码块;权威产物(references/detection-signals.md 中的优先级)与最新迁移之间的漂移。

Tier-1 验证查询

  • 受影响表的大小(锁是否会造成影响?):SELECT pg_size_pretty(pg_total_relation_size('<t>')), reltuples FROM pg_class WHERE relname='<t>';
  • 语句将获取的锁:检查 EXPLAIN/pg_locks,或针对一次性副本/影子 DB 执行 dry_run_migration。影子 DB 可用时,使用 verification.method: dry_run_migration;否则对静态 SQL 执行 migration_lint。若需要实时数据大小来判断严重程度,但无法连接数据库 → 标记为 needs_api,绝不能静默通过。

检查结果

按 schema/finding.schema.json 输出。示例 ID:

  • M22.20240115_drop_users_legacy.destructive_irreversible — 执行 DROP COLUMN,没有 down 且列仍被引用(失败,严重级别 5,轴 performance,可修复性 proposed → 扩展-收缩方案)。
  • M22.add_index.lock_blocking — 在高频使用的表上执行 CREATE INDEX,但未使用 CONCURRENTLY(警告,严重级别 4,轴 performance,可修复性 auto → 添加 CONCURRENTLY)。
  • M22.add_email_notnull.notnull_no_default — 在已有数据的表上执行 ADD COLUMN ... NOT NULL,但没有默认值(失败,严重级别 4,轴 performance,可修复性 proposed)。
  • M22.status_enum.enum_value_removed — 枚举值被删除或重新排序(不支持;会破坏依赖项)— 建议改用查找表(警告,严重级别 3,轴 performance)。
  • M22.drift.column_in_artifact_not_migration — 架构漂移(警告,严重级别 2,轴 performance,置信度 directional)。 每项检查结果:evidence.observed 引用违规迁移语句的原文(已 redact 密钥);verification.reproduce 是上文中使用 $DATABASE_URL 的可运行命令;verification.method 为 migration_lint 或 dry_run_migration;fix_preview 包含更安全的改写(例如 CONCURRENTLY、NOT VALID + VALIDATE、扩展-收缩序列);expected_impact 包含 {axis, confidence, magnitude, rationale} — 采用分档表示,绝不使用单一百分比。

诚实原则

  • 锁的严重程度取决于表大小和写入速率 — 没有实时证据时,对于大小未知的表,阻塞操作的严重程度为 directional(中等),而不是已确认的严重级别 5。不要声称停机时长精确到秒;只能使用分档表示影响程度。
  • 只有 DROP/TRUNCATE 类破坏性且不可逆的迁移,才会将性能严重级别设为 5。可逆或扩展-收缩变更属于警告。漂移仅为方向性,绝不会将严重级别设为上限。
  • 只读:M22 只执行检查并提出建议,绝不执行迁移。迁移由写入 Agent 负责,且须经用户明确接受。

评论

支持 Markdown