跳到主要内容

差点搞出一次事故,记录一下

敏姐转开发
敏姐转开发

· 阅读约 3 分钟

今天上午,差点把测试库里别人正在测的数据改掉。写下来给自己,不是给别人看。

背景先交代一下:我们模块有个「结算状态」字段,去年底做了一次状态机迁移,老的三个码合并成了新两个码,但历史数据里还留着一批老码没转。上线时做了兼容,读的时候做了映射,所以看起来是好的(其实不算真的「好」,只是遮住了)。但是下游导出那边一直有人报数不对,查下来就是这批老码。

所以项目经理安排我写个订正脚本把老码翻成新码。我负责的那个小模块正好有这块,就落我头上了。

流程我是按做测试的习惯来的:先把要订正的数据捞出来看了一遍,分了几类,边界大概有五六种(有一个是「老码+已退款」,这种我一开始不确定该翻成什么,问了一圈才确认)。然后写了个用例集,十几条假数据,把每种边界都锁住。先在本地跑,全绿。再在测试环境跑一遍,也全绿。

这里我要说一个事:我当时以为测试环境的库是独立的。我理解的是,每个环境一套库,这是常识吧。结果不是。我们测试环境的这个库和预发是共用的——历史遗留,好像是当年为了省资源一直没拆,反正就这么留下来了。我不知道。没人告诉过我。也可能有人说过我忘了。

前面说了这么多才说到正题。今天上午我在测试环境跑那个正式订正。脚本是包在事务里跑的,这个是我做测试时留下的习惯,改数据类的脚本我现在都包事务,不 commit 先看 count。(以前吃过教训,不过那次不是我的锅,这个下次再写。)跑了以后,屏幕上的 affected rows 比我预估的多不少。我当时心想不对,但没反应过来是哪不对——因为 dry run 的结果和这个数字对不上。dry run 是 3200 多,实际 affected 快 5000。

我第一反应是脚本逻辑有问题,去翻了翻 SQL,翻了两分钟没发现。然后钉钉开始响。部署群里有人在问,说测试环境里他们的用例数据挂了,结算状态突然全变了。我看到这条消息的时候,手是凉的。

因为脚本是包在事务里的,没 commit。我把连接切回去做 rollback,做的时候手有点抖,敲了两遍才敲对命令。回滚完让那个同事再跑一遍他的用例,恢复了。

后面复盘一下为什么多出来这一千多条。原因是这样:我写条件的时候带了 create_time < '2026-09-30',因为我觉得只有历史数据才需要订正。但是有个逻辑我没注意到——7 月份之后有一批数据是导入进来的老系统数据,他们的 create_time 是入库时间,但内容其实是老码。所以这批数据没被我那个时间条件挡住,被一起改了。这个边界我写用例时完全没想到。想当然认为 create_time 就是业务时间。

这个坑我那个用例集覆盖不到,因为我根本想不到要去覆盖它。(我一下理解了开发同事老说「用例永远覆盖不全」,原来是真的。)

不过话说回来——如果它没跑在共用库上,如果那条消息是下午才发的,如果我那个脚本没包事务,这事就不是文章了,是复盘会。所以这次算是运气兜住的。技术上我没做对什么,只是习惯救了我。

后面两件事得做:一是脚本要加条件,导入数据得单独区分;二是那个共用库的事,我要去问一下,到底是不是真共用,还是我理解错了(搞清楚之前我不打算再在测试环境跑任何写操作)。

先这样吧,想到再补。

敏姐转开发
敏姐转开发

测试八年,转开发第一年。慢一点没关系,返工最贵。

查看主页 →