我见过太多人栽在数据库搬迁上。明明提前做了方案,演练了流程,真到了切换那一刻,还是手心冒汗。有个朋友的公司,去年做系统升级,数据迁到一半,主库磁盘满了,事务日志撑爆,整个业务停了四个小时。事后复盘,问题出在最基础的一步——没算清楚数据量到底有多大。他以为三千万条记录撑死两百个G,结果光索引和临时表就占了一倍多。所以,第一步永远是量化,不是估算。你得知道源库有多少张表、每张表多少行、平均行长多少、索引多大、日志多大,连临时表空间都得算进去。拿这些数字去推演目标环境的存储和带宽,才算靠谱。

数据量摸清了,接着要选迁移方式。很多人一上来就想着全量导出再导入,简单粗暴,但风险全在后半程。全量迁移最怕的是业务不停,数据一直在写,你导出的快照和实时数据对不上。所以必须搞清楚一个概念:迁移窗口是停机迁移还是在线迁移。停机迁移适合业务允许短暂中断的场景,比如凌晨两点到五点,把应用停掉,数据库只读,然后全量导出,校验,再导入新库。在线迁移就复杂了,得用工具做增量同步,像Oracle的Data Guard、MySQL的主从复制、PostgreSQL的逻辑复制,这些都能帮你把增量数据追平。但工具不是万能的,你得提前测试同步延迟,别等到切换那天才发现延迟积压了几个小时。
工具选型这事儿,真不能图省事。开源的有pt-table-checksum和pt-table-sync,用来做数据校验和修复很顺手,但只支持MySQL。商业工具像Oracle的GoldenGate,功能强,但贵,而且配置繁琐,光一个进程调优就能让你折腾一整天。我有个客户,非要用一个自己写的Python脚本做迁移,跑了一晚上,第二天一看,数据少了0.3%,查了半天,原来是字符集不一致,中文全变成了问号。所以,工具不在多,在于匹配你的数据库类型和业务复杂度。如果数据量在TB级以下,业务允许短停机,用官方自带的逻辑备份工具最稳妥,比如mysqldump、pg_dump,再配合压缩和并行参数,速度和安全性都够用。
迁移中途最怕什么?不是速度慢,是没人盯着。很多团队把迁移脚本一跑,就各自忙去了,结果日志里刷了上千条警告,没人理会。等到校验,才发现数据对不上,又得从头再来。正确做法是,迁移过程中要有实时监控,至少每五分钟看一次传输速率、CPU占用、磁盘IO和网络延迟。如果发现某个表的导入速率突然掉到零,别犹豫,立刻查是不是锁表了,或者目标库的磁盘空间不够了。我还遇到过一种情况,源库是MySQL 5.7,目标库是8.0,数据类型隐式转换,导致某些字段的精度丢了,金额从100.50变成了100.5,虽然差值不大,但财务那边就是不认。所以,迁移过程中的每一步日志,都要留底,方便回溯。
数据导完了,别急着切流量。先做一次全量校验,比对源库和目标库的表结构、行数、校验和。这一步很多人嫌麻烦,觉得数据量太大,比对太耗时间。但你不比对,怎么知道有没有丢数据?我见过一个团队,用select count(*)比对行数,发现对上了,就切换了。结果第二天业务方说,某个客户的历史订单查询不到,一查,原来那张表有分区,源库的某个分区数据没导出,但行数恰好被另一个表的空行补上了。所以,校验不能只看行数,要按分区、按索引、按关键字段分组比对,最好用工具自动生成比对报告,逐项确认。
校验通过,接下来是切换策略。这里有个关键点:切换不是一步到位,而是先灰度,再全量。你可以先把只读流量切到新库,让一部分用户先体验,观察一段时间,看看有没有报错、性能有没有异常。同时保持源库和新库的增量同步还在跑,一旦发现问题,立刻回切。我有个客户,做的是电商平台,切换那天,他们先切了10%的流量过去,跑了半小时,发现新库的连接数飙高,响应变慢,查了下,是新库的连接池参数没调,和源库的配置不一致。他们马上回切,调完参数再切,这次跑了两个小时,一切正常,才放全量。这个过程很磨人,但比一次性切换出事故强多了。
切换完成,不代表万事大吉。源库别急着下线,至少保留一周,以防新库出现延迟性的数据问题。同时,新库的监控和告警要立刻上线,重点关注慢查询、死锁、主从延迟。如果新库和源库的版本有差异,比如从Oracle迁到了PostgreSQL,那SQL语法、函数、存储过程都可能要改,这些得提前在测试环境跑一遍,别等到生产环境才发现。我还有一个建议,迁移完成后,做一次完整的备份,然后把这个备份放到异地存储,万一新库出了什么幺蛾子,你还有一道防线。
数据库搬迁这事儿,说到底拼的不是技术多炫,而是细节抠得多细。从数据量摸底、工具选型、过程监控、全量校验、灰度切换,到源库保留和备份,每一步都环环相扣。你要做的,不是追求什么零丢失的绝对承诺,而是把每个环节的风险都提前识别、提前预案。零丢失不是靠运气,是靠流程和反复演练堆出来的。下次你接到搬迁任务,别慌,按这个套路走,一步一步来,数据稳稳当当,业务波澜不惊。


