因为我的一个低级错误,生产数据库崩溃了近半小时
共 3292字,需浏览 7分钟
· 2020-09-10
点击上方SQL数据库开发,关注获取SQL视频教程
SQL专栏
反常的SQL语句
某周四午休时分,我正在工位上小憩,睡梦中仿佛看到了自己拿着李白在荣耀峡谷里大杀四方的情景,就在我刚拿完五杀准备带领队友推对面水晶的时候,一句慌乱急促的“糟了”把我从睡梦中惊醒。
我眯开朦胧的双眼,才发现刚才的发声来源于我的组长庄哥,看到他在紧张的点开日志系统查看日志,我预感到有什么不妙的事情发生,仔细一问才知道,原来就在我眯眼的期间,线上数据库服务器的CPU被打满,同时触发了生产数据库只读延迟的限定时间并且发出告警,而且告警的过程持续了半个小时。
这让我倒吸了一口凉气,因为我们组做的系统很多都用的是同一个数据库服务器,日用户活跃量有好几十万,如果服务器崩溃了将会使所有的系统服务都不可用,于是我们赶紧通过SQL日志进行问题查找,最后排查出来是因为一张SQL的高量查询没有走索引导致,日志列表显示,这条sql语句的扫描行数达到了上百万,基本就是全表扫描的情况,而且半个小时的时间查询了达上万次,每条SQL查询的耗时都在3000ms以上。
我的天啊,难怪服务器会CPU打满,这么一条耗时的SQL语句查询量这么大,数据库的资源当然是直接就崩溃了,这是当时那条SQL的查询情况:
临时处理
看了这条语句,我又倒吸一口凉气,这不就是我写的系统调用的SQL语句吗?完了,这回逃不掉了,真是人在睡梦里,锅从天上来。
当然,因为是我自己写的SQL,所以我一看就知道这条语句是有问题的。
根据我的代码处理,这条sql的调用还少了个重要的参数user_fruit_id,这个参数没有传的话是不应该走这条sql查询的,在我的设计里,该参数是数据表里一个联合索引的最左侧字段,如果该字段没有传值的话,那么索引就不会生效了。
虽然定位到了SQL语句,但是线上的问题刻不容缓,总不可能找出bug改完再上线吧,所以,我们只能做了一个临时处理,就是在原来的表上多加了一个联合索引,其实就是去掉了user_fruit_id 字段,让这些高量的查询都能走新的索引,就像下面这样
最左匹配原则
找出Bug
总结
——End——
后台回复关键字:1024,获取一份精心整理的技术干货 后台回复关键字:进群,带你进入高手如云的交流群。 推荐阅读 这是一个能学到技术的公众号,欢迎关注