mysql连接不释放
环境:
持久层:JPA
数据库连接池:druid
数据库中间件:Mycat
数据库:Mysql
报错:
Unable to acquire JDBC Connection
排查步骤:
方法一:
1、druid配置没有问题。
2、Mysql连接数正常,但是发现mysql有很多链接没有释放。(用root用户执行:show full processlist ; 指令)
如图:发现很多State = Sleep的链接,链接都很长,一直不释放链接。
3、kill掉相应的链接。(因为业务数据不是很重要,为了先恢复功能,用此下策)
4、接着排查代码。发现JPA的save方法,默认更新一条记录使用如下方式:update tb_name set xxx = xxx where id = xxx ; 使用默认的主键进行数据的更新。而业务侧,由于数据庞大使用了数据库的分库分表,mycat作为数据库中间件,该表的路由规则为:根据用户id去摸,进行数据的分库分表。
问题原因找到:每次执行更新(save)方法时,Mycat都会广播这条sql,当数在插入时,就造成更新方法阻塞等待(锁,事务相关),导致链接不释放。
方法二:
1、查看mysql事务表,得到thread_id : select * from information_schema.INNODB_TRX ; 从结果中的:trx_mysql_thread_id 得到线程id
2、select * from performance_schema.threads where THREAD_ID = 第一步得到的线程id (这一步可以不执行,目的只是为了演示mysql的线程管理,以及相应的查看方法。)
3、select * from performance_schema.events_statements_current where THREAD_ID = 第一步得到的线程id ; 根据 SQL_TEXT 得到相应的sql语句。
以上就是mysql通过阻塞的线程,找到代码中相应的sql的方法。
解决方法:
1、写sql,在更新数据时,修改JPA默认的方式,使用路由规则去更新数据。