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 状态转换图

数据库迁移任务状态机 数据库迁移任务状态机 Created Scheduled Running Paused Failed Completed Cancelled 调度 Worker领取 暂停 恢复 异常 重试 成功 取消 取消 状态转换规则 禁止从Completed/Cancelled 转换到其他状态

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 任务状态机在迁移中的实际应用

在数据库迁移场景中,状态机需要处理以下特殊场景:

  1. 全量迁移完成 → 自动启动增量迁移:全量任务进入Completed后,调度器自动创建增量迁移任务。
  2. 增量迁移追平 → 切换验证:增量任务lag接近0时,进入“验证中”子状态,确认数据一致性后执行切换。
  3. 切换失败 → 回滚:切换任务失败,状态回退到“增量迁移中”,保留源库写入能力。
  4. 限流暂停:当目标库负载过高时,自动暂停增量迁移,待负载下降后恢复。
最佳实践:将状态机与任务调度器解耦。状态机只负责状态转换逻辑,调度器负责任务分发和Worker管理。两者通过消息队列通信,避免直接依赖。

4.6 本章小结

  • 全量迁移和增量迁移在任务粒度、一致性要求和恢复策略上有本质区别,需要不同的异步模型。
  • 任务生命周期管理包括创建、调度、运行、暂停、失败、完成和取消七个阶段,每个阶段都有明确的职责。
  • 任务状态机通过严格的状态转换规则,防止非法操作,确保迁移过程的正确性和可恢复性。
  • 实际迁移中,状态机需要支持全量→增量的自动衔接、切换验证和回滚等复杂场景。