MySQL运维设计实战:36小时崩溃到稳如磐石
|
文章配图,仅供参考 凌晨三点二十,机房空调嗡嗡响得像台老拖拉机,我蹲在IDC机柜前面,手指头按着root密码输错三遍——不是手抖,是左手无名指被泡面叉子戳破了,血珠混着汗往下淌,滴在键盘F7键上。客服在电话里说“我们这边看到MySQL连接数是正常的”,我说“你把‘正常’两个字咽回去”,她愣了两秒,挂了。我原以为磁盘满是最后一个爆点,结果它才是第一声枪响。四十来分钟前告警邮件还躺在钉钉免打扰里没点开,因为前一晚老板在运维群发了个红包,配文“中秋团圆夜,服务稳如山”,我手滑点了领,顺手把群消息设了静音。直到DBA小张冲进值班室,鞋带散着,手里捏着张打印纸,上面印着“/var/lib/mysql 99%”,纸边被他指甲掐出五道白痕。他说:“备份脚本昨儿就卡在scp上没动弹,但监控图看着还是绿的。”我看那图——绿得发虚,像隔着一层水膜看荧光笔划的线。 我扒拉服务器日志时,窗外开始下雨,雨点砸在机房顶棚像撒了一簸箕铁豆子。小张坐我旁边啃冷包子,忽然说:“你记得不?去年搬家,打包箱写着‘数据库配置’,拆开全是旧硬盘盒。”我没应,手还在翻slow_log那个23GB的文件——不是慢查多,是SELECT FROM user_history LIMIT 1 每分钟被执行四百多次。谁干的?没人认。开发组长老李后半夜上线,盯着屏幕盯了七分钟,突然笑:“哦,我上周给测试环境配了个新定时任务……忘删crontab了。”他删得挺快,可磁盘IO那会儿已经堵成早高峰地铁口。 DNS解析出问题那阵子,最离谱的是CDN缓存没崩,反倒是内部服务调用全掉链子。不是TTL太长,是运维同学把bind配置里的serial写成了20230910——比真实日期少一天,从中秋那天起,区域文件就再没同步过。监控屏右下角贴着块胶布,遮住一个闪烁的红色“—”符号,那是Zabbix agent失联的标志,贴胶布的是实习生小陈,她说“看着心慌”。我撕下来,胶面粘了层灰,底下漆皮都翘了。我也没重贴,就让它敞着。 机房断电没真来,但UPS蜂鸣器叫了三次,第一次是凌晨四点十七,声音短促;第二次在五点零二,持续六秒;第三次干脆哑了——电池老化报警停了。供电室王师傅拎着万用表晃进来,站我身后看了半天,说:“这玩意儿上次换电池还是你刚来那年吧?”我点头,他摇摇头走了,走前踢翻了半箱矿泉水,瓶身滚到我脚边,标签卷了边。没捡。 证书过期是早上八点才发现的。不是HTTPS,是主从复制用的SSL证书,自签的,三年前生成的,路径硬编码在my.cnf里。报错日志里就一行:SSL error: unable to get local issuer certificate。我搜了三分钟文档,才想起这事该问当年配证的老刘。他正送孩子上学,微信语音里听得到校门口喇叭声:“啊?那个证啊……我记得压根没部署到线上!怎么现在还能报错?”我没接话。后台grep出来的实际调用时间戳,是昨晚十一点四十六分,恰好是主库切从库那一秒。 被CC那波最安静。没流量峰,没SYN flood,就是一百多个IP轮着发INSERT,每条插三条记录,字段全空,value写成'null'、'undefined'、' '。防火墙日志里它们跑得规规矩矩,间隔精确到毫秒。运维群里有人说“加个WAF规则呗”,我说“WAF还没连主库的授权账号”,然后群里沉默了十三分钟。十三分钟后,老板发了个截图:阿里云RDS的监控面板,CPU曲线平得像尺子量过——他截的是只读实例,而扛写压的是那台物理机。没人提醒他看哪台。 我盯着那台物理机top输出看了半宿,发现mysqld进程RSS涨得不对劲,但pmap里堆内存并不大。重启服务?先kill -15;等三秒;ps aux | grep mysqld还在;再kill -9;敲完回车手停了半拍——我忽然想起来,上个月给这台机子加过jemalloc,但启动脚本里LD_PRELOAD路径写错了,所以它其实一直在用系统malloc。可这个我到现在也没想明白:为什么用错了内存分配器,反而撑过了前二十小时? 九点半,小张递来一碗面,油花浮着,葱花蔫了。我吃了一口,想起中秋前两天搬家,把家里MySQL配置备份U盘塞进了儿童积木盒,结果孩子全倒进收纳箱底层,跟一堆齿轮混在一起。找U盘找了俩钟头,最后是从乐高小人偶裤兜里抠出来的——他拿它当飞盘玩过。面汤凉了,我搁下筷子。告警邮件开始一封封跳出来,不再是“disk full”,而是“replica IO thread stopped”,“Seconds_Behind_Master: NULL”,“SSL handshake error”。这些告警十年前我见过,五年前我改过,去年我以为彻底清干净了。结果它们蹲在代码缝里、日志死角里、同事忘了删的注释里,像蟑螂,只等灯一关,就爬满整个控制台。 下午一点,监控终于亮起真实的红光。不是误报,不是阈值漂移,是磁盘真的满了,InnoDB redo log轮转失败,连强制刷盘都卡死。我按了三下Ctrl+C终止一个无响应的show processlist,第四次才成功。这时候小陈抱着笔记本进来,屏幕朝向我,指着一段Ansible playbook:“老师,这儿写的template: my.cnf.j2,但库里没有这个文件……”我没看她,盯着自己终端里最后一行报错:[ERROR] InnoDB: Write to file ./ib_logfile0 failed at offset 0. 和上一次看到它,隔了整整七年。那年我刚转岗做文档,帮人写手册,手把手教怎么改log_file_size,结果教错了单位,把128M写成128,导致整套集群重建。现在我想起来,那会儿也没这么后怕。 明天先把告警阈值调了。调低十个百分点。不是因为更谨慎了,是今天看见小张手机锁屏壁纸——他女儿画的全家福,蜡笔涂得歪歪扭扭,爸爸头顶多画了三根头发,写在旁边:爸爸修电脑修到月亮回家啦。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


鸿蒙开发者必学:MySQL运维设计实战
MySQL高可用架构:6年域名运维实战容灾方案
6年MySQL运维实战:慢查询到毫秒响应
MySQL事务控制无障碍设计指南