作者:吴金玲
爱可生 dble 项目团队成员,主要负责 dble 相关的日常测试工作,擅长对 dble 中出现的问题进行排查。热爱测试工作,余生欲将测试工作进行到底。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
一、本文以 dble 3.21.06.0 版本为例,首先让我们来看看社区经常遇到的几类找不到表或者表字段的问题
sharding.xml的关键配置如下:
问题1:启动 dble 后,在所有后端节点都建立了表 sharding_2_t1 ,然后在 dble 管理端执行 reload @@config_all 命令,查询表 sharding_2_t1 数据及向表 sharding_2_t1 中插入数据,均报找不到表的 metadata 信息(如下图所示),为什么?
问题2:在后端节点对表 sharding_4_t1 增加一个 age 字段,且已确保所有后端节点都增加了这个字段,然后执行 reload @@config_all ,对表进行查询使用新增的字段没问题,但使用 order by 就提示找不到这个字段(如下图所示),为什么?
二、在回答出现以上问题的原因之前,首先让我们来看看 reload @@config_all 和 reload @@metadata 的使用说明(具体可参见 dble 官方文档:https://github.com/actiontech/dble-docs-cn/blob/master/2.Function/2.1_manager_cmd/2.1.07_reload.md),这样能够使我们更好的理解问题
1.reload @@config_all(2.19.09.0 版本之后功能完全等同于reload @@config )
重新加载所有配置,涉及3个 xml 配置文件( user.xml,db.xml,sharding.xml ),同时 reload @@config_all 还有3个可选参数的形式:reload @@config_all [-s] [-f] [-r];
-s 跳过测试后端链接,默认不加此参数会对配置中的后端链接进行测试,测试失败将返回 ERROR ;
-f 关闭所有变更的 dbGroup(同时加-r参数则所有 dbGroup 都会被视为变更)相关的处于事务中的前端链接,如果无此参数默认仅将相应后端链接放入旧链接池。
-r 不做智能判断,将所有后端连接池全部重新加载一遍。不加此参数时,将对新配置进行智能判断,只会对增删改的连接池做变更,不影响未作变更的连接池。
相关影响:当执行此命令时,表的配置信息发生变更时,涉及到的表的 meta 信息才会被重载,否则保持原有表 meta 信息。另外,如果包含 -r 参数则不做上述判断,全部重新加载 meta 数据。如果不包含 -r 但是包含 -s 参数,则对 metadata 是否需要重新加载的计算时,忽略所有 dbGroup/dbInstance 的变更。注意,不能在配置变更中体现的某些变化是无法重新加载 metadata 的,比如一个带有默认 shardingNode 的 schema 尝试通过删除配置将拆分表或者 global 表变成非拆分表是不符合规范的。应当避免这种操作。
2.reload @@metadata
reload @@metadata 的作用是重新加载所有元数据信息,同时还有两种扩展的过滤表达式的形式:
reload @@metadata where schema=? [ and table=? ]:重新加载指定 schema 中所有表或指定表的元数据信息。
reload @@metadata where table in (‘schema1.table1’ ,‘schema2.table2’,‘schema1.table3’,…):重新加载 schema1 中 table1,table3 和 schema2 中 table2 的元数据信息。
从以上 reload @@config_all 和 reload @@metadata 的使用说明可以看出,二者在加载元数据时的主要区别为:reload @@config_all 只会对配置中的变更项进行重新加载 metadata ,对配置未做变更的项需要手动执行 reload @@metadata 同步变更的元数据。
三、理解了 reload @@config_all 及 reload @@metadata 的区别后,我们再来分析出现前面两个问题的原因。
不难看出,问题1和问题2的报错都是由于在配置没有发生变更的情况下,在后端节点建表或修改表结构后,认为可以通过执行 reload @@config_all 同步到变更的表的元数据导致的。这里使用者有一个常见的误区,认为所有场景下执行 reload @@config_all 都会触发重新加载元数据,但实际上只有当配置同时发生变更时才会同步更新元数据,其他场景都需要手动执行 reload @@metadata 将后端表的元数据同步到 dble 中。
另外,问题2中为什么 select age from sharding_4_t1 能够查询成功,这是因为此查询属于简单查询,直接下发语句到后端节点执行即可,dble 内部不需要用到 age 字段,而后端节点存在 age 字段,所以执行成功。
四、为了便于排查元数据相关的错误,可以使用 check full @@metadata 查看当前 dble 中所有表的元数据信息。
check full @@metadata 还支持按多种条件过滤(具体可参见 dble 的官方文档:https://github.com/actiontech/dble-docs-cn/blob/master/2.Function/2.1_manager_cmd/2.1.17_check_meta_data.md)
通过以上查询结果不难发现,表 sharding_2_t1 和表 sharding_4_t1 的元数据均未同步到更新。
执行 reload @@metadata 后,再次执行 check full @@metadata 查询元数据信息:
通过以上结果可以看到表sharding_2_t1和表sharding_4_t1已经同步到正确的元数据信息,此时可以对表进行常规操作而不会报错: