D1/SQLite schema 迁移安全:没有回滚的世界
背景与问题
Cloudflare D1(SQLite)没有内置的 migration 回滚——改坏了就是改坏了。solo 后端(opc-cron-design-minimum 的 job 表、opc-receipt-validation-minimum 的 entitlement 表)都以 D1 为家,schema 变更的安全步骤要固化。
发现
(来源访问日期均为 2026-09-17)
- 事实(Cloudflare D1 官方文档):D1 无 migration 内置回滚——撤销要手写 down migration;恢复备份是原地覆盖(restore 前要再做一份备份)。
- 事实(同官方):D1 的时点恢复用 Time Travel(取代旧的手动 backup 流程)——恢复到指定时间点的能力是最后的保险。
- 事实(系统设计 newsletter):安全回滚在部署前决定——旧代码、新代码、变更中的 schema 如何共存的计划(expand → migrate data → contract 模式),先加列再迁数据最后删旧列,任何一步可停。
- 事实(自动 checklist 的实践):破坏性操作(无 WHERE 的 DROP/DELETE)在 PR 层机器检查——人靠不住的环节交给工具。
- 事实(实操):
wrangler d1 execute --local先在本地副本验证迁移,再对生产执行。 - 推测:solo 的 schema 事故几乎全部来自「直接改生产 schema」——没有迁移文件、没有演练、没有回滚路径。三样都补齐的成本低于一次事故。
结论
- 迁移纪律四步:①本地副本先跑(--local)②迁移文件命名有序(无 down 时注释写「回滚方法」)③生产执行前 Time Travel 点位确认 ④破坏性操作(DROP/DELETE)一律延后一个版本执行。
- expand/contract 模式成为默认:加列(expand)→双写/迁数据→删旧列(contract),contract 永远单独发版——旧代码在任何时点都能活。
- 恢复演练:Time Travel 的恢复是覆盖式的——半年一次与 opc-backup-restore-drill 同场演练(恢复流程没走过就等于没有)。
- 工具辅助:d1-manager 类可视化工具可选(schema 审查用),但不引入为依赖——wrangler 足够。
待办 / 下次继续
关联
opc-cron-design-minimum opc-receipt-validation-minimum opc-backup-restore-drill opc-edge-api-workers