第一部分:通用数据库迁移流程
除了 MySQL,无论是哪种关系型数据库(如 PostgreSQL, Oracle, SQL Server)或非关系型数据库(如 MongoDB, Redis),如果是要在**不中断核心业务(零停机 / 平滑迁移)**的前提下进行大规模数据迁移,其底层逻辑和通用流程是一致的。
阶段一:环境准备与资源拉起
- 资源评估与创建: 根据源库的容量和水位,评估并创建目标数据库实例。
- 账号与权限配置: 确保迁移工具拥有源库的全局只读/复制权限,以及目标库的读写权限。
- DDL 迁移 (Schema 迁移): 提前将源库的表结构、索引、视图、触发器、存储过程等元数据迁移到目标库。
阶段二:开启实时捕获 (CDC)
- 寻找源库的增量日志起点(如 MySQL 的 Binlog position,PostgreSQL 的 LSN,MongoDB 的 Oplog timestamp)。
- 启动增量日志解析程序,开始记录并缓存从此刻开始发生的所有数据变化,但暂时不向目标库回放。
阶段三:全量数据同步 (Baseline Sync)
- 以截取 CDC 日志那一刻为数据快照点,将全量存量数据导出。
- 使用高并发工具将这批存量数据导入到目标库。
- 注意:此时目标库的数据只到了快照点那一刻,缺乏快照点之后的新增数据。
阶段四:增量数据追平 (Incremental Sync)
- 全量同步完成后,将阶段二中缓存的增量日志拿出来,开始向目标库进行回放 (Replay)。
- 随着回放的进行,目标库的数据会逐渐追赶上源库。
- 当延迟 (Delay/Lag) 降低到秒级甚至 0 时,说明源库和目标库的数据基本处于实时同步状态。
阶段五:数据一致性校验 (Data Validation)
- 在增量同步保持运行的状态下,进行数据两端对比。
- 全量比对: 适合数据量适中,通过 Hash 分块对比两边数据是否完全一致。
- 抽样比对: 适合数据量极大,抽取部分表或部分时间段的数据进行比对。
- 如果发现不一致,需要定位原因并通过工具或手动修复,直到数据完全一致。
阶段六:业务平滑切换 (Cutover)
此时两个库是镜像状态。根据架构特点选择切换方式:
-
停写闪断切换 (Read-Only Cutover - 推荐):
- 将源库设置为只读(或在应用层切断写流量)。
- 等待秒级时间,确保增量队列里的最后几条数据完全写入目标库。
- 将应用的数据库连接配置指向目标库(重启或配置中心动态刷新)。
- 放开写限制,业务恢复。
- 影响:仅在切换瞬间(通常几秒到 1 分钟)业务无法写入。
-
双写灰度切换 (Dual-Write Cutover):
- 修改业务代码,所有的写操作同时落入源库和目标库。
- 读取操作逐步由源库切换到目标库(10% -> 50% -> 100%)。
- 观察确认无误后,停止写入源库,只写目标库。
- 影响:业务完全不中断,但代码改造成本极高,需处理双写失败的回滚和分布式事务等复杂问题。
-
代理层切换 (Proxy Cutover):
- 如果不直接连数据库,而是连了中间件(如 ProxySQL, MyCat),直接在代理层修改路由规则。
- 影响:对业务应用最透明,平滑度最高。
阶段七:收尾与观察
- 保留源数据库和回滚链路(反向同步:将目标库的新增数据同步回源库)一段时间,以防新库出现未知故障需紧急回滚。
- 观察业务各项指标(错误率、慢查询、CPU负载)是否正常。
- 确认无误后,断开回滚链路,下线源数据库。
第二部分:MySQL 实战案例 - 大数据量无缝迁移
针对超大数据量的 MySQL 数据库,要实现线上服务完全不中断(零停机),其落地方案正是利用上述思想:全量物理/逻辑同步 + 增量 Binlog 实时追平 + 动态路由/代理切换。
1. 环境与参数准备
- 开启 Binlog: 必须设定
binlog_format=ROW,并强烈建议开启 GTID (gtid_mode=ON)。 - 自增主键规避: 若计划采用"业务双写"过渡,需调整源库与目标库的自增主键步长(
auto_increment_increment和auto_increment_offset)以避免主键冲突。
2. 全量数据导出与导入
对于大数据量,废弃传统的单线程 mysqldump,改用高效工具:
- Percona XtraBackup: 物理层级热备,速度极快且不阻塞线上读写(强烈推荐)。
- MySQL 8.0 Clone Plugin: 版本满足 8.0.17+ 时原生支持,操作简单。
- MyDumper / MyLoader: 多线程并发逻辑备份。
关键动作: 备份完成时,必须记录下对应的 Binlog 文件名及 Position,或当前的 GTID 集合。
3. 增量数据实时追平
利用全量备份时的位点,将目标库接入源库增量抓取序列,实时回放:
- 原生主从复制: 通过
CHANGE MASTER TO...让目标库成为源库的从库。 - 中间件方案: 使用 Alibaba Canal 或云厂商提供的 DTS (数据传输服务)。
4. 数据一致性校验
当目标库追平增量(Seconds_Behind_Master = 0)时,对新旧库数据进行在线校验:
- 核心工具: Percona Toolkit 中的
pt-table-checksum。 - 优势: 将大表自动分块校验,不影响源库线上性能;若存在差异,可配合
pt-table-sync生成修复 SQL。
5. 零停机平滑切换
通常有两种主流无缝切换策略:
方案 A:Proxy 代理层切换(推荐,业务零感知)
适用于已部署数据库代理(如 ProxySQL、MyCat 或云代理节点)的架构。
- 在代理层预热访问目标库的连接池。
- 更改代理路由规则,一键将流量指向目标库。
- 优势: 业务代码无需任何改动,切换瞬间可能有毫秒级阻塞,但服务不中断。
方案 B:应用层动态切换(无代理时的备选方案)
通过 Nacos、Apollo 等配置中心与应用代码配合。
- 代码准备: 引入新老库双写机制,并结合读写分离配置。
- 灰度切读: 通过配置中心下发指令,将只读查询按比例 (10% -> 50% -> 100%) 切至新库,观察负载。
- 平滑切写: 确认新库稳定后,再次刷新配置,业务停止向老库写入,应用连接池后台重连至新库,完成切换。
MySQL 工具链选型总结
| 环境场景 | 全量同步 | 增量同步 | 数据校验 | 业务切换 |
|---|---|---|---|---|
| 自建机房 | Percona XtraBackup | 原生主从复制 | pt-table-checksum | ProxySQL / 动态数据源 |
| 公有云环境 | 厂商 DTS | 厂商 DTS | DTS 自带数据核对 | 云数据库代理 (自带代理切换) |