上周跟一个做电商的朋友吃饭,他愁眉苦脸地说公司要换服务器,数据库得搬家,六百万条订单数据,光想想就头皮发麻。我问他准备怎么搞,他说打算让运维小哥周末加个班,用mysqldump一把导出再导入。我当时差点把嘴里的啤酒喷出来——这不是给数据搬家,这是在玩火。

数据库迁移这事儿,说白了就是把你辛辛苦苦攒了多年的数据,从一个地方挪到另一个地方。听着简单,做起来全是坑。我见过太多人栽在这上面:有人迁移完发现数据少了三天的交易记录,有人半夜三点被老板电话叫醒说系统崩了,还有人迁移完才发现新数据库压根没开binlog,数据丢了连恢复的机会都没有。说白了,数据库迁移不是技术活,是良心活——你做的每一步,都直接关系到公司能不能正常运转。
先说最基础的事儿:迁移前必须搞清楚你要搬什么。很多人一上来就想着怎么搬,却忘了先想搬什么。你的数据库里,有些表是核心业务数据,比如用户信息、订单记录、支付流水,这些丢了公司可能直接倒闭。但也有些表是日志数据、临时缓存,三个月前的访问记录,丢了也无所谓。所以第一步,找业务方一起梳理数据资产,给每个表打标签:核心、重要、一般、可丢弃。这不是技术问题,是业务决策。你作为技术负责人,得主动去跟运营、财务、客服聊,问清楚哪些数据他们天天用,哪些数据三年都没人碰过。这一步做好了,后面能省一半功夫。
接下来是选工具。市面上的数据库迁移工具多到让人眼花缭乱,但别被各种花里胡哨的功能忽悠了。你得先搞清楚自己的场景:源库和目标库都是什么类型?MySQL到MySQL,那简单,mysqldump或者MySQL Workbench都能搞定。但从Oracle到PostgreSQL,或者从SQL Server到MySQL,那就复杂多了,得用专业的迁移工具,比如AWS的DMS或者阿里云的数据传输服务。我有个朋友从MySQL迁移到TiDB,图省事直接用mysqldump导出再导入,结果跑了三天三夜,中间还断了两次,数据校验发现对不上,只能重来。后来换了TiDB官方推荐的Dumpling工具,半天就搞定,数据还自动做了校验。工具选对了,效率翻倍;选错了,等着加班吧。
数据量也是个关键因素。如果你只有几百兆数据,随便找个工具都能搬。但如果你有几百个G甚至上T的数据,那就得认真规划了。大文件迁移最怕两件事:网络中断和磁盘空间不足。我见过最惨的案例,一个哥们儿用scp传200G的SQL文件,传到一半网线被保洁阿姨踢掉了,又得重传。更惨的是,他忘了检查目标服务器的磁盘空间,导入到一半磁盘满了,数据库直接挂了。大文件迁移的正确姿势是什么?压缩传输,用gzip或者pigz把SQL文件压到原来的三分之一大小;分片传输,把大文件切成100M一个的小块;断点续传,用rsync或者专门的数据传输工具。这些细节看似琐碎,但任何一个掉链子,都能让你一夜回到解放前。
迁移过程中的数据一致性是个硬骨头。你在导出数据的时候,源库还在不断写入新数据,这就导致你导出的数据可能不是同一个时间点的快照。比如你导用户表用了10分钟,这10分钟里正好有新用户注册,那这些用户的数据在导出文件里就没有。更麻烦的是,如果你的业务有跨表的事务,比如下单操作同时更新订单表和库存表,导出时可能只导出了订单表的新数据,没导出库存表的更新,那迁移完数据就对不上了。解决这个问题的办法是使用数据库的事务一致性功能,比如MySQL的FLUSH TABLES WITH READ LOCK,或者在导出时指定--single-transaction参数,让导出操作在一个事务里完成。但注意,这会影响线上业务,得选在业务低峰期操作。
迁移完不等于结束,数据校验才是真正的关卡。我见过太多人,迁移完直接切流量,结果用户登录报错、订单查不到,才知道数据有问题。正确的做法是先做全量校验:把源库和目标库的数据逐条比对,看记录数是否一致,关键字段的值是否相同。常用的工具有pt-table-checksum,它能快速比对两个库的数据差异。但注意,这个工具会消耗数据库性能,建议在从库或者低峰期运行。如果记录数对不上,别慌,先看差异在哪里,再决定是重新迁移还是手动补数据。比全量校验更重要的是增量校验:迁移完成后,源库还在运行新业务,这些增量数据也要同步到目标库。如果你用的是数据同步工具,比如Canal或者Debezium,一定要监控同步延迟和错误日志,确保增量数据没有丢。
别忘了业务验证这步。数据校验通过,不代表业务就能正常运行。你的应用代码里可能硬编码了数据库地址,或者用了某个数据库特有的函数。比如MySQL的DATE_FORMAT函数,在PostgreSQL里就不存在。再比如你的ORM框架可能在MySQL里用了自增主键,迁移到TiDB后,自增主键的分配策略变了,可能导致性能问题。所以迁移完成后,先让测试团队跑一遍核心业务流程:用户登录、下单、支付、查询订单。别只跑一遍,要多跑几遍,模拟高并发场景。我有个客户,迁移完自测一切正常,结果第二天早上九点,用户一窝蜂涌进来,数据库连接池直接被打满,系统卡死。后来查原因,是迁移后数据库的连接数参数没调,默认值太小。这些坑,都是前人用血泪踩出来的。
说一个很多人忽略的点:回滚方案。数据库迁移不是一次性的,万一迁移后发现数据有问题,或者业务性能不达标,你得能快速回滚到旧数据库。所以迁移前,旧数据库别急着关,保留一份完整的快照。同时,在迁移过程中,每次操作都要有记录:什么时候导出的数据,导出了哪些表,用了什么参数,目标库的配置是什么样的。这些记录在你回滚时能救命。我见过最离谱的案例,一个团队迁移完发现数据对不上,想回滚,结果旧数据库已经被新业务覆盖了,只能从备份里恢复,而备份还是三天前的,丢了整整三天的数据。所以,回滚方案不是备选项,是必选项。你得提前想好:如果迁移失败,我怎么在30分钟内恢复业务?这个问题的答案,决定了你的迁移方案是否靠谱。
写到这里,想起开头那个朋友。后来我给他支了个招:先做一次小规模迁移,比如先搬一个用户表,数据量不大,跑通流程再说。他用了一天时间,从选工具到数据校验到业务验证,全走了一遍。第二次正式迁移,全程只用了四个小时,数据零丢失,业务零中断。他请我吃饭时说,原来数据库迁移没想象中那么可怕,关键是每一步都想清楚,别图省事。是啊,数据搬家这事儿,跟搬家一样,提前规划好、分步执行、留好退路,就能轻松搞定。怕就怕你觉得自己能搞定,却连箱子都没打包好就急着出发。


