前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高并发下 MySQL Statement Cancellation Timer 的线程数暴涨

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

作者头像
没有故事的陈师傅
发布2023-09-06 15:25:22
2970
发布2023-09-06 15:25:22
举报
文章被收录于专栏:运维开发故事运维开发故事

问题描述

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

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

依赖信息:

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

环境配置信息

  1. druid 配置,全部都是默认值
  2. mybatis 配置:
代码语言:javascript
复制
@Bean
public 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. 引用关系如下

image.png

  1. 什么时候启动 enableQueryTimeouts = true

image.png

  1. 默认值是 true

image.png

  1. startQueryTime 的调用方 StatementImpl 的 executeQuery

image.png

  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 参数

image.png

  1. 如果这些都去掉可以通过 mysql 服务端 collection timeout 配置处理
    • mysql 服务器会有一个参数 wait_timeout:mysql server 关闭连接之前,允许连接闲置多少秒。默认是 28800,单位秒,即 8 个小时。
代码语言:javascript
复制
# 分别查看全局、会话变量值
show global VARIABLES like '%timeout%';
show  VARIABLES like '%timeout%';

image.png

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

image.png

复现和修复

测试代码

  • 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
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维开发故事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述
  • 环境配置信息
  • 发生过程分析
  • 处理方案
  • 复现和修复
  • 参考资料
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档