凌晨两点十七分,值班手机震了。
监控大屏上,数据库连接数那条曲线像被什么东西猛地拽了一把,从平时的1200左右,直接冲到了5800。业务侧的消息跟着就炸了——“页面打不开”“订单提交卡死”。我放下手里的速溶咖啡,坐到操作台前,脑子里先过了一遍:今天没上线,没变更,大概率是慢查询把连接池打满了。
登录跳板机,切到数据库服务器,show processlist一敲,好家伙,四百多个“Sending data”状态的查询,全卡在同一张订单表上。把那个SQL拷出来,explain跑一下,type列是ALL,扫描行数三千多万。索引失效了。我瞟了一眼时间,从手机震到定位问题,刚好三分钟。
不是手快,是这种场景太熟了。上个月做演练的时候我就说过,线上环境这种不走索引的大查询,必须五分钟内止血。先把那条SQL对应的连接全杀了,pkill -f “xxx”,再临时加个限流策略。连接数掉下来了,业务恢复。整个过程七分钟。说实话,如果慢一点,连接池彻底被占满,就得重启应用,那影响面就大了。
这事儿告一段落,但我没关终端。翻了翻慢查询日志,发现这条SQL最近一周执行计划都是正常的,怎么今天就炸了?再看表结构,上周开发那边给订单表加了个字段,但建表语句里用了ALGORITHM=INPLACE, LOCK=NONE,按理说不会锁表。问题出在另一个地方——新字段的类型是varchar(64),而SQL里关联查询用的条件传的是int。隐式转换,索引直接废掉。
我截了图,把执行计划和表结构对比一起打包,钉钉上发给对应的开发。附加一句话:“下次改表结构,相关的SQL执行计划记得看一眼。”
上午九点半,按惯例做夜间的巡检报告。监控系统没告警,但我注意到有个服务的错误日志量在凌晨三点到四点之间,有规律地出现尖峰。每次持续七分钟,然后自动恢复。阈值设的是“连续十分钟错误率超5%”,七分钟,刚好绕过去。
这不是工具的问题,是人的问题。我把那段时间的变更记录调出来,发现有个定时任务正好在那会儿跑,任务里有个操作会锁一张大表的元数据。业务请求进来的时候拿不到锁,报错,重试,七分钟后任务结束,锁释放,一切恢复正常。
我找到开发的负责人,把日志和锁等待的堆栈甩给他看。他说:“没影响业务,先放着吧,后面再优化。”我没让步。我说:“这次没炸,不代表下次不会。这个定时任务的数据量一直在涨,再过一个月,锁的时间可能从七分钟拉到十分钟,到时候你再看。现在改,成本就是调个时间窗口加个重试;等真炸了,你我都在复盘会上写报告。”他没再坚持,下午就把排期定了。
下午两点,厂商通知来换核心交换机的光模块,说有批次隐患。这活儿本身不复杂,但我留了个心眼。换之前,我把相邻设备的配置全备份了一遍,show running-config和show vlan各存一份,接口状态也截了图。
换完之后,光模块状态灯是绿的,但ping核心网关的时候,丢包率在5%左右。第一反应是光模块兼容性问题,差点就拿起电话投诉厂商了。但我还是先切到交换机上,show interfaces看了一圈,发现那个端口的CRC错误计数在涨,runts也有。这不是光模块的锅,是那根跳线老化了,拔插的时候受了力,内部接触不良。
如果当时只盯着光模块换,这个问题可能就漏过去了。等业务有感知再查,又得绕一大圈。现在我养成个习惯,但凡涉及物理接口的操作,变更前后必须留一份“状态快照”。有对比才有真相,不然你都不知道问题出在哪一步。
下午四点半,趁着脑子还热乎,我把今天这几个事理了理。
一个是定时任务锁表的问题。我往“高风险变更检查表”里加了一条:涉及元数据锁的操作,必须评估执行时间窗口和业务低峰期的重叠度,同时确认监控阈值能否覆盖。不能指望监控系统帮你兜底,它只是工具,真正知道该看什么的,还是人。
另一个是跳线老化的事。我在“变更操作checklist”里补了一段:涉及物理接口的操作,变更前必须记录接口协商状态、错包计数,变更后逐一比对。这玩意儿,干过运维的都懂,就是那些书本上不写,但关键时刻能救命的小招数。你永远不知道一个看起来正常的硬件,会在什么时候给你使绊子。
下班前,我把今天故障处理的整个过程整理成文档,塞进团队的知识库里。不光是“怎么解决的”,还写了“为什么要这么解决”“中间有哪些判断差点走偏”。新来的同事照着这个做,至少不会在原地上再踩一遍坑。
说实话,干这行久了,你会发现真正让人成长的,不是那些顺顺利利的日常,而是那些“我靠,差点没顶住”的瞬间。每一次故障,都是一次压力测试,不光是测系统的稳定性,也是在测你自己的判断力和抗压能力。
我现在看问题,不只看它炸没炸,更看它有没有炸的潜力。那种“每次都绕过去”的异常,比直接炸了还危险——你根本不知道它在那儿悄悄挖坑。等哪天坑填满了,一脚踩下去,就是个大事故。
-
需要更多的工作总结网内容,请访问至:工作总结