10 · 数据迁移与双写
换库/加字段/分表最怕的不是迁移本身,而是迁移后才发现两边对不上。本篇讲平滑迁移的套路:评估、全量+增量、双写、校验、切换与回滚,让"上线"变成"可验证、可回退"。
速览卡
| 项 | 内容 |
|---|---|
| 一句话定位 | 数据库迁移的操作指南:从评估到切换,每一步都有校验与回滚 |
| 核心内容 | 全量/增量/双写/校验/灰度切换/回滚,一套可复用的迁移流程 |
| 读完能回答 | 迁移期间新旧库不一致怎么办?怎么证明迁移成功? |
| 相关板块 | DB03 事务 | DB08 分库分表 | C04 一致性与事务 |
一、迁移前的三件事
| 事项 | 内容 |
|---|---|
| 评估 | 数据量、字段映射、停机窗口、回滚方案 |
| 迁移脚本可重放 | 幂等:重复跑结果一致 |
| 先定验收标准 | "什么算成功"要预先定义,不是上线后拍脑袋 |
验收标准示例:抽样 N 条对比一致率 100%、特定边界字段正确、双写期间新增数据无丢失。
二、平滑迁移的六步流程
text
① 全量迁移 历史数据一次性搬过去
② 增量同步 迁移期间的新写入实时同步
③ 双写 新旧两套都写,校验后以新为准
④ 校验 对比两边数据,修差异
⑤ 灰度切换 逐步把读/写切到新库
⑥ 观察 + 回滚窗口 出问题立即回退三、全量迁移:先搬家
sql
-- 迁移方向:旧表 → 新表(可写一段脚本做字段映射/清洗)
INSERT INTO new_table (id, name, created_at)
SELECT id, name, created_at FROM old_table;要点:
- 大表分批插入(
LIMIT+ 游标),避免一次锁太久 - 跑之前先停写或接受"迁移期间增量差异"
- 迁移完成立刻对比数量(行数、校验和)
四、增量同步:让差异可控
全量搬完的那一刻,新库就落后了——期间的写入需要增量补。
| 方案 | 机制 |
|---|---|
| binlog 订阅 | 监听旧库变更,同步到新库(最通用) |
| 时间戳增量 | 按 updated_at > 上次位置 轮询拉取 |
| 应用双写 | 写旧库同时写新库(见下) |
五、双写:新旧都写,校验为准
text
写请求 → 写旧库 + 写新库
↓
(新库写失败?记日志,不阻塞主流程)
读请求 → 仍读旧库,直到切换| 好处 | 代价 |
|---|---|
| 新库数据持续最新 | 双写失败要补偿 |
| 切换前就有真实数据 | 应用代码要改两处 |
判断框架:迁移窗口内写流量大 → 双写让新库"热身";写流量小 → 先全量再增量,可能不需要双写。
六、校验:证明迁移成功
| 校验层 | 做法 |
|---|---|
| 行数 | 两表 COUNT 一致 |
| 抽样 | 按 id 抽样对比关键字段 |
| 全量哈希 | 按行算哈希聚合后对比 |
| 边界字段 | 时间、金额、NULL、超长字段 |
| 业务探针 | 跑几条真实业务查询对比结果 |
校验不能只对一次:双写期间要周期校验,发现漂移就修复后继续。
七、灰度切换与回滚
| 步骤 | 动作 |
|---|---|
| 读灰度 | 小比例流量读新库,观察错误/延迟 |
| 写灰度 | 小比例流量写新库 |
| 全量切换 | 确认稳定后全部切走 |
| 回滚窗口 | 保留旧库一段时间(按业务定,如 1~2 周),必要时切回 |
回滚不是"一键搞定":旧库可能没有新写入,要设计"新→旧"的反向同步或接受数据回退。
八、自检清单
- [ ] 迁移前先定验收标准与回滚方案
- [ ] 全量迁移分批执行、跑完立刻对比数量
- [ ] 迁移窗口的增量用 binlog/时间戳/双写补上
- [ ] 双写期间周期校验,不只看一次
- [ ] 灰度切换分读/写两阶段
- [ ] 保留回滚窗口,且有数据回退预案
九、常见误区
| 误区 | 事实 |
|---|---|
| "迁移一次就完" | 增量、校验、灰度都要跟上 |
| "两边数量对得上就行" | 要校验内容与边界字段 |
| "双写失败不影响" | 要记录补偿,否则新库缺数据 |
| "切换完就能删旧库" | 保留回滚窗口,出问题能退 |
| "回滚是无损的" | 新库写入旧库没有时,要接受回退或反向同步 |
| "迁移脚本跑一遍就好" | 要幂等可重放 |
十、动手练习
练习 A:写迁移验收标准
给"用户表从 MySQL 迁到 Postgres"写一份验收清单(数量、抽样、边界、业务探针各两条)。
练习 B:设计双写补偿
双写时新库偶发失败,你怎么保证最终一致?画出"失败 → 重试 → 对账"的链路。
练习 C:模拟灰度
流量按 1% → 10% → 50% → 100% 切读,每阶段看什么指标才放行下一阶段?
相关文档
本区
- 03 · 事务与隔离级别 —— 迁移期间的写入一致性
- 08 · 分库分表与读写分离 —— 分表迁移的特殊性
其他域
- 04 · 一致性与事务边界 —— 双写与最终一致
- 17 · 部署与 CI/CD —— 数据库迁移在发布流程里的位置