4. 数据库迁移异步任务模型:全量迁移与增量迁移
数据库迁移是中间件通信机制中最具挑战的场景之一。迁移过程涉及大量数据、长时间运行、网络波动和一致性保障。本章聚焦于异步任务模型如何支撑全量迁移与增量迁移,以及如何通过任务状态机管理迁移生命周期。
4.1 全量迁移与增量迁移的异步模型
数据库迁移通常分为两个阶段:全量迁移(Snapshot)和增量迁移(CDC Catch-up)。两者在异步任务模型中的处理方式有显著差异。
| 维度 | 全量迁移 | 增量迁移 |
|---|---|---|
| 数据范围 | 全部存量数据 | 迁移期间新增变更 |
| 任务粒度 | 分片(Shard)并行 | 变更事件流(Event Stream) |
| 一致性要求 | 快照一致性 | 最终一致性 + 幂等 |
| 任务时长 | 分钟~小时级 | 持续运行直到追平 |
| 失败恢复 | 断点续传(基于分片偏移) | 基于Binlog位点/序列号重放 |
| 异步模型 | 分片任务队列 + Worker池 | 事件驱动 + 状态机 |
关键设计原则:全量迁移追求吞吐,增量迁移追求低延迟和有序性。两者通过“切换点”衔接,切换点必须保证全量快照之后的所有变更不丢失。
4.2 异步任务的生命周期管理
每个迁移任务从创建到完成经历多个阶段。生命周期管理需要处理任务调度、执行、重试、暂停、取消和清理。
4.2.1 任务生命周期阶段
- 创建(Created):任务元数据写入数据库,分配唯一ID,设置初始参数。
- 调度(Scheduled):任务进入调度队列,等待Worker消费。
- 运行(Running):Worker获取任务,开始执行迁移逻辑。
- 暂停(Paused):手动或自动暂停,保存当前进度。
- 失败(Failed):执行异常,触发重试策略或人工介入。
- 完成(Completed):迁移成功,清理临时资源。
- 取消(Cancelled):用户主动终止,回滚已迁移数据(可选)。
实践建议:生命周期中的“暂停”状态是异步任务的关键能力。在数据库迁移中,暂停允许运维人员观察迁移进度、调整限流参数或修复源端问题,而无需重新开始。
4.2.2 生命周期管理组件
| 组件 | 职责 | 技术选型参考 |
|---|---|---|
| 任务调度器 | 从DB拉取待调度任务,分发到Worker | Redis Stream / Kafka + 定时轮询 |
| Worker池 | 执行任务逻辑,上报心跳和进度 | 线程池 + 协程 + 状态上报 |
| 状态存储 | 持久化任务状态、进度、错误信息 | MySQL / PostgreSQL + 乐观锁 |
| 监控告警 | 检测任务超时、失败、卡死 | Prometheus + AlertManager |
| 管理API | 暂停、恢复、取消、重试任务 | REST / gRPC + 幂等设计 |
4.3 任务状态机设计
任务状态机是异步任务模型的核心。它定义了任务在生命周期中允许的状态转换路径,防止非法操作(如从“完成”状态直接跳转到“运行”)。
4.3.1 状态转换图
4.3.2 状态转换规则
- 正向路径:Created → Scheduled → Running → Completed
- 暂停/恢复:Running ↔ Paused(可多次循环)
- 失败处理:Running → Failed → Running(重试,需记录重试次数)
- 终止路径:Running/Paused → Cancelled(用户主动取消)
- 终态:Completed 和 Cancelled 为终态,不可再转换
常见陷阱:状态转换必须使用乐观锁或分布式锁防止并发更新。例如,两个Worker同时将任务从Running更新为Completed和Failed,会导致状态不一致。建议使用CAS(Compare-And-Swap)或版本号机制。
4.4 全量迁移与增量迁移的异步任务实现
4.4.1 全量迁移任务模型
全量迁移采用“分片-并行”模型。源表按主键范围或哈希值拆分为多个分片,每个分片对应一个独立的任务。
// 全量迁移分片任务定义
{
"taskId": "full_001_shard_05",
"type": "FULL_SYNC",
"source": {
"table": "orders",
"shardKey": "id",
"rangeStart": 100000,
"rangeEnd": 200000
},
"target": {
"table": "orders_new",
"batchSize": 5000
},
"state": "RUNNING",
"progress": {
"processedRows": 45000,
"totalRows": 100000,
"lastProcessedKey": 145000
},
"retryCount": 0,
"maxRetries": 3
}
4.4.2 增量迁移任务模型
增量迁移基于CDC(Change Data Capture)事件流。任务持续监听源库的Binlog/Redo Log,将变更事件异步应用到目标库。
// 增量迁移任务定义
{
"taskId": "inc_001",
"type": "INCREMENTAL_SYNC",
"source": {
"binlogFile": "mysql-bin.000123",
"binlogPosition": 456789,
"serverId": 1
},
"target": {
"applyMode": "UPSERT",
"conflictStrategy": "IGNORE"
},
"state": "RUNNING",
"metrics": {
"eventsProcessed": 1024000,
"lagSeconds": 2.5,
"lastEventTimestamp": "2025-03-21T10:30:00Z"
},
"checkpoint": {
"currentBinlogFile": "mysql-bin.000125",
"currentPosition": 123456
}
}
4.5 任务状态机在迁移中的实际应用
在数据库迁移场景中,状态机需要处理以下特殊场景:
- 全量迁移完成 → 自动启动增量迁移:全量任务进入Completed后,调度器自动创建增量迁移任务。
- 增量迁移追平 → 切换验证:增量任务lag接近0时,进入“验证中”子状态,确认数据一致性后执行切换。
- 切换失败 → 回滚:切换任务失败,状态回退到“增量迁移中”,保留源库写入能力。
- 限流暂停:当目标库负载过高时,自动暂停增量迁移,待负载下降后恢复。
最佳实践:将状态机与任务调度器解耦。状态机只负责状态转换逻辑,调度器负责任务分发和Worker管理。两者通过消息队列通信,避免直接依赖。
4.6 本章小结
- 全量迁移和增量迁移在任务粒度、一致性要求和恢复策略上有本质区别,需要不同的异步模型。
- 任务生命周期管理包括创建、调度、运行、暂停、失败、完成和取消七个阶段,每个阶段都有明确的职责。
- 任务状态机通过严格的状态转换规则,防止非法操作,确保迁移过程的正确性和可恢复性。
- 实际迁移中,状态机需要支持全量→增量的自动衔接、切换验证和回滚等复杂场景。