哥几个,今天跟你们唠唠我那回《弗雷德狂奔》的事儿。说起来真是一把辛酸泪,但也挺带劲的。那会儿公司里有个老系统,叫它“弗雷德”,那真是老掉牙了,跑起来跟蜗牛似的,每次一到月末出报表,整个机房都能听到风扇嗷嗷叫,就跟弗雷德在喘气儿一样。
这玩意儿用了好几年,谁也不敢动它,生怕一碰就塌。但总有那么一天,扛不住了。我们老板突然不知道从哪儿听来的消息,说月底之前,所有核心数据都必须迁到新服务器上去,还要换个新的数据库。这话一出来,整个部门都炸锅了。这不就是把弗雷德给活生生拆了,再用新的零件拼起来吗?而且只给了一个月时间!
起步,硬着头皮上
接到这任务,我当时就懵了。弗雷德那堆代码,历史比我工龄都长,注释少得可怜,各种奇奇怪怪的存储过程,好多都是手写的SQL,连着好几个数据库,关系盘根错节。谁动谁死。但没办法,任务下来了,不干也得干。我们组长直接点名,说我平日里爱折腾老物件,这活儿非我莫属。我也没辙,只能硬着头皮接了。
我第一步是先去把弗雷德的老底儿给摸清楚。我从哪儿开始?先是吭哧吭哧把数据库连接配置都扒拉出来,然后一个个对着老配置文件、老代码文件,想搞明白它到底是怎么个跑法。那几天,我抱着电脑就跟抱着个定时炸弹似的,生怕敲错一个字,整个生产环境就崩了。我翻阅了堆积如山的老文档,有的还手写着,纸都黄了。我拉过来以前的同事,挨个儿问,问到他们都烦我了,说这玩意儿谁还记得住。
- 把旧的数据库表结构,字段类型全部导出,一个个比对。
- 分析那些老掉牙的存储过程,弄懂它们的业务逻辑。
- 记录下所有外部接口,看看弗雷德还跟哪些系统有着千丝万缕的联系。
这摸底阶段就搞了我差不多一个星期。头都大了。数据量太大,每天光是跑个数据同步的脚本,都要一两个小时,关键还不能一次性全跑,得拆分,得小心翼翼地跑。
狂奔,问题一个接一个
底子摸清了点儿,我就开始着手迁移了。新服务器、新数据库都备好了,性能那是杠杠的。问题是,怎么把老数据安全无误地搬过去?
我们决定采用增量迁移的方案。先是写脚本,把老数据里那些最核心、变动最少的静态数据先同步过去。这个阶段还算顺利,虽然跑得慢,但好歹没出大错。接着就是那些每天都在刷新的业务数据。我开始尝试写更复杂的同步脚本,要能实时捕获老数据库的变动,然后更新到新数据库里。
这一写不要紧,问题就来了。老数据库里好多脏数据,各种重复的、格式不对的,还有一些根本不知道是干嘛的字段。新数据库的规范严格多了,这些脏数据一过来就报错。我不得不一点点排查,清洗,转换。那段时间,我每天跟SQL语句打交道,眼睛都快花了。有时为了一个字段的数据格式转换,得尝试好几种函数,跑一遍又一遍的测试。
最让人头疼的是,弗雷德还有一些业务逻辑是直接写在数据库触发器里的,搬家的时候不能直接照搬。我绞尽脑汁,和组长反复商量,最终决定把这些逻辑重构成新的应用层代码,然后在新系统里实现。这意味着我不光要迁数据,还要改代码,测试逻辑。时间紧,任务重,每天都得加班到半夜,吃住都在公司了。
有那么一回,快到割接(就是切换新老系统)的前几天,我发现一个致命的bug。一个关键的报表,新系统跑出来的结果跟老系统对不上!当时汗就下来了。我赶紧回去查,一个个SQL语句对照,一行行代码调试。查到才发现是老系统里一个隐蔽的函数,在一个非常特殊的业务场景下,会把某个字段的值多算了一次!这东西要不是在老系统里藏得太深,平时根本发现不了。我立刻调整了新系统的计算逻辑,重新跑了一遍测试,终于对上了。那一刻,我觉得自己跟侦探似的,查出了一个隐藏多年的“谋杀案”。
冲刺,弗雷德“退役”
到了割接那一天,所有人都很紧张。大家提前开会,把所有的步骤都罗列出来,精确到分钟。凌晨两点,我按下了一批数据的同步按钮,然后大家屏住呼吸,切换了系统的数据库连接。新系统启动起来,那速度简直是飞快,报表唰唰地就出来了。我盯着监控,看着各项指标飙升,但都稳定住了,没有错误。心里的石头总算是落了地。
从那天起,弗雷德就“退役”了,虽然它的名字还在,但核心业务已经完全跑在新系统上了。我们再也不用担心月末机房“咆哮”了。那一个月,我感觉自己瘦了一圈,头发都掉了不少。但看到新系统运行得这么溜,心里还是挺有成就感的。这弗雷德的狂奔,可算是跑完了。
