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 评审机制:三个人把关

评审不是走过场。我经历过最惨的一次,就是评审没看出索引冲突,上线后慢查询把库打挂了。

评审机制我建议分三层:

  1. 技术评审——DBA或资深开发看DDL本身。有没有锁表?索引是否冗余?字段类型是否合理?
  2. 业务评审——业务负责人确认变更是否匹配需求。字段名有没有歧义?默认值是否合理?
  3. 成本评审——存储成本专家评估变更对存储的影响。新增字段会增加多少空间?索引会不会膨胀?

举个例子,有一次业务方申请加一个 VARCHAR(1000) 的字段,用来存用户备注。技术评审没问题,业务评审也过了。但成本评审一看——这个表有 2 亿行,每行多 1000 字节,就是 200GB 的额外存储。最后改成 TEXT 并单独拆到扩展表里,成本降了 80%。

注意:评审不是「同意」或「拒绝」二选一。我常用的做法是打标签:「通过」「有条件通过」「打回修改」。有条件通过时,必须列出前置条件,比如「先加索引再改字段」。

4.3 灰度发布:小步快跑

Schema变更最怕的就是「一把梭」。直接全量执行,出了问题连抢救的机会都没有。

灰度发布的思路很简单:先影响一小部分流量,观察没问题再逐步放量。

我常用的灰度策略有三种:

策略 适用场景 操作方式
按分库分表灰度 分片架构 先改一个分片,观察 10 分钟
按读写分离灰度 有从库 先改从库,确认无误再改主库
按流量比例灰度 微服务架构 只让 5% 的流量走新Schema

嗯,这里要注意:灰度不是「改完就等」。你得有监控。我习惯在灰度期间盯着三个指标:

  • 慢查询数量——新Schema可能导致查询计划变化
  • 锁等待时间——DDL 是否阻塞了业务
  • 错误率——应用层是否报字段不存在的异常

我曾经在一个项目里,灰度改从库时一切正常,切到主库后瞬间锁表。为什么?因为主库的写入压力是从库的 10 倍,DDL 执行时间被拖长,导致锁冲突。从那以后,我坚持灰度时必须模拟线上写入压力。

灰度黄金法则:每步灰度后至少观察 5 分钟,确认所有指标平稳再走下一步。别急着「全量」,急容易出事。

4.4 回滚策略:留好退路

回滚不是「改回去就行」。Schema变更的回滚,比代码回滚复杂得多。

我总结了三类回滚方案,按优先级排列:

  1. DDL 反向操作——加字段就删字段,改类型就改回去。但要注意:有些操作不可逆,比如 VARCHAR(100) 改成 VARCHAR(200) 后,数据还在;但反过来截断长度,数据可能丢失。
  2. 表级切换——提前建好新表,变更时双写。出问题直接切回旧表。这是最安全的方案,但成本高。
  3. 备份恢复——从备份拉回变更前的数据。这是最后的手段,耗时最长,数据丢失风险最大。

我个人习惯,每次变更前必须做两件事:

  • 备份被变更的表结构——SHOW CREATE TABLE 存下来
  • 记录变更前的行数——SELECT COUNT(*) 做个快照

为什么?因为有一次我回滚时,发现数据对不上——变更期间有大量写入,回滚后丢了几万条记录。从那以后,我坚持在变更前打快照,回滚时做数据校验。

避坑指南:我曾经遇到一个场景——回滚DDL时,因为表里有 10 亿行数据,反向 ALTER 跑了两个小时。这期间业务完全不可用。后来我改用「在线DDL工具」(如 gh-ost 或 pt-online-schema-change),回滚时只需要切换触发器,秒级完成。

4.5 完整流程:一张图看懂

把上面四个环节串起来,就是一套完整的Schema变更流程。我画了张图,方便你理解:

Schema变更流程 Schema变更完整流程 变更申请 填写DDL + 影响评估 评审机制 技术 + 业务 + 成本 灰度发布 分片/从库/流量比例 回滚 兜底 评审不通过,打回修改 灰度异常,触发回滚 关键节点说明 1. 变更申请:必须包含DDL、影响行数、锁表风险、回滚方案 2. 评审机制:三层评审缺一不可,有条件通过需列出前置条件 3. 灰度发布:每步灰度观察5分钟,监控慢查询、锁等待、错误率 4. 回滚策略:优先DDL反向操作 → 表级切换 → 备份恢复 5. 变更前必须备份表结构 + 记录行数快照

4.6 实战建议:别让流程变成形式

流程定好了,执行才是关键。我见过太多团队,流程文档写得漂亮,但实际执行时「评审秒过」「灰度跳过」「回滚没准备」。结果呢?出一次故障,成本比省下来的时间高一百倍。

给你三个落地建议:

  • 自动化评审检查——把常见问题写成脚本,提交变更时自动跑一遍。比如检查是否用了 ALTER TABLE 直接加索引(会锁表),自动提示改用 pt-osc。
  • 灰度阶段强制卡点——在CI/CD流水线里设置「灰度观察期」,不到时间不准全量。我习惯用 sleep 300 加监控告警,时间不到自动拒绝。
  • 回滚方案必须可执行——每次变更前,把回滚脚本写好、测试通过、放在固定目录。别等到出问题时才现写。

最后一句:Schema变更不是开发的事,也不是DBA的事,是整个团队的事。流程不是束缚,是安全带。系好它,才能开快车。