作者:林海
华夏银行数据库专家,专注于开源及国产分布式数据库技术,多年一线金融行业数据库开发与运维经验。目前主要负责分布式数据库的研究、应用与推广工作。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
采用分布式数据库中间件模式时,我们将业务表按照某种特定的算法和规则分散到了多个业务子表当中。中间层对应用屏蔽后端拆分细节、解析客户端 SQL 请求并转发至后端数据库,整个过程由中间件进行 SQL 解析、重写、路由、执行、结果集归并。对于每一个执行过程,我们一般希望语句能完整地下压至多个后端数据库节点,以达到并行计算的目的。然而有些关联查询语句却可能无法达到我们的预期。它会把语句拆分执行,然后将结果集提升到 DBLE 层匹配计算。这就造成了 DBLE 的 CPU 升高、语句执行耗时严重的问题。极端情况下更可能会造成 DBLE 无法对外提供服务。什么样的语句会造成这种情况?我们下面逐一说明。
环境检查 DBLE 版本:2.19.11.1 MySQL 版本:5.7.28 涉及分片表:h_tempinvm、h_acsn 涉及全局表:brhm 分片拆分规则:stringhash 节点数量:4
下面将通过四个示例来展示造成 DBLE 压力升高的情况及优化方式。
结论:关联查询表分片规则不同,关联语句无法正确下压。
分片表 h_acsn、h_tempinvm 关联查询语句如下:
分片规则如下:
通过配置可见拆分算法 function 是不同的。
执行计划如下:
执行计划可见,DBLE 对语句进行了拆分。分别在每个数据节点扫描两张表后,将各自结果集合并排序后,在 DBLE 层做 MERGE、JOIN 操作。
调整分片规则如下:
调整后执行计划如下:
语句已完全下压至后端数据节点,DBLE 层 MERGE 操作。
结论:关联查询条件未使用分片键,关联语句无法正确下压。
分片表 h_acsn、h_tempinvm 关联查询语句如下:
分片规则如下:
执行计划如下:
该执行计划与示例 1 无法下压情况相同,都是将语句做了拆分,在 DBLE 层 JOIN 操作。
结论:当全局表作为驱动表时,语句无法正确下压。全局表 brhm(驱动表)与分片表 h_acsn(被驱动表)关联查询语句如下:
分片规则如下:
执行计划如下:
执行计划可见语句并没有正确下压。
我们来调整一下,全局表 brhm(被驱动表)与分片表 h_acsn(驱动表)关联查询语句如下:
执行计划如下:
语句已完全下压至后端数据节点,DBLE 层 MERGE 操作。在程序逻辑不可更改情况下,临时解决是将全局表变更为分片表使用。
结论:此问题为全局表处理逻辑 BUG。
分片表 h_acsn、h_tempinvm,全局表 brhm 关联查询语句如下:
分片规则如下:
执行计划如下:
执行计划可见,DBLE 对语句进行了拆分。两张分片表正常下压,全局表单独下压,结果集在 DBLE 层进行 JOIN 操作。临时解决是将全局表变更为分片表使用。