测试环境中某个clickhouse实例由于意外断电而终止,重新启动报错,报错的关键信息 DB::ParsingException: Cannot parse input: expected ‘columns format version: 1\n’ at end of stream

其中报错的日志如下:

1
{} <Error> auto DB::MergeTreeData::loadDataParts(bool)::(anonymous class)::operator()() const: Code: 27. DB::ParsingException: Cannot parse input: expected 'columns format version: 1\n' at end of stream. (CANNOT_PARSE_INPUT_ASSERTION_FAILED), Stack trace (when copying this message, always include the lines below):

可以搜一下github上面的issue,也有几个类似的问题, 例如:https://github.com/ClickHouse/ClickHouse/issues/37397。

这个报错是因为clickhouse在启动服务的时候会检查损坏的数据文件块数量,如果超过一个特定值(默认是10,对应于max_suspicious_broken_parts配置),就会发生这个异常,导致无法启动。

而出现这么多损坏的文件块数据,是因为在系统异常断电的时候,有些数据还存在于内存中,并没有完全写入磁盘,导致出现数据不一致的情况。

解决方案有两个:

(1)调整max_suspicious_broken_parts值

让其在启动时能允许更多的损坏,但是这个值不好把控,主要取决于在断电的那一瞬间,不一致的数据量有多大,本人自测当调整到10000的时候,才能正常启动。

修改配置文件中如下配置:

1
2
3
4
5
<yandex>
<merge_tree>
<max_suspicious_broken_parts>50</max_suspicious_broken_parts>
</merge_tree>
</yandex>

(2) 强制启动

在clicckhouse数据根目录下的flags文件夹下创建一个force_restore_data文件,然后再重启服务即可。假设现在clickhouse的数据根目录是/var/lib/clickhouse, 则执行如下命令:

1
touch /var/lib/clickhouse/flags/force_restore_data

注意,无论上面哪种方式,都有可能会导致数据丢失。

参考文档:

  1. https://github.com/ClickHouse/ClickHouse/issues/37397
  2. https://kb.altinity.com/altinity-kb-setup-and-maintenance/suspiciously-many-broken-parts/