跳到主要内容

今天下午差点把预发搞挂,记录一下

敏姐转开发
敏姐转开发

· 阅读约 3 分钟

今天下午两点二十几(具体时间记不清了,反正刚过午休),我把预发环境的订单主表改了,四十七条,改完不到十分钟,群就炸了。

先交代背景,不然看不出这事有多险。我转过来第十一个月,这个模块是第九个月开始独立带的。里面有一张 t_order 表,历史遗留的脏状态:有一批单子状态停在 PENDING_AUDIT,但审核流水其实早走完了,正常应该是 AUDITED。这批单子前端点进详情会报错,客服那边攒了小半年,产品催过两次。我上周把方案写了,准备这周三上。方案简单得很:写个数据修正脚本,把状态是 PENDING_AUDIT、update_time 早于某个时间点、并且审核流水里有对应记录的那批,刷成 AUDITED。

按我做测试的习惯,动手前先建了备份表。这句其实是今天唯一做对的事——不对,不是唯一,但确实是救命的那个。CREATE TABLE t_order_bak_20260928 AS SELECT * FROM t_order,全表备的。我问了 DBA,说这张表不大,两百多万行……呃不是,二十几万行,我记混了,反正不大。他让我別挑业务高峰跑,我选了下午两点。

然后是预发。预发那张表只有三百多条,我跑了一遍,影响 3 条,报错 0 条,我还挺得意。但是我犯了个错:我没跑那条 select count。这语句我明明写了,写在脚本最上面,跑的时候我直接选中 update 那段执行,前面那条没选上。就这么个手滑。

预发跑完大概五分钟,订单列表开始 500。我去翻日志,报的是 IllegalStateException: status transition not allowed: AUDITED -> AUDITED。看清楚了才明白:状态机那边有拦截,同一个状态重复流转会抛异常。那为什么会有已经是 AUDITED 的单子又走了一遍流转?因为那批脏数据的 update_time 被人工改过,掉进了我的 where 条件里。预发那 3 条里正好有一条是这种。

所以要是直接上了线,线上二十几万行里掉进来多少条?我后来数了,1184 条。这 1184 条会把订单详情和列表一起打挂。

捡回来倒不复杂,因为备份表在手。写了个 join,把 status 从备份表刷回去。跑之前我数了一遍影响行数——这个我按做测试的旧习惯叫预期结果——应该正好 47,多一条少一条都不对。第一次跑出来 47,我松了口气,结果前端还在报错,哦是有缓存,等了两分钟才消。

写回滚脚本的时候手是真抖,中间把 ON 打成了 NO,运行报语法错,我愣了两秒,以为表已经刷坏了。后面就顺了。

现在还剩两件事没弄完。一是 where 条件我还没想好怎么收:update_time 被人改过这件事本身就是个坑,我打算先加一条"排除已终态"的条件,但这条到底够不够,我还没底。二是这脚本要不要上线,我现在有点怂,想再拿预发的全量快照跑一遍,可那套快照环境搭起来要一天。

先这样吧,想到再补。

敏姐转开发
敏姐转开发

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

查看主页 →