作者:肖亚洲
爱可生 DBA 团队成员,负责项目中数据库故障与平台问题解决,对数据库高可用与分布式技术情有独钟。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
背景介绍
客户环境近期出现了几次问题,经过讨论后决定进行架构变更,要将 mycat 迁移到 dble 。要求是:最小变动。
问题整理
结合客户情况与要求罗列了下需要考虑的事情:
- 参数设置
- 分片函数
- 数据节点的数据
- 业务SQL
问题处理
1、参数设置
mycat 端参数如下:
<system><property name="defaultSqlParser">druidparser</property><property name="processors">4</property><property name="processorBufferPool">20480000</property><property name="processorBufferLocalPercent">100</property><property name="frontSocketSoRcvbuf">10485760</property><property name="frontSocketSoSndbuf">41943040</property><property name="frontSocketNoDelay">1</property><property name="backSocketSoRcvbuf">41943040</property><property name="backSocketSoSndbuf">10485760</property><property name="backSocketNoDelay">1</property><property name="maxPacketSize">2048576000</property><property name="memoryPageSize">100m</property></system>
针对该参数 DBLE 侧建议如下:
- defaultSqlParser 、memoryPageSize 、processorBufferLocalPercent 已于 dble 中被废弃,可不必配置
- processorBufferPool 参数名变更为 bufferPoolPageSize
- 其他的参数在 dble 中可在 server.xml 中与 mycat 保持一致配置信息,部分参数信息详情可见:https://github.com/actiontech/dble-docs-cn/blob/2.19.11.0/tag/1.config_file/1.03_server.xml.md
注意:mycat 和 dble 的内存管理配置有较大不同。比如:没有 threadlocal 概念。建议阅读以下文档:https://actiontech.github.io/dble-docs-cn/2.Function/2.07_memory_manager.html
2、分片函数
查看 mycat 分片规则:
<function name="mod-long" class="io.mycat.route.function.PartitionByMod"><!-- how many data nodes --> <property name="count">8</property> </function>
直接采用 DBLE 的 hash 算法测试发现部分数据查询报错:
查看表内数据情况:
样例数据:20210810143211157000000000036
字段:user_code为varchar(32)
查看 mycat 环境分片规则:采用的分片算法为 mod-long 。而 long 的取值范围是 -9223372036854774808~9223372036854774807 ,查询出错的 20210810143211157000000000036 超过了 long 的取值范围。所以可以得出 mycat 针对这一特殊情况做了特殊处理。
针对该情况 DBLE 侧建议如下:
1、建议分片算法换成 HashString
分片列值超过Long的最大值(9223372036854774807), 需要换成列为String型的分片算法;
注意:历史数据需要在更换完算法分片后重新导入
2、采用 DBLE 的自定义算法
引用mycat的PartitionByMod算法,加入[dble的自定义算法https://actiontech.github.io/dble-docs-cn/1.config_file/1.09_dble_route_function_spec.html?q=]中。
最终配置如下:
<function name="test_func" class="com.actiontech.dble.custom.sharding.algorithm.PartitionByMod"> <property name="count">8</property> </function>
3、数据节点数据
通过引入 DBLE 的自定义拆分算法功能,兼容了原环境 mycat 上的拆分算法,因此原 mycat 环境的存储节点数据也不需要再做任何变动。这极大的减少了我们迁移的工作量。
4、业务 SQL
经过几轮测试下来,我们发现mycat在很多时候会将SQL直接下发到后端节点,这就造成了我们在测试时碰到了很多问题,因为DBLE对多种情况做了细分。
为了最大程度保证业务查询数据的准确性DBLE砍了很多此类SQL的支持,但为了业务的变更最小,DBLE也做了适当开放。
如下是部分记录:
- 对insert into … select … 语法的支持 目前DBLE放开了垂直表该语法的支持。
- 对 rownum透传的支持 目前DBLE放开了指定表rownum的透传。
- UPDATE query with sub-query is not supported 1.update多节点更新会触发分布式事务的问题,难以保证一致性 2.按照目前的执行计划,mycat对于update+子查询采用的是将源sql进行广播下发(下发至表关联的所有节点),这种机制在某些情况下是无法保证正确性的 3.多表关联更新不支持,dble作为一个中间件产品,处理的某一类的sql,对于这类sql正确的处理方法是需要先将子查询下发,回收结果后再拼接外层sql进行下发,目前对于这种处理方式解析、实现比较困难,而且性能问题也是需要考量。 4.为了保证update+子查询这类sql的正确性,肯定不能用mycat这种广播下发来做,所以对于这类sql目前是不支持的
- 全局表+分片表类型SQL支持 ERROR 4004 (HY000): Unknown function FN_TREE_PATHNAME 1.dble 在 2.20.04.x 版本及其之后版本已经做过优化可以直接执行这种情况的sql. 2.全局表+分片表之前没有处理是因为直接下发是可能存在问题,对于全局表+分片表中特殊的场景:全局表+垂直表,并未计算出来这些节点最后使用的是同一个节点。(其实可以计算,dble 在 2.20.04.x 版本及之后已优化) 3.mycat 会直接下发语句到节点中,全局表在每个配置的节点都会存储相同的数据,如果将每个节点和拆分表 Left Join 的结果进行简单的 UNION ALL 合并,会造成数据的重复,不能保证数据的准确性。所以不能直接透传。
更多
针对 DBLE 对 MyCat 做的增强更多记录于:https://actiontech.github.io/dble-docs-cn/0.overview/0.2_dble_enhance_MyCat.html