mycat是一個很是著名的分庫分表中間件,可是不少使用過這個中間件的人都會遇到一個共通的問題,那就是mycat的進程老是會重啓,同時重啓的時候應用的代碼裏面也會報出 Java.lang.NullPoint_er_Exception , 今天就來分析一下這個問題,以及解決辦法!java
這個mycat的重啓問題可能一部分人遇到了,一部分人沒有遇到過,這是爲何呢? node
有一部分有經驗的人知道分庫分表中間件是不太適用於跨庫查詢的,這些有經驗的人會讓業務代碼去一個一個庫查出數據庫後,讓業務代碼本身去作數據合併,排序的邏輯,若是是這樣的話就完美避開了這個問題。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
這個問題的代碼主要問題就是出在了 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的重啓問題就完全修復了。
答案是能夠的!我知道不少公司維護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/