Java Mybatis

SQL监控埋点

大部分性能问题都发生在存储层。当然对于优化需要有足够的样本,这些样本也就是慢SQL。数据库本身就有慢SQL的日志,但不方便跟具体的接口和trace进行关联。
如果要跟trace进行关联那么就必须自己进行埋点上报性能数据,之前用Cat做监控的时候,就是基于Mybatis的插件进行埋点,这样可以在Cat中看到每次请求下执行了哪些SQL,以及SQL的执行时间。

SQL校验

如果数据表做了水平拆分,也就是分库分表。当然有可能是用开源框架实现的,也有可能是自研的框架。对于SQL的写法没有过多要求,但是如果是分库分表,而查询语句中没有带分片的字段,这个时候一般都是会进行所有表的查询,然后合并结果返回。
假如想打破这个规则,查询的SQL中必须带分片的字段,否则就直接报错。当然可以对分库分表框架进行改造,如果是开源的改起来比较麻烦,那是否可以简单点实现呢?
可以的,答案就是用Mybatis插件进行扩展,拿到执行的SQL进行分析,然后做校验。

SQL改写

SQL改写相对来说用的比较少,主要是改写是个很危险的事情,稍有不慎,线上就要炸锅了。那么改写会有哪些场景下需要呢?
场景就是要一个新的分库分表的框架,老框架是支持分表场景下update分片字段的。比如user表的分片字段是id,那么update语句中可以带上这个id,只不过值还是原来的,不影响数据,这种也经常会在用一些自动生成SQL的场景下会有。
自从接了新框架后,对SQL更新有要求了,分片字段是不允许更新的,不能出现在update的SQL中,如果有就直接报错。所以这个时候改写SQL就排上用场了,当然为了稳定性,还是采用了最原始的方式,将所有SQL都改了一遍。

SQL中透传信息

SQL中透传信息这个很实用,问题在于透传的信息给谁使用呢?
其实这个要归根于有没有使用Proxy方式的分库分表中间件,如果有的话就需要透传信息。
比如读写分离场景,Proxy怎么知道SQL要走主库还是走从库呢?
比如在做压测的时候,Proxy怎么知道SQL要走正常库还是影子库呢?当然这个也可以把影子库控制放在客户端。
那么如何通过SQL进行信息透传呢?如下:

  1. /*master:true*/ SELECT * FROM table

其实就是在SQL的前面加一些特殊的信息,然后中间件去解析做对应的处理。