ClickHouse关于插入重复数据丢失问题

 

ClickHouse关于插入重复数据丢失问题

 

对复制表多次写入重复数据无效。

如下:

dev-app76 :) select count(*) from zkm;

SELECT count(*)
FROM zkm

Query id: 8e2bbf61-8adf-4fcc-a6d8-5601e258347d

┌─count()─┐
│       0 │
└─────────┘

1 rows in set. Elapsed: 0.010 sec. 


--为减少篇幅,过程略
insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;
insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;
insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;
insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;


dev-app76 :) select count(*) from zkm;

SELECT count(*)
FROM zkm

Query id: a465d57a-d868-4c3e-b572-a571e9541aa5

┌─count()─┐
│       1 │
└─────────┘

1 rows in set. Elapsed: 0.010 sec. 

 

 

这会导致另外个问题,中途将数据删除成功后,无法再次插入。

dev-app76 :) alter table zkm_local on cluster ceb_cluster delete where 1;

ALTER TABLE zkm_local ON CLUSTER ceb_cluster
    DELETE WHERE 1

Query id: 71b895fa-6b5a-447e-98ad-cf98e9d7d6d2

┌─host──────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ dev-app76 │ 90000 │       │                   30 │
│ dev-app78 │ 90000 │       │                   20 │
│ dev-app77 │ 90000 │       │                   10 │
│ dev-app79 │ 90000 │       │                   00 │
└───────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘

4 rows in set. Elapsed: 0.135 sec. 

dev-app76 :) select count(*) from zkm;

SELECT count(*)
FROM zkm

Query id: 6cd25adc-f580-4c33-b284-e683b469c541

┌─count()─┐
│       0 │
└─────────┘

1 rows in set. Elapsed: 0.011 sec. 

dev-app76 :) insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;

INSERT INTO default.zkm SELECT *
FROM ceb_dev.T_E_RETURN_INFO
LIMIT 1

Query id: 8c235601-8aeb-4e40-8562-bf5de83d22d1

Ok.

0 rows in set. Elapsed: 0.033 sec. 

dev-app76 :) select count(*) from zkm;

SELECT count(*)
FROM zkm

Query id: bbe2f00a-12db-47a2-bbea-132bbbd42e45

┌─count()─┐
│       0 │
└─────────┘

1 rows in set. Elapsed: 0.009 sec. 

 

 

实际上这个是ClickHouse默认的预期行为,点击查看官档

数据块会去重。对于被多次写的相同数据块(大小相同且具有相同顺序的相同行的数据块),该块仅会写入一次。这样设计的原因是万一在网络故障时客户端应用程序不知道数据是否成功写入DB,此时可以简单地重复 INSERT 。把相同的数据发送给多个副本 INSERT 并不会有问题。因为这些 INSERT 是完全相同的(会被去重)。去重参数参看服务器设置 merge_tree 。(注意:Replicated*MergeTree 才会去重,不需要 zookeeper 的不带 MergeTree 不会去重)

这里涉及几个新的概念:

数据块

数据块写入的原子性

max_insert_block_size

资料较少,《ClickHouse原理解析与应用实践》(P212,P21)有提到Block和Block流,并不确定与这里的数据块是不是一样的东西。

也可以读读官网的简要说明:ClickHouse 架构概述

另外,需要如何测试数据块写入的原子性,因为参数max_insert_block_size对于客户端clickhouse-client和insert select无效。

 

扯远了。

对于重复数据插入无效问题,由参数insert_deduplicate控制。

默认是启用的。

ev-app76 :) show settings like 'insert_deduplicate';

SHOW SETTINGS LIKE 'insert_deduplicate'

Query id: b8b78d6e-cdf8-4527-a942-ecdabcd20090

┌─name───────────────┬─type─┬─value─┐
│ insert_deduplicate │ Bool │ 1     │
└────────────────────┴──────┴───────┘

1 rows in set. Elapsed: 0.003 sec. 

 

 

临时设置为禁用后,就可以插入重复数据了。

dev-app76 :) set insert_deduplicate=0;

SET insert_deduplicate = 0

Query id: 457f9f18-2508-47a2-b352-26421b73802d

Ok.

0 rows in set. Elapsed: 0.001 sec. 

insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;
insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;
insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;
insert into default.zkm select * from ceb_dev.T_E_RETURN_INFO limit 1;

dev-app76 :) select count(*) from zkm;

SELECT count(*)
FROM zkm

Query id: eae41929-bb63-4b0b-9d67-b66affeb9c7d

┌─count()─┐
│       5 │
└─────────┘

1 rows in set. Elapsed: 0.010 sec. 

 

posted @ 2022-11-22 11:07  PiscesCanon  阅读(2226)  评论(0编辑  收藏  举报