Clickhouse的字典表在分布式表中进行查询操作时,会报列不存在(THERE_IS_NO_COLUMN)的问题。
最近,在做一个基于Clickhouse进行日志分析验证工作,基本操作:
1) 搭建拥有三个结点的的Clickhouse集群。
2) 创建log数据库, 并新增字典表 dict_device_model。
3)在log库,建立日志表【 ngx_log_single】 和分布式表 【ngx_log】
4) 用Springboot应用执行查询操作,结果报如下错误:
(Java错误堆栈信息)
Caused by: java.lang.Throwable: Code: 8. DB::Exception: Cannot find column
dictGetStringOrDefault('dict_device_model', 'out_model',dev_model), dev_model)`
in source stream, there are only columns:------ 此处忽略无关信息
(THERE_IS_NO_COLUMN) (version 22.8.4.7 (official build))
为了排查问题,把SQL语句放在终端执行,结果同样报错:
Code: 60. DB::Exception: Received from 10.11.9.155:9000. DB::Exception: There was an error on [10.11.9.156:9000]: Code: 60. DB::Exception: Table dict_device_model doesn't exist. (UNKNOWN_TABLE) (version 22.8.4.7 (official build)). (UNKNOWN_TABLE)
接下来,执行SQL语句验证:
1、单表的查询可以在每个节点正常执行
select log_time, log_ip, dictGetStringOrDefault('dict_device_model', 'out_model',dev_model), dev_model) from ngx_log_single
2、改为分布式表,复现了问题
select log_time, log_ip, dictGetStringOrDefault('dict_device_model', 'out_model',dev_model), dev_model) from ngx_log
我是链接的 10.11.9.155:9000 这个节点,则在 156 这台主机上会报表不存在;类推, 我在156这台主机上执行, 在 155上会报同样的错。最后,我在字典表的前面添加了数据库名,问题解决:
select log_time, log_ip, dictGetStringOrDefault('test.dict_device_model', 'out_model',dev_model), dev_model) from ngx_log
由此可见,Clickhouse在执行分布式表的查询时,默认不是在分布式表所在的数据库查找字典表。其中的缘由,我现在还没弄清楚,有了解这块的读者,欢迎留言。