1538万行大表迁移实战,从SQLServer到MySQL的断点续传工具设计

在跨境电商 ERP 系统从 V2 升级到 V3 的过程中,作者面临将包含 1538 万行数据的 Product_AreaPrice_Detail 表从 SQL Server 迁移到 MySQL 的挑战...

互联网/IT

在最近的一次系统升级中,我们团队负责将一套跨境电商 ERP(AEERP)从 .NET Framework 4.x 升级到 .NET 8。虽然框架层的迁移通过单元测试验证后进展顺利,但两张超大表的迁移却成为项目中的最大难点。

这两张表分别是 Product_Freight_Detail(520 万行)和 Product_AreaPrice_Detail(1538 万行),合计超过两千多万行数据。要把这些数据从 SQL Server 完整无误地迁移到 MySQL,不仅需要处理长时间运行可能遇到的断线、内存溢出等问题,还要应对业务实时写入数据的干扰。经过多次尝试现有工具失败后,我们决定自主研发一个控制台程序 BigDBMigrator 来解决这个问题。

为什么选择自己开发?

在开始编写之前,我们尝试了多种现成的迁移工具,但都存在明显缺陷。图形化工具无法支持断点续传,一旦中途失败就必须重新开始;数据库自带的导入导出功能效率低下,对复杂数据类型处理不够透明;而先导出中间文件再导入的方式则需要消耗大量磁盘空间和 IO 资源。

为了直观展示不同方案的耗时差异,我们记录了以下几种方法的实际运行时间:

  • 压缩备份数据库并跨公网下载耗时超过 1 小时
  • 使用 SQL Server 临时表复制数据耗时约 30 分钟
  • 使用 SSIS 包迁移 39.5 万行数据耗时超过 20 分钟



如果按照 SSIS 包的迁移速率估算,迁移 1538 万行数据将需要约 13 个小时。更重要的是,这些工具都无法提供断点续传和实时进度监控功能,这意味着任何一次中断都需要从头开始,极大地增加了迁移风险。

基于以上考虑,我们决定自行开发一个迁移工具,核心需求包括:支持断点续传、提供实时迁移进度和速率显示、确保迁移过程幂等安全(重复执行不会产生副作用)。

关键设计决策

文章配图

BigDBMigrator 的技术栈选择了 .NET 8 控制台应用,使用 Microsoft.Data.SqlClient 读取 SQL Server 数据,并通过 MySqlConnector 的 MySqlBulkCopy 写入 MySQL。在具体实现过程中,我们做出了以下几个关键决策:

1. 分页策略:避免 OFFSET

对于千万级数据表的分批读取,直觉上会使用 ORDER BY ID OFFSET n ROWS FETCH NEXT b ROWS ONLY 的方式。然而,这种方式的性能随着批次增加急剧下降,因为 OFFSET 的代价是 O(n)。为了解决这个问题,我们采用了其他更高效的分页策略,确保每批数据的读取时间保持稳定。

2. 断点续传机制

为了实现断点续传功能,我们在每批数据迁移完成后记录当前批次信息。如果迁移过程中断,下次启动时可以从记录的批次继续,而不需要重新开始整个迁移过程。

3. 实时监控与日志

BigDBMigrator 提供了详细的实时监控功能,每批数据迁移都会打印进度、速率和耗时信息。这不仅方便我们跟踪迁移进度,还能在出现问题时快速定位故障点。

4. 幂等安全性

为了确保迁移过程的安全性,我们设计了幂等机制。即使迁移过程中出现重复执行的情况,也不会对目标数据库造成影响。这通过在迁移前检查目标表中是否已存在相同数据来实现。

迁移过程中的挑战与解决方案

在实际迁移过程中,我们遇到了一些预料之外的挑战。例如,某些特殊字符在 SQL Server 和 MySQL 之间的编码转换问题,以及 GUID 类型数据在两种数据库中的处理差异。针对这些问题,我们分别采取了字符集转换和自定义数据映射策略来解决。

此外,由于迁移过程中需要处理大量并发操作,我们还优化了连接池配置和批量插入的大小,以提高整体迁移效率。通过这些优化措施,最终成功完成了 1538 万行数据的迁移任务,整个过程耗时约 3 小时,远低于预期的 13 小时。

结语

通过这次迁移实践,我们不仅成功解决了大规模数据迁移的技术难题,还积累了宝贵的经验。BigDBMigrator 的设计思路和实现方法可以为类似场景提供参考。未来,我们将继续优化该工具,增加更多高级功能,如数据校验、冲突处理等,以满足更复杂的迁移需求。