追溯 MySQL Statement Cancellation Timer
1. 背景
在 jstack
的内容中可以看到以下的 MySQL Statement Cancellation Timer
守护线程, 在业务高峰期的时候会出现大量的这类守护线程, 由此追溯该线程的生命周期过程;
"MySQL Statement Cancellation Timer" #20647 daemon prio=5 os_prio=0 tid=0x00007f2d087e9800 nid=0xfb83 in Object.wait() [0x00007f2b4b45a000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000005da147038> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
Locked ownable synchronizers:
- None
"MySQL Statement Cancellation Timer" #24138 daemon prio=5 os_prio=0 tid=0x00007f402802c800 nid=0x4cf64 in Object.wait() [0x00007f3e49453000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at java.util.TimerThread.mainLoop(Timer.java:526)
- locked <0x00000005f606cc60> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
Locked ownable synchronizers:
- None
2. TimerThread
java.util.TimerThread
是 Timer.java
文件里的一个内部类, 主要负责 Timer
队列任务的执行和调度;
- 根据定位
Timer.java:526
位置的代码, 当前状态WAITING (on object monitor)
, 表示当前的timer
线程池为空, 正在等待新入驻; - 根据定位
Timer.java:552
位置的代码, 当前状态TIMED_WAITING (on object monitor)
表示任务等待被激活;
3. getCancelTimer
根据线程名称 MySQL Statement Cancellation Timer
继续追溯, 在 com.mysql.jdbc.ConnectionImpl#getCancelTimer
方法中找到该 TimerThread
的创建(cancelTimer
):
4. getCancelTimer 的上游调用
主要是 mysql-connector-java-xxx.jar
中负责 sql 查询的 Statement
5. 创建 CancelTask timeoutTask
在 com.mysql.jdbc.StatementImpl#executeQuery
方法中可以发现, 当启用 queryTimeout
且 timeoutInMillis!=0
时, 在执行 sql 的时候就会创建一个 CancelTask
的线程来控制超时; (后面那个 versionMeetsMinimum
是个版本判断可以先忽略)
然后在项目的 application.yml
中发现配置 mybatis.configuration.default-statement-timeout: 5
, 所以 mybatis
在每次的数据库查询都会加上 queryTimeout
, 且该配置对全局 SQL 生效, 包括 insert
, select
, update
;
6. CancelTask 执行过程
在 com.mysql.jdbc.StatementImpl.CancelTask#run
方法中, 会另起一个线程, 判断如果启用了 queryTimeoutKillsConnection
的配置时, 会调用当前 Statement
对应的 Connection
里的 realClose
方法;
在 realClose
方法里发现会关闭 cancelTimer
线程;
7. Connection 关闭时
在 com.mysql.jdbc.ConnectionImpl#close
方法里也会发现有 realClose
方法的调用, 即在连接关闭时也会处理 cancelTimer
的释放
8. 总结 MySQL Statement Cancellation Timer 线程的流程
设置了 queryTimeout
会使 jdbc driver
在每次查询数据库时新建 CancelTask
(timeoutTask
对象) 线程来处理超时, 并使用 CancelTimer
(在 ConnectionImpl
类中) 来进行调度;
如果 SQL
查询超时了, 则会在 timeoutTask
的 run
方法里调用 com.mysql.jdbc.ConnectionImpl#realClose
来释放 CancelTimer
;
如果 Connection
正常关闭 close
时, 也会调用 com.mysql.jdbc.ConnectionImpl#realClose
来释放 CancelTimer
;
9. 阅读资料
追溯 MySQL Statement Cancellation Timer的更多相关文章
- MYSQL Statement violates GTID consistency: Updates to non-transactional tables can only be done in either autocommitted statements or single-statement transactions, and never in the same statement as
[2019-04-21 10:17:20] [ERROR] [org.hibernate.engine.jdbc.spi.SqlExceptionHelper:144] Statement viola ...
- mysql Statement violates GTID consistency 的坑
今天项目迁移,重新换了一个数据库版本,然后问题来了,原本运行正常的程序迁移过来之后就是不能正常运行,后台报错如下: update tbl_user_info set -- 强制下架 mv_count ...
- MYSQL Statement violates GTID consistency: CREATE TABLE ... SELECT. 错误代码: 1786 问题
1.在MYSQL中,执行建表语句时CREATE TABLE aaaa AS SELECT * FROM menu; 报: 错误代码: 1786Statement violates GTID co ...
- MySQL Fabric和MyBatis的整合过程中遇到的问题
这是我昨天在整合MySQL Fabric和MyBatis时遇到的问题,花了大半天才解决的问题,解决的过程中在网上查找了很久,都没有找到解决的方案.现在记下来,希望能够帮助有同样问题的朋友.如果各位朋友 ...
- registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped.
最近在用maven整合SSH做个人主页时候,在eclipse里面使用tomcat7插件发布项目是没有问题的,但当打包成war之后,使用tomcat7单独发布项目,就出现了以下的错误. 严重: Cont ...
- jstack工具查看系统线程问题
背景: 最近在做项目系统的异常测试,项目依赖于nkv,需要模拟依赖组件nkv异常时系统的响应及性能情况.通过tc工具模拟当服务器发送到nkv的请求超时时系统的响应.发现接口返回错误率100%,查看服务 ...
- JDBC驱动自身问题引发的FullGC
公众号HelloJava刊出一篇<MySQL Statement cancellation timer 故障排查分享>,作者的某服务的线上机器报 502(502是 nginx 做后端健康检 ...
- Tomcat6.0的Thisisverylikelytocreateamemoryleak异常
從Apache Tomcat 5.5升級到6.0,通常不用太大的修改,原有的Web Application就能繼續運作.不過在server.xml中設定MySQL Datasource,卻出現一串惱人 ...
- Tomcat常见内存溢出的解决办法
PermGen space错误解决方法 在看下文之前,首先要确认意见事情,就是你是如何启动tomcat的,我们在平时的开发环境当中,都是通过startup.bat方式启动tomcat的,那么你按照下面 ...
随机推荐
- 洛谷 P2391.白雪皑皑 (并查集,思维)
题意:有\(n\)个点,对这些点进行\(m\)次染色,第\(i\)次染色会把区间\((i*p+q)\ mod\ N+1\)和\((i*q+p)\ mod\ N+1\)之间的点染成颜色\(i\),问最后 ...
- 2015ACM/ICPC亚洲区沈阳站-重现赛 D - Pagodas
题意:有\(n\)个数,开始给你两个数\(a\)和\(b\),每次找一个没出现过的数\(i\),要求满足\(i=j+k\)或\(i=j-k\),当某个人没有数可以选的时候判他输,问谁赢. 题解:对于\ ...
- 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)
题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...
- 【cpp上】课后正误小题
State whether each of the following is true or false. If false, explain why. Assume the state ment u ...
- windows下的PyCharm设置注释字体的斜体
操作截图如下:File --> Settings --> Editor --> Color Scheme --> Language Defaults --> Commen ...
- 牛客网多校第7场 J Sudoku Subrectangles 【构造】
题目:戳这里 题意:给一个n*m的矩阵,里面由a~z及A~Z构成,问有多少个子矩阵满足任意一行或一列中都没有相同的字母. 解题思路:左上角和右下角两点可以确定一个矩阵.可以先预处理出来每个点作为一个矩 ...
- zoj-3870 (二进制)
For an upcoming programming contest, Edward, the headmaster of Marjar University, is forming a two-m ...
- Win7环境下mysql报错1045:Access denied for user root@localhost错误解决方法
产生场景:在涉及到连接数据库操作的时候,会报1045:Access denied for user root@localhost. 比如:本地建立的数据库连接不上,在IDEA等开发工具中使用反向生成. ...
- 北京网络赛G BOXES 大模拟+BFS
题目描述 Description There is a strange storehouse in PKU. In this storehouse there are n slots for boxe ...
- 浅谈WEB前端规范化标准之ESlint
规范化标准 软件开发需要多人开发,不同的开发者具有不同的编码习惯和喜好,不同的喜好增加项目的维护成本,所以需要明确统一的标准,决定 了项目的可维护性,人为的约定不可靠,所以需要专门的工具进行约束,并且 ...