ClickHouse 复制表引擎重复数据没办法写入
关于复制表重复数据无法写入,这里进行一下演示和剖析。有时候,我们明明已经插入了数据,可是查询到的数据行数并没有新增,现对该情况进行分析。
--演示说明
CREATE TABLE try
(
`username` String,
`lables.name` Array(String),
`lables.value` Array(String),
`day` Date
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/try', '{replica}')
PARTITION BY toYYYYMMDD(day)
ORDER BY username;
insert into try values ('张三',['os_type','version','database_name','owner'],['linux','redhat_7.6','postgres','postgres'],toDate(now()));
insert into try values ('李四',['os_type','version','database_name','owner'],['linux','redhat_7.7','flyingdb','flyingdb'],toDate(now()));
insert into try values ('王五',['os_type','version','database_name','owner'],['linux','Mint_17.3','test','test'],today());
insert into try values ('赵六',['os_type','version','database_name','owner'],['linux','Mint_17.4','data','data'],today());
select * from try;
┌─username─┬─lables.name───────────────────────────────────┬─lables.value────────────────────────┬────────day─┐
│ 赵六 │ ['os_type','version','database_name','owner'] │ ['linux','Mint_17.4','data','data'] │ 2022-09-14 │
└──────────┴───────────────────────────────────────────────┴─────────────────────────────────────┴────────────┘
┌─username─┬─lables.name───────────────────────────────────┬─lables.value─────────────────────────────────┬────────day─┐
│ 李四 │ ['os_type','version','database_name','owner'] │ ['linux','redhat_7.7','flyingdb','flyingdb'] │ 2022-09-14 │
└──────────┴───────────────────────────────────────────────┴──────────────────────────────────────────────┴────────────┘
┌─username─┬─lables.name───────────────────────────────────┬─lables.value────────────────────────┬────────day─┐
│ 王五 │ ['os_type','version','database_name','owner'] │ ['linux','Mint_17.3','test','test'] │ 2022-09-14 │
└──────────┴───────────────────────────────────────────────┴─────────────────────────────────────┴────────────┘
┌─username─┬─lables.name───────────────────────────────────┬─lables.value─────────────────────────────────┬────────day─┐
│ 张三 │ ['os_type','version','database_name','owner'] │ ['linux','redhat_7.6','postgres','postgres'] │ 2022-09-14 │
└──────────┴───────────────────────────────────────────────┴──────────────────────────────────────────────┴────────────┘
重复执行上面insert数据,然后select数据,发现数据还是只有4行。
分析日志,有如下日志记录:
2022.09.14 17:01:20.725741 [ 163 ] {67719eb7-2f61-41b7-8abb-bcf2e67d6ae8} <Error> executeQuery: Code: 57, e.displayText() = DB::Exception: Table icat.try already exists. (version 20.2.1.2120 (official build)) (from 127.0.0.1:36636) (in query: CREATE TABLE icat.try (`username` String, `lables.name` Array(String), `lables.value` Array(String), `day` Date) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/try', '{replica}') PARTITION BY toYYYYMMDD(day) ORDER BY username), Stack trace (when copying this message, always include the lines below):
可以发现,新插入的数据被clickhouse过滤掉了。那么,来看下ClickHouse的处理逻辑。
# 数据插入入口
InterpreterInsertQuery::execute
StorageReplicatedMergeTree::write // 构造数据流 ReplicatedMergeTreeBlockOutputStream
deduplicate = replicated_deduplication_window != 0 && insert_deduplicate // 是否去重,跟去重窗口和去重标志有关,默认窗口为100,标志为true
ReplicatedMergeTreeBlockOutputStream::write // 数据写入
block转为part
if deduplicate == true
hash // part的哈希值
block_id = partition_id "_" hash.words[0] "_" hash.words[1] // 构造block_id的字符串名称
end
commitPart // 向zk提交part
if block_id not empty
zkutil::makeCreateRequest // 如果zk上有相同的节点,则返回空block_number,否则创建该节点
end
if getActiveContainingPart
return // 该part已经被包含,则忽略它
# 复制表清理线程
ReplicatedMergeTreeCleanupThread::run
sleep_ms // 周期间隔时间,默认30s~40s随机
ReplicatedMergeTreeCleanupThread::iterate
clearOldBlocks // 清理过期block
replicated_deduplication_window_seconds
replicated_deduplication_window // 两者综合考虑,超过replicated_deduplication_window或者之间间隔超过replicated_deduplication_window_seconds
在默认情况下,如果一次插入的数据与一周内最近的100次左右(如果一次性插入的block可以分为多个part,则不到100次)成功插入的数据具有相同的block_id,则会被过滤掉。
针对这个问题官方有个参数:insert_deduplicate
对于 Replicated* 表,启用或禁用INSERT删除重复数据。
可能的值:
0 -禁用。
1 -启用(默认值)。
默认情况下,通过INSERT语句插入到复制表中的块会被重复数据删除(请参阅数据复制)
https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/replication
insert_deduplicate参数配置三种方式:
1.在 users.xml 中的用户配置文件中
2.SET 命令的会话
3.在SELECT语句的 SETTINGS 子句中。
通过设置可以让clickhouse不做此项检查,保证数据每次都能插入成功。有点需要注意的是,真正生效的窗口大小可能不止100,可能更多。因为清理线程的周期是30-40s,如果老的block_id没有及时清理掉,会导致实际的去重窗口值大于replicated_deduplication_window。
声明
因小编个人水平有限,专栏中难免存在错漏之处,请勿直接复制文档中的参数、命令或方法应用于线上环境中操作。
近期文章推荐
ClickHouse 版本升级
PostgreSQL 逻辑复制模块(一)
PostgreSQL 逻辑复制模块(二)
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgcakjb
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13