一 背景
DBA团队成员从监控视图中发现,MySQL内存使用率超过95%,使用异常,所幸未影响业务。但众所周知,内存使用率过高可能会导致系统性能下降,甚至导致数据库服务崩溃。
监控视图如下:
二 排查分析
在数据库实时监控平台抓取会话,发现有2个异常连接,如下图所示:
是查询的SQL语句也无特别,只是统计单张表的条目数,该表的条目数达到亿级。
本以为是个简单的session的查询,由于统计的数据量很大,创建的临时表消耗的较多的内存,KILL掉当前的连接,就可以完美解决。之前在其他业务上也碰到过类似的问题。
但是KILL掉线程后,线程处于KILLED状态,并且资源并未释放。
首先来看看KILL不掉查询线程的原因:
① 线程没有执行到判断线程状态的逻辑;
② 终止逻辑耗时比较长。
耗时较长的几种情况?
① 超大事务执行期间被kill:回滚操作需要对事务期间生成的所有数据版本做回收操作,耗时比较长;
② 大查询过程中生成比较大的临时文件需要删除,如果OS系统压力很大,删除临时文件需要等待IO资源;
③ DDL执行阶段被kill:需要删除中间过程的临时文件,可能受IO资源影响耗时较久。
三 处理过程
知道原理和原因后,使用万能大法进程处理,在业务低峰对数据库集群实施主备切换,终于恢复正常状态。