十年沉睡数据,一招激活智能决策力
|
告警响的那一刻,我正把泡面叉子插进最后一块蛋里,屏幕右下角弹出三个窗口:Zabbix 的红色爆闪、Ansible 批量执行失败、还有开发老张发来的钉钉语音——我点开,他嗓子里像卡了台旧风扇:“你那边是不是动了啥?订单创建延时直接飙到十二秒。”我没回,把叉子放下了。窗外天快亮了,灰蒙蒙的,机房空调嗡嗡震得人太阳穴跳,冷得人后颈起栗子。 其实我原以为是证书续签漏了。上个月刚补了三台机器的 TLS,顺手把 Nginx 配置全扫了一遍,连注释里的“# 2016 年老接口兼容”都删了。结果凌晨三点半,不是证书过期,是数据库连接池在抽风——不是满,是空。监控没报警,它自己静音了十年。不是坏,是睡死了。好几台实例,查慢日志发现第一条记录是 2015 年 11 月 7 号,最后一条是 2016 年 4 月 12 号,之后再没写过一行。整整十年,数据在库里躺着,表结构没变,索引没重建,统计信息全是初始值,连 autovacuum 都懒得碰它。运维群早没人提这库,DBA 换了两轮,文档里只有一行:“历史归档库(读),勿动。” 我翻了翻迁移复盘纪要——上回整库迁移是 2022 年,用的逻辑备份,恢复完也没人测读性能,反正当时没告警。那会儿我就觉得不对劲:导出命令加了 --no-owner --no-privileges,但没加 --disable-triggers,结果一堆触发器锁表三小时,同事小王蹲在机柜前啃冷包子等解锁,嘴里还念叨“这库早该下线了”。结果呢?下线评审会开了三回,最后因为“下游有个报表还在跑 weekly cron”,拖着。报表跑完,cron 脚本被注释掉了,没人删。它就那么挂着,跟墙缝里一株干掉的绿萝似的,没人浇水,也没人拔。 那天晚上真正致命的操作?就一句:我把 pg_statistic 里这张表的 n_distinct 和 null_frac 值,手动 update 成了真实采样结果。半句都没多写。就两条 SQL。第一条执行完,第二条还没敲完,开发老张的电话打进来,我没接,直接按了免提。他说:“你们是不是把那个‘用户地域热力’接口重写了?”我嗯了一声。他说:“怪了,之前查一次要七秒,现在 320 毫秒。我们刚上线新算法。”我没吭声。我盯着屏幕左上角——那个我忘了关的 Slack 窗口还开着,里面是家里人问“晚饭吃了吗”,我回了“吃了”,其实泡面还在碗里晃汤。
文章配图,仅供参考 优胜劣汰——这话不是虚的。我查了所有十年没访问过的表,三百二十张。挨个看 last_modified(我们自己埋的字段,没走 pg_class.rellastmod,因为太假),真·十年没动的六十三张。其中十七张,在更新统计信息后,查询计划立刻从 Nested Loop 切成 Hash Join;二十一张,自动触发了分区剪枝;剩下二十六张……干脆被优化器直接忽略——执行计划里压根不出现它们。对,它认出来:你连统计信息都不维护,你就是个幽灵表,不配进计划。这不叫淘汰,叫系统自发清退。不是人删的,是数据库自己判定“你不值得被算进去”。比我们当年搞下线流程痛快多了。当年为下掉一张日志表,开了四次跨部门会,法务怕丢审计证据,安全怕违规留存,最后折中方案是“加密归档至磁带库”,结果谁也没去换磁带,那批磁带现在还在机柜最底下压着,标签纸泛黄,字迹洇开,写着“2016Q3”。 说到磁带,想起上周值班表又轮到我值周六夜班。我老婆今早发消息说:“孩子发烧了,三十八度六,你要回来一趟。”我回她“等这波告警过了”,然后把手机倒扣在键盘上。屏幕还开着另一窗口:Chrome 里是《2016 年安全基线文档》PDF,第 47 页标红了一行:“建议每半年刷新静态数据统计信息。”——当时没人当真。我们信的是“不动就不坏”,结果坏得悄无声息。十年前写的脚本,现在还在 crontab 里跑着,每周三凌晨两点清理 /tmp 下的临时文件,可/tmp/目录早就挂了 tmpfs,清理命令执行成功,返回码 0,日志里写着“0 file removed”,实际上它删了个寂寞。 火大吗?不至于。就是心里硌得慌。像摸到一件旧西装内袋里还揣着半包受潮的烟,打火机都锈了,火石刮不出火星。你知道它不该在这儿,但也没力气掏出来扔了。这次能撞见,纯属运气差:老张非要给那个三年没人碰的运营后台加个实时热力图,开发随手联了“历史库”做参考维度,SQL 里写了 LEFT JOIN,优化器被迫扫了十年沉睡表——然后,它醒了,带着一身尘和错乱的直方图,反手就让整个集群抖了半宿。我们一直以为数据睡着是省资源,结果它睡着是在耗决策精度。不是数据没用,是它用错了方式活着:靠默认值骗优化器,靠空统计骗 DBA,靠沉默骗所有人相信“没动静=没问题”。 我今早补了件事:把 pg_statistic 更新脚本塞进每日巡检,不走定时任务,改成了人工触发——就一条 alias:“alias freshstats='psql -c \\"SELECT update_table_stats();\\"'”。为什么不用自动化?因为我试过。去年在测试环境推了个 auto-stats 工具,跑三天就崩了:它把一张千万级大表误判为“低频冷表”,直接把统计采样率降到 0.1%,结果某次促销查询直接绕开索引,主键扫描耗时四十一秒。工具没错,是它不认识什么叫“伪冷表”——表面不读,其实每笔订单创建都隐式 JOIN 它三次。所以这事我认了:智能决策力不是算法给的,是人亲手把十年沉睡的脉象号准了,再喂给系统一口真实的气。至于下一步?补不了全量。我打算先从三十张高关联表下手,逐个跑 ANALYZE VERBOSE,顺便看看日志里有没有人在偷偷查这些表——比如老张的热力图,比如财务部那个从来只出现在邮件抄送栏的“季度穿透分析”。要是真有人在用,那这十年,根本不是沉睡,是装睡。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |




