一、背景

上周承接了一个新需求需要为券打标签,此处不关注业务背景,只聚于技术业务流程:上游服务通过Kafka下发标识,我们服务订阅kafka,kafka消费后对分片库(采用mycat实现分库,目前有128个分片,通过user_id作为分片路由键)中的xx表tag字段(新增字段:tag)进行更新。在周四正式发版之前,周三晚上通过onlineDDL完成对分片库加字段。

二、现象1、周四晚上

周四晚上10点切完流量一会后,异常日志告警就出来了:

file

这个是老代码根本没动过,去年也出现过这个相同的这个问题,当时只出现了一会大概3分钟后就消失了(联系运维观察估计是网络抖动造成的),于是决定进一步观察。

file

后续又陆续出现告警:Got packets out of order,Communications link failure,立马联系DBA检查分片库,得到的回复是数据库目前都正常,无异常。后续连这个分片库的服务也开始告警,立马进一步向上级leader请示。经商讨后:决定将连接这个分片库所有服务串行重启。晚上流量相对较少,后面偶尔报一次。

2、周五

第二天早上9点随着流量增加告警频繁出现,游走在UIOC事件的边缘,非常危险,立即拉mycat中间件维护人员、DBA等人员一起分析。将当前版本的改动:新增字段和更新sql语句发给中间件相关同事(目前Kafka每批最多消费20条数据,于是决定采用批量更新的方式提升效率)。

file

经分析未找到出现问题的原因,无奈之下准备回退版本(不再消费kafka,让kafka先积压,同时不再读取),并于13:00发布到生产,发布完后无告警。

在生产回滚后继续分析,大家都怀疑是批量更新导致的问题,于是准备晚上尝试验证一下:新增单个更新sql,通过动态开关走批量更新单个更新。

晚上先打开kafka消费开关,开启单条更新sql开关,更新tag和读取tag都正常,无告警,至此实锤是因Mycat批量更新导致的问题。

_发现批量异常应怎么处理_批量错误改善方法

三、问题分析1、rewriteBatchedStatements

先明确jdbc驱动(5.1.13版本以上才生效)中rewriteBatchedStatements含义,重写批量sql比如update语句:update t set … where id = 1; update t set … where id = 2; update t set … where id = 3,会将多条语句组成一条语句提交给mysql。

2、mycat为什么不支持

上github上查看有没有类似问题,在mycat源码中的issues直接输入关键字rewriteBatchedStatements:

file

可以看到在2020年6月17合入以下分支:https//MyCATApache/Mycat-Server/tree/Mycat-server-1.6.76-test,以下是mycat版本发布时间线:

在这里插入图片描述

查看当前使用的版本未1.5.1,当然不支持批量重写后的update语句,进而导致乱包,mycat出现乱序进一步影响这分片库的其他业务。

四、解决及总结

基于以上分析得出结论:mycat版本较低无法支持批量update,提交批量update语句致Mycat乱报,进而引发一系列问题。针对以上问题,给出以下解决方案:

1、规避业务写批量更新语句;

2、中间件升级mycat版本,但目前有很多定制化开发,中间件不是太愿意升级。

3、换成其他中间件比如shardingjdbc;

短期按方案1执行,目前分片库存量数据量达到将近百亿,明年逐步完成去Mycat。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。