搞clickhouse遇到的几大问题,记录于此。
本来想编译clickhouse,结果其编译对依赖包的版本都非常高,g++要至少g++10以上版本,cmake也要4.5以上版本,依赖内容也非常多。在Linux上好不容易装上g++12之后,发现下载依赖的速度太慢,所以最终还是从预编译版本deb包里获取通用的linux二进制文件,进行布署安装。
clickhouse提供了daemon启动的参数,但是不知道为啥就是不生效,没有任何日志输出,连日志文件都不会创建,就立马退出了:
./bin/clickhouse server --config-file=conf/config.xml --pid-file=clickhouse.pid --daemon
而且github上也有人发现类似问题,但好像最终都自行解决了,但我始终觉得这个daemon不是常人想要的daemonize。无奈就使用nohup搞定。
连数据库的客户端模块,往往是最让人头疼的,比如MySQLdb,安装的时候会进行二进制模块的编译,鬼晓得clickhouse会遇到什么问题,golang也要连,python也要连。但突然发现clickhouse支持开启类MySQL的监听端口,果然就可以使用连MySQL的模块直接连clickhouse,省事很多。
不知道用了多久,突然clickhouse的日志就不停地报错,而且写日志写得非常快,重启无效,升级到最新版本无效:
<Error> auto DB::IBackgroundJobExecutor::execute(DB::JobAndPool)::(anonymous class)::operator()() const: Code: 427, e.displayText() = DB::Exception: OptimizedRegularExpression: cannot compile re2: �$, error: invalid UTF-8. Look at https://github.com/google/re2/wiki/Syntax for reference. Please note that if you specify regex as an SQL string literal, the slashes have to be additionally escaped.
找了好半天,才知道为什么,以及怎么处理。
原来,对clickhouse进行修改操作,比如DELETE或者ALTER TABLE,都是会异步进行,后台会启线程去完成MergeTree的操作,但是如果处理失败了,就悲剧了,只能一直重试,并不断报错,我这里遇到的就是sql里有非UTF-8编码的字符不支持,而报错。
通过如下语句可以查询最近的修改操作:
select * from system.mutations
如果is_done为0,表示该操作未成功进行。此时就可以找到是哪个操作在反复尝试,然后干掉它,我这里直接全部干掉了:
KILL MUTATION where is_done=0;
然后,世界就安静了。
在clickhouse里,String就是变化的,而FixedString(N)是需要指定长度的定长字符串。而奇葩的就是当在where条件里进行查询时,对于FixedString(N)需要自行使用\0补齐到N长度,否则就会匹配不上。也就是如果如果有个类型是FixedString(8),如果要查询这个字段为a,那么查询需要写成where field='a\0\0\0\0\0\0\0'。
作为列式数据库,理论上不应该支持删除和修改操作的。clickhouse对删除和修改的操作实现是进行的重新建表,也正如它特定的SQL语法一样,让你感受到这是一个代价很高的操作:
alter table user delete where uid=123;
alter table user update age=20 where uid=123;