如何解决ClickHouse的表处于只读状态

2年前 (2022) 程序员胖胖胖虎阿
588 0 0

在使用ClickHouse的过程中,经常会遇到某个副本的表A处于readonly状态,无法更新数据。

<Error> executeQuery: Code: 242, e.displayText() = DB::Exception: Table is in readonly mode

原因:说是zookeeper的压力大(建议data和log分开存储到不同的磁盘),metadata元数据丢失。

此时通常有两种解决办法:

1)创建一个和该表A结构相同的表A',然后将数据从A表导入到A',多个副本A'的数据会自动同步,以后使用A'表,涉及使用A表的地方都需要修改为A'表;

2)DEATCH掉A表,重新创建A表,但此时数据不会自动同步,需要人工从其它副本A表导入。

查询哪些副本表处于readonly状态:

select table,zookeeper_path,replica_path from `system`.replicas where is_readonly

对于第二种方法,若DEATCH失败,则只能将该节点停止,并备份该节点的数据(如:mv /var/clickhouse /var/clickhouse_bak),重新启动该节点,会自动创建/var/clickhouse目录,创建新的数据库(如:ksdb),并在此库基础上ATTACH/Create table和Create view(相当于重建节点),然后让集群自动从其他节点同步数据,若无法自动同步,则需要手工进行从其他副本导入。

附1:ATTACH语句案例

--ATTACH 语句

ATTACH TABLE ksdb.client_local (
`userid` String,
 `name` String,
 `type` String,
 `timestamp` Date DEFAULT toDate(now())
) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/{layer}-{shard}/client_local', '{replica}') PARTITION BY toYYYYMM(timestamp) ORDER BY userid SETTINGS index_granularity = 8192;

附2: 手工导入语句案例

insert into ksdb.client_local select * from remote('192.168.242.152:9000',ksdb.client_local)

补充第三种解决办法,只重建处于readonly状态的当前表:

#通用方式,在当前节点
#删除表数据
rm -rf  clickhouse/data/database名/表名
#删除表元数据
rm -rf clickhouse/metadata/database名/表名.sql
#./zkCli.sh 连接ZooKeeper,删除其分片对应的副本
rmr /clickhouse/tables/分片名/表名/replicas/副本名
#删除以上数据后,重启该节点,重新CREATE TABLE,数据会自动从其它副本同步过来
#举例如下:
rm -rf  clickhouse/data/ksdb/client_local
rm -rf clickhouse/metadata/ksdb/client_local.sql
./zkCli.sh
rmr /clickhouse/tables/152-01/client_local/replicas/worker1

总结:

第一种方法:数据能自动同步,但需要修改表名,对应用程序不友好;

第二种方法:若DETACH成功,则比较方便;若DETACH失败,则需要重建节点;

第三种方法:是最优的一种方法,只能针对当前处于readonly状态的表,不用改名,也不用重建节点,但要注意不要删错了。

版权声明:程序员胖胖胖虎阿 发表于 2022年10月13日 上午10:56。
转载请注明:如何解决ClickHouse的表处于只读状态 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...