Safe Schema Migrations 的目标是在不停机、不长时间锁住热表、不产生不可逆步骤的前提下变更数据库结构。它把迁移和代码部署视为需要协调的多个步骤,而不是一次大切换。资料建议与 financial-invariants 配合以保证数据正确性,并与 scale-readiness-review 配合评估规模影响。
用途与适用场景:用于新增、删除、重命名列,添加或修改约束、类型、索引,以及进行数据回填等结构变更。
工作流程:
- 对变更分类:加性变更(可空列、新表/索引)风险最低;回填的风险在于运行时长与锁持续时间;约束/类型变更(NOT NULL、外键、加宽/收窄)的风险在于表锁与重写;重命名/移动不应在运行中的应用下原地进行,而应使用 expand/contract;破坏性变更(删除)只有在完整一个发布周期内没有任何代码引用它之后才可执行。
- Expand / contract:每个阶段独立发布且可回滚,步骤之间应用不会中断。包括扩展(加入新结构但不删旧结构)、迁移代码(双写、读旧,或在新结构后面用开关控制读新)、回填(分批填充已有行)、切换读取(读新,短暂保留双写)、收缩(停止写旧、添加约束、最后删除旧结构)。
- 保持 DDL 在线:在支持的情况下并发/在线创建索引;NOT NULL 通过受检约束并单独验证,或先设默认值再强制;外键先用 NOT VALID,再单独 VALIDATE;保持 DDL 事务简短,绝不在繁重工作期间持有锁。
- 安全回填:按 id/日期有序、有界分批,批次之间短暂休眠;可续跑且幂等;作为任务/脚本运行,绝不放在结构迁移事务里;监控锁竞争、复制延迟、批次时长,若增长则限流。
- 回滚计划:每个步骤都有下行路径或记录在案的前向修复;破坏性步骤放在更晚的独立迁移中,这样回滚最新部署不会丢失数据。
- 验证:在生产规模的行数上测试,测量锁时间与时长;在每个阶段对迁移后的结构运行测试套件;若存在下行路径则先下行再上行;财务表在回填前后核对行数与关键汇总。
防护准则:绝不在停止使用某列的同一个部署中重命名或删除它;绝不在一个事务中回填大表;绝不添加会对热表全表加锁的 NOT NULL 或验证型外键;绝不在运行中的代码引用旧结构时执行破坏性 DDL。