Mycat适配oracle,各种坑

注:文中使用版本为Mycat 1.6.5。

1、Mycat

正如官方所说,

Mycat 是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。由于前面讲的对数据进行分片处理之后,从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储。 当然,Mycat没有自己的存储引擎,并不是完全意义的分布式数据库系统。

 以下是官方的架构图。

我们可以清晰地看到MyCat的核心是“拦截sql并做解析、路由,结果集合并”。

但是,也如官方所设计的

Mycat 就是MySQL 最佳伴侣,它在一定程度上让MySQL 拥有了能跟Oracle PK 的能力。

MyCat的基因从Cobar开始,就是为MySQL为设计的。当你使用oracle作为物理库的时候,就会出现各种问题。

2、SQL解析问题

不论原有Mycat不支持的SQL语句,但oracle语法就很多不兼容,甚至无法正常运行。如insert into .... select ...语句不支持;blob大字段的insert/update在oracle环境有问题;不支持start with ... connect by....递归树语句;

如果你的系统有这些,要么在应用端改写掉,要么请放弃使用Mycat。

3、select count(1) from xxxx

默认查询,如果是多分片,这个结果会返回多条记录,每天记录是单一个分片的执行结果。

如果需要Mycat合并结果集,需要修改server.xml 的属性 :

useOffHeapForMerge=0

另,如果schema设置了sqlMaxLimit,而物理库中结果记录远大于此值,那么你查询的结果会总是不超过sqlMaxLimit。这是一个BUG。

4、Mybatis的批量insert/update

如果你的系统有mybatis对于Oracle环境下进行批量的insert或者update,那么对不起。

Mycat 不能很好识别和解析begin ... insert.... end 语句。

5、调用存储过程

恩,你没看错,不支持CallableStatement方式调用存过。得换Mycat自己的写法,而且还有限制。

// create or replace procedure p_test(return_result out varchar,--返回结果,如果没有费用返回空字符串
      // err_code out number,--异常编码
      // err_msg out varchar,--异常消息
      // p_order_item_id in varchar, --订单标识
      // p_prod_offer_id in number
      // ) as
      // begin
      // err_code:='0';
      // err_msg:='';
      //
      // return_result:=0;
      //
      // exception
      // when dup_val_on_index then
      // err_code:= sqlcode;
      // err_msg:=sqlerrm;
      // when others then
      // err_code:=sqlcode;
      // err_msg:=sqlerrm;
      // end p_test;

      String sql =
          "/*#mycat: sql=SELECT 1 FROM customer_order where cust_id='90000000000' */set @p_order_item_id='',@p_prod_offer_id=0; call p_test (@return_result,@err_code,@err_msg,@p_order_item_id,@p_prod_offer_id);select @return_result,@err_code,@err_msg";

      ps = conn.prepareStatement(sql);
      ps.executeUpdate(); 
      rs = ps.getResultSet();
      if (rs != null) {
        while (rs.next()) {
          String returnVal = rs.getString(1);
          Integer returnVal2 = rs.getInt(2);
          String returnVal3= rs.getString(3);
          System.out.println(returnVal);
          System.out.println(returnVal2);
          System.out.println(returnVal3);
        }
      }

6、分页排序有问题

如果你的数据足够多,你会发现oracle环境下采用rownum分页排序查询的结果,会同一页的结果每一次都可能不一样。

这是因为Mycat内部结果集合并逻辑的原因。需要换成limit形式。

7、内存飙升导致假死问题

嗯。这个是在1.6.5增加子查询后衍生的重大故障BUG。

采用单元测试 MycatSchemaStatVisitorTest.test5() 测试8层以上嵌套的sql,在本案例没提交前,发现mycat单机内存急剧飙升到700MB。 子查询达到14万之多。修正子查询逻辑后,条件组合仍达到33万之多。太恐怖了。

更详细请参见我的Pull requests:

https://github.com/MyCATApache/Mycat-Server/pull/1722

8、感言

Mycat是一个优秀的数据库分库分表中间件,但也正如其标榜和隐喻的,它很好地为MySQL为工作。

如果你需要Oracle分库分表,那么需要做大量的SQL检测,及相应的性能测试,才能启用Mycat。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博客

MVC项目开发中那些用到的知识点(Asp.Net Mvc3.0 Areas)

   我们知道MVC项目各部分职责比较清晰,相比较ASP.NET Webform而言,MVC项目的业务逻辑和页面展现较好地分离开来,这样的做法有许多优点,比如可...

15510
来自专栏jessetalks

bootstrap + requireJS+ director+ knockout + web API = 一个时髦的单页程序

也许单页程序(Single Page Application)并不是什么时髦的玩意,像Gmail在很早之前就已经在使用这种模式。通常的说法是它通过避免页面刷新...

33650
来自专栏漏斗社区

代码审计| 从今天起,做一个精致的多米咖!

0x00 背景 在看CNVD漏洞库的时候发现有师傅发了某cms前台SQL注入漏洞,通过查阅漏洞描述可知道存在问题的参数是cardpwd,便开始尝试对该版本的c...

37380
来自专栏JackieZheng

RabbitMQ入门-高效的Work模式

扛不住的Hello World模式 上篇《RabbitMQ入门-从HelloWorld开始》介绍了RabbitMQ中最基本的Hello World模型。正如其名...

24060
来自专栏智能计算时代

「大数据系列」:Apache zeppelin 多目标笔记本

Apache Zeppelin解释器概念允许将任何语言/数据处理后端插入Zeppelin。 目前Apache Zeppelin支持许多解释器,如Apache S...

30330
来自专栏牛客网

美团Android三面面试经历

之前在阿里实习,回来后只参加了美团的面试。最后有幸拿到了阿里的转正offer和点评平台的offer。这里简单地把我在美团面试过程中记录的一些问题分享一下,总体来...

52760
来自专栏python爬虫实战之路

Python爬虫-百度模拟登录(二)

参数值都看到了,token、tt、dv、callback这些变化的参数我们都知道了吧,其他的参数固定,别问我为什么。这个logincheck注意到了吗?是不是有...

19230
来自专栏NetCore

微信快速开发框架(四)-- 体验微信公众平台快速开发框架

今天上午想着用那个框架来快速建立一个测试,用着用着,发觉了些bug,赶紧修复了下,目前已经更新到github上。 接下来,我们的快速开发,首先您要建立一个公众账...

25880
来自专栏数据之美

Hive Lock 那些事儿

0、背景 最近两天数据仓库中一张核心表遭遇了锁的问题,导致数据插入失败,影响挺大,之前一直没注意到这个问题,借此总结一下这块的知识和遇到的坑。 hive 在 0...

50450
来自专栏程序你好

使用Java Streams(流)查询数据库

在本文中,您将了解如何编写纯Java应用程序,这些应用程序能够使用来自现有数据库的数据,而无需编写一行SQL(或类似的语言,如HQL),也无需花费大量时间将所有...

13420

扫码关注云+社区

领取腾讯云代金券