书山有路勤为径,学海无涯苦作舟
说到mysql,不提版本号就是耍无赖,所以先贴一下本文mysql版本:
mysql Ver 14.14 Distrib 5.7.31
最近项目开发的时候使用了一个定时任务,一个线程开启一个事务,且事务内处理逻辑较多,比较耗时,最终在进行事务提交时报链接丢失异常。
报错信息如下:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 337,576 milliseconds ago. The last packet sent successfully to the server was 1 milliseconds ago.
从服务器成功接收到的最后一个数据包是337576毫秒前,这意味着后面的数据包就不会接收,此时链接已经丢失。
经查阅资料显示,db有自己的僵尸♀️♂️资源保护机制,为了防止链接长时间被无效资源占用,db开启了最长等待时间,若一次请求时间大于此等待时间,则db会自动中断本地请求。
知道问题所在后就好处理了,我们只需要将等待时间延长至合理范围即可。那么什么是合理范围呢?
以mysql为例,查看超时时间配置
show global variables like '%timeout%';
变量名称 | 值 |
---|---|
connect_timeout | 10 |
delayed_insert_timeout | 300 |
have_statement_timeout | YES |
innodb_flush_log_at_timeout | 1 |
innodb_lock_wait_timeout | 50 |
innodb_rollback_on_timeout | OFF |
interactive_timeout | 28800 |
lock_wait_timeout | 31536000 |
net_read_timeout | 30 |
net_write_timeout | 60 |
rpl_stop_slave_timeout | 31536000 |
slave_net_timeout | 60 |
wait_timeout | 300 |
当前配置的等待时间为300s,确实小于我程序的运行时间,为此可以调高等待时间。现在我们将等待时间设置至8h
set global wait_timeout=28800;
set global interactive_timeout=28800;
(1)interactive_timeout: 服务器关闭交互式连接前等待活动的秒数
(2)wait_timeout: 服务器关闭非交互连接之前等待活动的秒数。
两者生效取决于:客户端是交互或者非交互的连接。
在交互模式下,interactive_timeout才生效;非交互模式下,wait_timeout生效。