MySQL Aborted connection分析

文章描述了一次在线上日志巡查中发现的应用程序无法获取JDBC连接的问题,具体表现为事务不能回滚,错误信息显示连接已被关闭。通过对监控、数据库日志的分析以及查阅MySQL文档,了解到可能的原因包括连接超时、权限问题、网络问题等。尽管Aborted_connections和Aborted_clients难以完全避免,但可以通过优化参数配置如调整max_allowed_packet和timeout来减少影响,并要求应用程序具备一定的容错处理能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题背景

        最近在线上的日志巡查中,发现了如下的异常日志,应用程序不能获取JDBC连接,连接被关闭。

Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not roll back JDBC transaction; nested exception is java.sql.SQLException: Connection is closed。

紧随其后,系统里日志记录信息如下:

Could not roll back JDBC transaction; nested exception is java.sql.SQLException: 
Connection is closed - org.springframework.transaction.TransactionSystemException: Could not roll back JDBC transaction; 
nested exception is java.sql.SQLException: Connection is closed
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doRollback(DataSourceTransactionManager.java:350)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:835)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:809)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:649)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:370)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
 

        数据库连接关闭,事务还不能回滚,这是一个比较严重的问题。我们的MySQL是5.7版本,隔离级别是RR,数据库引擎是Innodb。所以当下就抓紧去排查该问题发生的根因,避免发生线上事故。

二、根因分析

        查看了应用的监控,从监控上看系统表现正常,无异常信息,联系DBA,反馈数据库也正常;从数据库的日志中得到了下面的日志信息。

        [Note] Aborted connection 11078996 to db: '数据库名' user: '用户' host: '数据库IP' (Got an error writing communication packets)

       上述日志信息中,Aborted connection 关键字到MySQL的文档中查询可知,造成Aborted_connects状态变量增加的可能原因:

  1. 没有数据库的权限;
  2. 使用了错误的密码。
  3. 连接包不包含正确的信息。
  4. 获取一个连接包需要的时间超过connect_timeout秒。

同时,文档中紧接着还介绍了Aborted clients出现时可能的原因:

  1. 客户端程序在退出时没有调用mysql_close()方法;
  2. 客户端已休眠超过wait_timeout或interactive_timeout秒,而没有向服务器发出任何请求;
  3. 客户端程序突然终止了传输中的数据;

导致Aborted connections或Aborted clients问题的其他原因:

  1. max_allowed_packet变量值太小,或者查询需要的内存比为mysqld分配的内存多;
  2. 客户端和服务器之间的网络原因导致;
  3. 线程库出现问题,导致读取中断;
  4. TCP/IP配置错误;
  5. 各种硬件故障,需要对硬件进行更换;

        综上来说,Aborted connections和Aborted clients是不太可能完全避免的,在MySQL的日志里或多或少都会有一些,这需要我们程序有这种容错处理能力。

三、参数配置

        为了验证“Aborted connections和Aborted clients是不太可能完全避免”这一结论,对线上的数据进行查询统计以便证实该结论。

1、SHOW GLOBAL STATUS LIKE '%abort%';

这是线上数据库累计的这2个异常的数值,说明该问题并不是第一次出现,只不过可能之前出现时业务无感知或是没有影响到业务;

2、 SHOW VARIABLES LIKE '%max_allowed_packet%';

目前是系统默认值1G,当进行修改超过1G时,数据库重启将恢复至默认值1G;

3、  SHOW VARIABLES LIKE '%timeout%';

        在这组参数中,重点关注标红的几个参数,这几个参数与我们本次排查的问题相关性较高,这几个参数标识了连接超时的问题;连接在服务器端可能已超时,但在客户端的连接池里并不是马上失效导致了连接断开而事务还不能回滚的情况。

        综上分析,数据库出现连接问题的情况是比较难完全避免的,需要我们的应用程序有容错性来处理这类问题。

附MySQL官方文档针对该问题的阐述:

MySQL :: MySQL 5.7 Reference Manual :: B.3.2.9 Communication Errors and Aborted Connections

### 解决 MySQL 数据库连接中断问题 当遇到 `MySQL Aborted connection` 错误并提示 `got an error reading communication packets` 时,这通常意味着客户端与服务器之间的通信出现问题。为了有效解决问题,可以从以下几个方面入手: #### 调整超时参数配置 增加 MySQL 的超时时间可以减少因网络延迟或其他原因导致的连接中断情况。可以通过修改 my.cnf 文件中的以下参数来实现这一目标[^1]: ```ini wait_timeout=28800 interactive_timeout=28800 ``` 这些设置将等待超时的时间延长到了 8 小时。 #### 增大最大允许包大小 如果传输的数据量较大,则可能是因为数据包超过了默认的最大尺寸限制而被丢弃。适当增大 max_allowed_packet 参数可以帮助处理更大的查询结果集或批量操作: ```ini max_allowed_packet=64M ``` 此调整同样应在 my.cnf 中完成,并重启服务使更改生效。 #### 启用警告显示功能 对于希望进一步了解具体错误信息的情况,可利用 mysqladmin 工具启用显示警告的功能。通过命令行执行如下指令能够查看由语句执行产生的警告信息[^2]: ```bash mysqladmin --show-warnings processlist ``` 该方法有助于诊断潜在的问题根源所在。 #### 定期维护和优化表结构 定期运行 OPTIMIZE TABLE 和 ANALYZE TABLE 可以帮助保持良好的性能状态,防止由于索引碎片化等原因造成的异常断开现象发生。 以上措施综合运用后应该能显著改善数据库连接稳定性问题。值得注意的是,在高版本 MySQL 中,曾经有效的某些自动重连机制已不再适用,因此建议按照上述方案进行排查和修复工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值