37岁,我在成都 40 度的热浪里,感受代码的冰冷

数据全毁了,不是部分,是整整三个月的体育场馆预约记录,四十多万条。空调开到16度,汗还是顺着脊椎往下淌,不是热的,是代码逻辑里那个该死的边界条件,把delete写成了update,还他妈没加事务回滚。

成都这鬼天气,四十度,体感像在蒸笼里。我盯着屏幕上那一大片刺眼的“0”,感觉比窗外的水泥地还烫。团队去年就解散了,现在所有活儿自己扛,从谈需求到写爬虫到清数据,链条一断,全盘皆输。这次接的是个连锁健身房的系统对接,要把他们分散在美团、大众点评、自家小程序里的预约数据统一清洗、去重、入库,再跑分析模型给他们做排课优化。听起来挺美,钱也不少,但坑都在细节里。

问题出在去重合并那一步。原始数据源太脏了,同一个用户,在美团叫“张老三”,在小程序里是“Zhang LaoSan”,手机号还缺一位。我设计了个基于“手机号后八位+预约时间戳+场馆ID”的联合模糊匹配逻辑,先用正则清洗,再用相似度算法跑。跑测试集没问题,真上了生产环境,数据量一上来,内存就崩了。我为了省事,没做分批次处理,想着一次性load到内存里用pandas怼完。结果脚本卡死,我强制中断,再重启时,那个关键的标志位更新语句,在异常处理分支里,手滑把“UPDATE records SET flag=1 WHERE…”写成了“DELETE FROM records WHERE flag=0”。更要命的是,我图快,没开数据库事务。

瞬间,所有未处理的原始数据,全没了。备份?有,是三天前的。这三天新增的预约数据,全泡汤。客户下午还要看数据看板。

现在不是骂娘的时候。我关了空调,让自己完全暴露在燥热里,强迫冷静。第一步,救火。赶紧联系客户运维,看能不能从数据库binlog里恢复。运气好,他们的MySQL开了日志,但只保留七天。花了两个小时,导出一份删除时间点的日志,用mysqlbinlog一点点解析、回滚。这过程里,手一直在抖,不是怕,是那种对自身愚蠢的强烈愤怒。一个十年经验的老手,犯这种低级错误。

火暂时灭了,但根子没解决。我给自己定了新的铁律,所有数据清洗脚本,必须遵循以下结构,少一步就抽自己一耳光:第一,任何写操作,必须包裹在显式事务里,BEGIN…COMMIT/ROLLBACK,像呼吸一样自然。第二,核心变更语句执行前,先用SELECT预览影响行数,把结果打印到日志,人工确认。第三,实行“双备份”制,动生产数据前,先全表导出到临时表,表名加`_bak_时间戳`。第四,引入“软删除”和操作审计表,任何DELETE或UPDATE,实际是更新状态位,并记录操作人、时间、IP和前置数据快照。

这些规则会让每个脚本的执行速度慢至少40%,但慢就是快。真正的快,不是敲代码的手速,而是不用回头补窟窿、不用低声下气求运维、不用在凌晨三点对着空洞的数据库发呆的那种“快”。那种快,能让你在四十度的天气里,后背不发凉。

搞完这些,天都快亮了。热浪稍微退下去一点。我给自己灌了瓶冰水,看着恢复后的数据行数,和日志里那条“预览影响行数:438,762”的记录。这次教训,价值四十万条数据。比任何管理课、任何产品方法论,都来得直接。37岁, solo 打仗,命就是代码,代码就是命。容错率是零。

© 版权声明
THE END
喜欢就支持一下吧
点赞59 分享