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/