ClickHouse源码分析:optimize table xxx流程分析

举报
ZhjDayDayUp 发表于 2021/12/29 15:48:49 2021/12/29
【摘要】 基于ClickHouse v21.3.4.25版本的代码,分析optimize table xxx final的流程。

代码基于v21.3.4.25,具体流程如下:

# optimize table分析
# 非复制表
StorageMergeTree::optimize
    if (!partition && final) // 没有指定partition,但有final,则遍历所有分区进行合并
        StorageMergeTree::merge
            StorageMergeTree::selectPartsToMerge
                selectAllPartsToMergeWithinPartition // 有partition_id,选择分区内所有的part进行合并。
                    if final
                        // 如果设置了optimize_skip_merged_partitions,且分区内只有一个part,且part的level大于0,则不进行merge
                    // 根据规则,同一个分区下,只要有两个part之间无法merge,则整个分区都无法merge。只有一个part也能merge
            StorageMergeTree::mergeSelectedParts // 真正merge
    else // 1、指定了partition且有final;2、指定partition,没有final;3、没有partition,没有final
        StorageMergeTree::merge
            StorageMergeTree::selectPartsToMerge
                if 没有partition
                    MergeTreeDataMergerMutator::selectPartsToMerge // 根据内部算法,返回某个分区的一些part进行merge
                        SimpleMergeSelector::select
                else
                    while true // 选择到part或者超时,会break
                        selectAllPartsToMergeWithinPartition
                            if final
                                // 如果设置了optimize_skip_merged_partitions,且分区内只有一个part,且part的level大于0,则不进行merge
                            else
                                // 如果分区内只有一个part,则不进行merge
                        if final
                            currently_processing_in_background_condition.wait_for // 有final时,如果没有选择到part,会等待正在合并的part结束(不超过120s),然后再次选择part进行merge
            StorageMergeTree::mergeSelectedParts // 真正merge
            
            
# 复制表
StorageReplicatedMergeTree::optimize
    if (!partition && final) // 遍历所有分区,每个分区最多尝试10次
        selectAllPartsToMergeWithinPartition
            ...
        createLogEntryToMergeParts // 本节点和zk上某个分区的part不一致,就停止合并
    else
        if 没有partition
            MergeTreeDataMergerMutator::selectPartsToMerge
        else
            selectAllPartsToMergeWithinPartition
        // 没有选择到,就退出合并流程
    if replication_alter_partitions_sync != 0 // 默认为1
        waitForAllReplicasToProcessLogEntry // 等待所有副本的所有的entry处理结束  

总结:

1、optimize如果没有指定partition,有final的话,会遍历所有分区的所有part进行合并,如果有分区的part不能进行合并,则该分区都不合并;

2、optimize如果没有指定partition,没有final的话,则会根据内部算法,对某个分区的一些part进行合并;

3、optimize如果指定了partition,不管有没有final,都会选择对应分区的所有part进行合并;

4、如果指定了partition,也指定了final,在设置了optimize_skip_merged_partitions,且分区内只有一个part,且part的level大于0,则不进行merge

5、如果指定了partition,但没有指定final,当分区内只有一个part时,则不进行merge

6、非复制表,如果指定了分区,且有final时,会等待正在合并的part结束,再进行merge,而复制表则是直接退出了

7、对于复制表,如果本节点和zk的part不一致,则不会进行merge

8、默认情况下,复制表会等待所有副本merge结束,在复制表上执行optimize还是要慎重一些。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。