mycat自動重啓解決辦法

前言

mycat是一個很是著名的分庫分表中間件,可是不少使用過這個中間件的人都會遇到一個共通的問題,那就是mycat的進程老是會重啓,同時重啓的時候應用的代碼裏面也會報出 Java.lang.NullPoint_er_Exception , 今天就來分析一下這個問題,以及解決辦法!java

原理

這個mycat的重啓問題可能一部分人遇到了,一部分人沒有遇到過,這是爲何呢?               node

實際上這段mycat的bug代碼是出如今了跨庫結果集合並後,釋放堆外內存的代碼上面         

有一部分有經驗的人知道分庫分表中間件是不太適用於跨庫查詢的,這些有經驗的人會讓業務代碼去一個一個庫查出數據庫後,讓業務代碼本身去作數據合併,排序的邏輯,若是是這樣的話就完美避開了這個問題。sql

好比我用mycat的註解數據庫

/*#mycat: datanode=dn1*/select * from ljj_table/*#mycat: datanode=dn2*/select * from ljj_table

這樣就強行指定了datanode的節點,就算我sql裏面沒有分庫字段也能夠去這個庫裏面查出數據。而後在業務裏面把select出來的結果進行合併app

可是對於不少中小型的公司來講,由於經驗不足,以及代碼的快速迭代,是容許mycat跨庫查詢的,這就致使了mycat內部須要作排序,這樣作的話就有概率觸發堆外內存重複釋放的bug致使重啓。運維

好比我直接執行ide

select * from ljj_table

這樣的sql,mycat內部就會進行匯聚以及排序,就會致使空指針。spa

代碼REVIEW以及修改方法

這個問題的代碼主要問題就是出在了 MultiNodeQueryHandler.net

這個類上面,在這個類裏面,有幾個釋放資源的類須要作出修改。指針

在方法 outputMergeResult(這個類裏面有2個outputMergeResult,都要改!)

裏面,咱們須要調整釋解鎖與釋放堆外內存的順尋

原先是

lock.unlock();dataMergeSvr.clear();

如今咱們須要改爲

dataMergeSvr.clear();lock.unlock();

以及在這個類的clearResources方法裏面,咱們須要加上鎖

原先是

if(dataMergeSvr!=null){

    dataMergeSvr.clear();

}

如今改爲

lock.lock();try{if(dataMergeSvr!=null){

    dataMergeSvr.clear();

}

}finally{lock.unlock();

}

這樣改完後,咱們就保證了dataMergeSvr.clear()這個方法的原子性。鄭州好的不孕不育醫院是哪家:http://jbk.39.net/yiyuanfengcai/tsyl_zztjyy/989/

還有在AbstractConnection這個類上面的cleanup方法上面加上sync的鎖,這樣mycat的重啓問題就完全修復了。

若是不修改源碼從新打包?有什麼簡單的方法能夠直接改掉這個類嗎?(針對dba和運維)

答案是能夠的!我知道不少公司維護mycat的都是dba和運維,這裏能夠利用mycat自帶的wrapper功能(加載外部jar包)來進行直接修復

我把我改完的這2個類的jar(僅針對mycat1.6版本)已經上傳到了網盤

連接:https://pan.baidu.com/s/1coay5H-QE7ED26UWuKsL5g 
提取碼:ygad

把個人這個jar包mycatExtend.jar放到mycat的lib目錄下

好比\Mycat-server-1.6\mycat\lib下面

而後在conf文件裏面的wrapper.conf這個文件裏面設置地址

\# Java Classpath (include wrapper.jar)  Add class path elements as  \#  needed starting from 1  wrapper.java.classpath.1=lib/mycatExtend.jar
wrapper.java.classpath.2=lib/wrapper.jar  
wrapper.java.classpath.3=conf  
wrapper.java.classpath.4=%REPO_DIR%

鄭州不孕不育:http://www.ytsg120.cn/

相關文章
相關標籤/搜索