mysql鏈接不釋放

環境:mysql

  持久層:JPAsql

  數據庫鏈接池:druid數據庫

  數據庫中間件:Mycatui

  數據庫:Mysql線程


報錯:orm

  Unable to acquire JDBC Connection中間件

 

排查步驟:blog

方法一:事務

  一、druid配置沒有問題。ssl

  二、Mysql鏈接數正常,可是發現mysql有不少連接沒有釋放。(用root用戶執行:show full processlist ; 指令)

    

 

     如圖:發現不少State = Sleep的連接,連接都很長,一直不釋放連接。

  三、kill掉相應的連接。(由於業務數據不是很重要,爲了先恢復功能,用此下策)

  四、接着排查代碼。發現JPA的save方法,默認更新一條記錄使用以下方式:update tb_name set xxx = xxx where id = xxx ; 使用默認的主鍵進行數據的更新。而業務側,因爲數據龐大使用了數據庫的分庫分表,mycat做爲數據庫中間件,該表的路由規則爲:根據用戶id去摸,進行數據的分庫分表。

  問題緣由找到:每次執行更新(save)方法時,Mycat都會廣播這條sql,當數在插入時,就形成更新方法阻塞等待(鎖,事務相關),致使連接不釋放。

 

 方法二:

  一、查看mysql事務表,獲得thread_id :  select * from information_schema.INNODB_TRX ;  從結果中的:trx_mysql_thread_id 獲得線程id

  二、select * from performance_schema.threads where THREAD_ID = 第一步獲得的線程id (這一步能夠不執行,目的只是爲了演示mysql的線程管理,以及相應的查看方法。)

  三、select * from performance_schema.events_statements_current where THREAD_ID =  第一步獲得的線程id ;  根據 SQL_TEXT 獲得相應的sql語句。

  以上就是mysql經過阻塞的線程,找到代碼中相應的sql的方法。

 

 

解決方法:

  一、寫sql,在更新數據時,修改JPA默認的方式,使用路由規則去更新數據。

相關文章
相關標籤/搜索