数据库迁移这事儿,干过的都懂,就像在刀尖上跳舞。数据量小的时候还好说,几十个 GB,找个夜深人静的凌晨,导一下,重启,完事。可一旦上了 TB 级别,甚至几十个 TB,你就得打起十二分精神。稍有不慎,数据库直接崩溃,业务系统跟着宕机,老板的电话能把你手机打到没电。我见过最惨的一次,某电商平台做数据迁移,没做好限流,源库的查询压力瞬间飙升到平时的十倍,磁盘 IO 直接打满,主从延迟从几秒飙到几个小时,不得不回滚,整个迁移窗口延长了两天,客户投诉电话打爆了客服部。所以,想要高效迁移海量数据还能保住系统稳定,核心就三个字:控节奏。

第一个关键动作是给迁移任务装上“刹车片”。你不能想着一次性把几 TB 的数据全倒过去,那相当于让一头大象挤进一个窄门。正确的做法是分片迁移,按时间、按 ID 范围、按业务模块,切成一个个小块。比如按日期分,每天几百万条,分批执行。每批次之间留出缓冲时间,让源库和目标库喘口气。同时给每批任务设定超时阈值,如果某批次执行时间超过预设值,自动终止并跳过,防止死循环拖垮系统。我做过一个金融系统的迁移,数据量大概 5 TB,我们按小时分片,每批次处理 100 万条,批次间隔 10 秒。这样虽然总时间拉长了,但源库的 CPU 和 IO 始终维持在 30% 以下,业务系统几乎没有感知到异常。
光控节奏还不够,你得给数据库装个“心跳监测仪”。迁移过程中最怕的不是慢,而是突然的负载飙升。你需要实时盯着几个核心指标:连接数、活跃会话、锁等待、磁盘 IOPS、主从延迟。一旦某个指标突破阈值,比如活跃会话数超过正常值的两倍,立刻触发降级策略——要么暂停迁移任务,要么降低当前批次的并发度。我见过一个团队做迁移时,源库的锁等待突然暴增,结果没人发现,等到业务反馈查询卡死,已经晚了。后来他们在迁移脚本里嵌入了监控逻辑,每批次执行前先检查数据库健康状态,如果锁等待超过 5 秒,就自动休眠 30 秒再重试。这个简单的机制,救了不少场子。
迁移过程中另一个容易翻车的点是索引和约束。很多人图省事,直接把源库的表结构和索引一股脑全建到目标库,结果写入效率惨不忍睹。正确的姿势是:先在目标库关掉所有索引和约束,把数据当成裸数据灌进去,等数据全部到位后再批量重建索引。这个操作能让写入速度提升 5 到 10 倍。我参与过一个电商订单库的迁移,数据量 8 TB,之前开着索引写入时每秒只能灌 3 万条,关了索引后直接飙到 20 万条。当然,重建索引的几分钟会影响查询,但可以选在业务低峰期进行,或者使用在线 DDL 工具(如 pt-online-schema-change),把影响降到最低。
别忘了给迁移任务留条“回滚路”。很多团队只盯着“怎么迁过去”,却忘了“万一出问题怎么退回来”。在迁移开始前,必须确保全量数据有备份,并且备份文件可用。同时,设计好回滚脚本,一旦目标库出现问题,能快速把流量切回源库。我见过最离谱的案例,某公司做数据库迁移,源库和目标库同时写入数据,迁移到一半发现目标库数据不完整,想回滚却发现备份文件损坏,只能从生产环境重新导数据,业务中断了整整两天。所以,迁移前一定要做一次完整的备份恢复演练,确保备份文件能正常拉起一个可用的库。
还有一个容易被忽略的细节:数据一致性校验。迁移完成后,不能拍拍屁股说“数据过去了”,必须验证两边的数据是否完全一致。最简单的做法是比对总行数,但更严格的做法是按分片比对 CRC 校验值。我习惯使用 pt-table-checksum,它能逐行比对源库和目标库的数据,发现不一致的地方还能自动修复。有一次迁移时,校验发现某个分片中目标库比源库少了 5 000 条,查了半天才发现是迁移脚本在处理特殊字符时出了 bug。如果没有这一步校验,问题可能会在业务上线后才暴露,后果不堪设想。
别忘了给业务系统一个“过渡期”。迁移完成后,不要立刻把所有流量切到新库。先切一部分只读流量,比如报表查询、后台统计,观察一两天,确认新库的查询性能和稳定性没问题后,再逐步切写流量。可以采用灰度发布策略,先切 10% 的用户流量,观察 24 小时,没问题再切到 30%,以此类推。这样即使新库有问题,影响面也有限,回滚也快。我做过一个社交平台的迁移,新库上线后第一天只切了 5% 的读流量,结果发现新库的某些查询比源库慢了 3 倍,赶紧调优索引,等性能达标后才逐步扩大。过程虽然慢,但确保了业务零中断。
说到底,数据库迁移这活儿,拼的不是技术有多炫,而是细节把控有多到位。你得像个老司机一样,知道什么时候该踩油门,什么时候该点刹车,什么时候该看后视镜。别想着一步到位,也别赌运气。做好分片、监控、索引优化、回滚方案、数据校验、灰度切流,这六步走下来,即便遇到再大的数据量,也能稳稳地把车开到终点。毕竟,一次成功的迁移,远比一次快速的迁移更有价值。


