当前位置:首页 >焦点 >高并发下 MySQL Statement Cancellation Timer 的线程数暴涨 允许连接闲置多少秒

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨 允许连接闲置多少秒

2024-06-26 02:01:48 [百科] 来源:避面尹邢网

高并发下 MySQL Statement Cancellation Timer 的高并线程数暴涨

作者:老郑 数据库 MySQL 线上业务高峰期 CPU 飙升,抓取 thread dump 发现 MySQL Statement Cancellation Timer 的发下线程数比较多,接收到线上预警,线程分析一下原因。数暴

问题描述

线上业务高峰期 CPU 飙升,高并抓取 thread dump 发现 MySQL Statement Cancellation Timer 的发下线程数比较多,接收到线上预警,线程分析一下原因。数暴业务高峰:

图片图片

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨 允许连接闲置多少秒

下面是高并一些可能相关的信息( mysql 驱动,db 连接池,发下orm 框架)

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨 允许连接闲置多少秒

依赖信息:

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨 允许连接闲置多少秒

  1. mysql-jdbc 8.0.24
  2. druid 1.2.8
  3. mybatis 线程3.4.6

环境配置信息

  1. druid 配置,全部都是数暴默认值
  2. mybatis 配置:
@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {     SqlSessionFactoryBean factory = new SqlSessionFactoryBean();    factory.setVfs(SpringBootVFS.class);    factory.setDataSource(dataSource);    //todo 省略其他配置    Configuration c = new Configuration();    c.setLogImpl(StdOutImpl.class);    c.setDefaultStatementTimeout(25000);    factory.setConfiguration(c);    return factory.getObject();}

发生过程分析

  1. 找到该线程的创建的地方 NativeSession

图片图片

  1. 引用关系如下

图片图片

  1. 什么时候启动 enableQueryTimeouts = true

图片图片

  1. 默认值是 true

图片图片

  1. startQueryTime 的调用方 StatementImpl 的 executeQuery

图片图片

  1. 可以发现 timeOutInMillis 不为 0 的情况下,并且 enableQueryTimeouts = true 就会创建 CanalQueryTask 然后如果超时就会自动调度

方法调用如下:com.mysql.cj.CancelQueryTaskImpl#run

图片图片

处理方案

  1. 项目使用的高并是使用 alibaba druid

图片图片

参考:https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8调用的是 setQueryTimeOut 方法,然后传给 timeOutInMills

图片图片

如果需要取消 CancelQueryTask 需要将 validationQueryTimeout 设置为 0

  1. 并且去掉 mybatis 发下defalutStatemnetTimeOut 参数

图片图片

  1. 如果这些都去掉可以通过 mysql  服务端 collection timeout 配置处理

mysql 服务器会有一个参数 wait_timeout:mysql server 关闭连接之前,允许连接闲置多少秒。线程默认是 28800,单位秒,即 8 个小时。

# 分别查看全局、会话变量值show global VARIABLES like '%timeout%';show  VARIABLES like '%timeout%';

图片图片

  • druid 可以通过 testOnBorrow 和 testOnReturn、testWhileIdle分别在链接获取,链接归还的时候判断是否有效。

图片图片

复现和修复

测试代码

  • PushCallbackService.java
  • CallbackLog.java
  • DBTimerController.java
  • MccClient.java

修复效果

现象 MySQL Statement Cancellation Timer的线程不再产生

图片图片

thread dump 分析工具地址:https://fastthread.io/

参考资料

  • https://segmentfault.com/a/1190000020162800
  • https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_wait_timeout
责任编辑:武晓燕 来源: 运维开发故事 CPUMySQL线程

(责任编辑:综合)

    推荐文章
    热点阅读