4. Schema变更流程:变更申请、评审机制、灰度发布、回滚策略
Schema变更,说白了就是给数据库表动手术。改个字段类型、加个索引、拆个大表——这些操作看着简单,但线上出过多少故障?我见过太多团队,一个 ALTER TABLE 下去,整个库锁住,业务停了半小时。
所以,一套靠谱的变更流程,不是用来卡人的,是用来保命的。今天我把这套流程拆成四个环节,挨个讲透。
核心原则:任何Schema变更,都必须经过「申请→评审→灰度→回滚」四个阶段。跳过任何一步,都是在赌运气。
4.1 变更申请:把话说清楚
变更申请不是填个表单就完事。你得让评审的人一眼看懂:改了什么、为什么改、影响多大。
我个人习惯,申请单里必须包含这几项:
| 字段 | 说明 | 示例 |
|---|---|---|
| 变更目标表 | 数据库名.表名 | prod.user_order |
| 变更DDL | 完整的SQL语句 | ALTER TABLE ... ADD COLUMN ... |
| 变更原因 | 业务需求或技术优化 | 支持新支付渠道,需增加 channel_id |
| 预估影响行数 | 变更涉及的数据量 | 约 500 万行 |
| 锁表风险 | 是否阻塞读写 | MySQL 5.7 直接 ALTER 会锁表 |
| 回滚方案 | 如何撤销变更 | 执行反向DDL或切回旧表 |
小技巧:我建议把DDL提前在测试环境跑一遍,用 EXPLAIN 和 SHOW PROCESSLIST 确认执行计划。别等到线上才发现语句走了全表扫描。
4.2 评审机制:三个人把关
评审不是走过场。我经历过最惨的一次,就是评审没看出索引冲突,上线后慢查询把库打挂了。
评审机制我建议分三层:
- 技术评审——DBA或资深开发看DDL本身。有没有锁表?索引是否冗余?字段类型是否合理?
- 业务评审——业务负责人确认变更是否匹配需求。字段名有没有歧义?默认值是否合理?
- 成本评审——存储成本专家评估变更对存储的影响。新增字段会增加多少空间?索引会不会膨胀?
举个例子,有一次业务方申请加一个 VARCHAR(1000) 的字段,用来存用户备注。技术评审没问题,业务评审也过了。但成本评审一看——这个表有 2 亿行,每行多 1000 字节,就是 200GB 的额外存储。最后改成 TEXT 并单独拆到扩展表里,成本降了 80%。
注意:评审不是「同意」或「拒绝」二选一。我常用的做法是打标签:「通过」「有条件通过」「打回修改」。有条件通过时,必须列出前置条件,比如「先加索引再改字段」。
4.3 灰度发布:小步快跑
Schema变更最怕的就是「一把梭」。直接全量执行,出了问题连抢救的机会都没有。
灰度发布的思路很简单:先影响一小部分流量,观察没问题再逐步放量。
我常用的灰度策略有三种:
| 策略 | 适用场景 | 操作方式 |
|---|---|---|
| 按分库分表灰度 | 分片架构 | 先改一个分片,观察 10 分钟 |
| 按读写分离灰度 | 有从库 | 先改从库,确认无误再改主库 |
| 按流量比例灰度 | 微服务架构 | 只让 5% 的流量走新Schema |
嗯,这里要注意:灰度不是「改完就等」。你得有监控。我习惯在灰度期间盯着三个指标:
- 慢查询数量——新Schema可能导致查询计划变化
- 锁等待时间——DDL 是否阻塞了业务
- 错误率——应用层是否报字段不存在的异常
我曾经在一个项目里,灰度改从库时一切正常,切到主库后瞬间锁表。为什么?因为主库的写入压力是从库的 10 倍,DDL 执行时间被拖长,导致锁冲突。从那以后,我坚持灰度时必须模拟线上写入压力。
灰度黄金法则:每步灰度后至少观察 5 分钟,确认所有指标平稳再走下一步。别急着「全量」,急容易出事。
4.4 回滚策略:留好退路
回滚不是「改回去就行」。Schema变更的回滚,比代码回滚复杂得多。
我总结了三类回滚方案,按优先级排列:
- DDL 反向操作——加字段就删字段,改类型就改回去。但要注意:有些操作不可逆,比如
VARCHAR(100)改成VARCHAR(200)后,数据还在;但反过来截断长度,数据可能丢失。 - 表级切换——提前建好新表,变更时双写。出问题直接切回旧表。这是最安全的方案,但成本高。
- 备份恢复——从备份拉回变更前的数据。这是最后的手段,耗时最长,数据丢失风险最大。
我个人习惯,每次变更前必须做两件事:
- 备份被变更的表结构——
SHOW CREATE TABLE存下来 - 记录变更前的行数——
SELECT COUNT(*)做个快照
为什么?因为有一次我回滚时,发现数据对不上——变更期间有大量写入,回滚后丢了几万条记录。从那以后,我坚持在变更前打快照,回滚时做数据校验。
避坑指南:我曾经遇到一个场景——回滚DDL时,因为表里有 10 亿行数据,反向 ALTER 跑了两个小时。这期间业务完全不可用。后来我改用「在线DDL工具」(如 gh-ost 或 pt-online-schema-change),回滚时只需要切换触发器,秒级完成。
4.5 完整流程:一张图看懂
把上面四个环节串起来,就是一套完整的Schema变更流程。我画了张图,方便你理解:
4.6 实战建议:别让流程变成形式
流程定好了,执行才是关键。我见过太多团队,流程文档写得漂亮,但实际执行时「评审秒过」「灰度跳过」「回滚没准备」。结果呢?出一次故障,成本比省下来的时间高一百倍。
给你三个落地建议:
- 自动化评审检查——把常见问题写成脚本,提交变更时自动跑一遍。比如检查是否用了
ALTER TABLE直接加索引(会锁表),自动提示改用pt-osc。 - 灰度阶段强制卡点——在CI/CD流水线里设置「灰度观察期」,不到时间不准全量。我习惯用
sleep 300加监控告警,时间不到自动拒绝。 - 回滚方案必须可执行——每次变更前,把回滚脚本写好、测试通过、放在固定目录。别等到出问题时才现写。
最后一句:Schema变更不是开发的事,也不是DBA的事,是整个团队的事。流程不是束缚,是安全带。系好它,才能开快车。