追溯 MySQL Statement Cancellation Timer
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了追溯 MySQL Statement Cancellation Timer,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2974字,纯文字阅读大概需要5分钟。
内容图文
![追溯 MySQL Statement Cancellation Timer](/upload/InfoBanner/zyjiaocheng/863/62e71343d6e441c097a99f36a143f001.jpg)
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 Cancellation Timer所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。