db-migrations 是 paradev 仓库中的一项技能,用于在修改 packages/db 下的数据库 schema 时,借助 Drizzle 生成数据库迁移,并验证该迁移能否在生产负载下安全运行。
用途与背景 该技能面向数据库迁移的生成与安全审查。文档指出,在空闲数据库上正确的迁移仍可能拖垮生产:曾有迁移在持有多张认证表 ACCESS EXCLUSIVE 锁的情况下重写大表,导致 API 宕机。因此流程要求先生成迁移,再通过安全清单后才可提交 PR。
生成方式 流程为:新建 Neon 分支并将根目录 .env 指向该分支;在 packages/db/src/schema/ 中修改 schema;在 packages/db 下执行 bunx drizzle-kit generate --name="<sample_name_snake_case>" 生成迁移;仅在开发分支上应用,不得对共享或生产数据库应用。除非用户明确确认(唯一正当理由是语句顺序),不得手工编辑 packages/db/drizzle/ 下的 .sql 文件、meta/_journal.json 和快照。
安全清单 清单包括:检查迁移涉及每张表的生产大小;不在大表或繁忙表上变更列类型;锁按先子表后父表的顺序获取;避免在热点表上长时间持有 ACCESS EXCLUSIVE;每条语句在生产规模下远低于 60 秒;当迁移锁定热点表或重写/扫描大表时,需在生产分支上带负载预演;读取位置迁移时同版本内完成数据迁移;同一 PR 不夹杂 tRPC 输入输出变更;修改已推送迁移后删除 PR 的预览 Neon 分支。
规则要点
- 所有待执行迁移在一个事务中运行,分散到多个文件不会带来锁隔离。
- 不在大而繁忙的表上做非二进制兼容的列类型变更,枚举可用 ALTER TYPE ... ADD VALUE,否则新增列、分批回填、后续版本切换。
- 锁顺序按应用访问顺序:先子表再父表,避免与在途插入死锁;drizzle-kit 决定语句顺序,手工调整需用户确认并在 SQL 注释说明原因。
- 明确热点表(auth.users、auth.organizations、automation_events、ingest.webhook_events)及需等待相关作业 advisory lock 的情形。
- 读取位置变更需在同版本内完成数据回填,CI 单元测试因 mock 查找层无法发现该问题。
预演与部署 预演针对生产子 Neon 分支,用 pgbench 编写读父表、写子表的脚本并并发运行,同时以 PGOPTIONS="-c lock_timeout=5s -c statement_timeout=60s" bun drizzle-kit migrate 应用迁移,多次重复验证。生产部署使用并发组、锁与语句超时、最多 8 次仅针对死锁或锁超时的重试,并用 verify-migrations-applied.ts 校验。复用预览分支会导致检查空转,需删除分支以强制真实运行。
适用与限制 适用于采用 Drizzle、Neon 分支与生产部署流程的数据库迁移场景;未提供独立产品定价、平台支持范围等信息。