在使用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失败,则需要重建节点;文章来源:https://www.toymoban.com/news/detail-406609.html
第三种方法:是最优的一种方法,只能针对当前处于readonly状态的表,不用改名,也不用重建节点,但要注意不要删错了。文章来源地址https://www.toymoban.com/news/detail-406609.html
到了这里,关于如何解决ClickHouse的表处于只读状态的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!