Clickhouse源碼分析-TTL執行流程

第一種情況:無ttl_only_drop_parts配置

總體示例以及說明

如果沒有ttl_only_drop_parts的配置,過期數據的刪除(這里是刪除,是將過期的數據從這個part刪除,并將過期的數據構成一個part,這個過期的part標記為inactive,沒過期的變為新part)會在TTL Merge任務中進行。

示例如下,ttl_only_drop_parts = 0:

CREATE TABLE my_table1
(
? ? `event_time` DateTime,
? ? `id` UInt64,
? ? `message` String
)
ENGINE = MergeTree
PARTITION BY toStartOfHour(event_time)
ORDER BY (event_time, id)
TTL event_time + toIntervalMinute(3)
SETTINGS index_granularity = 8192, ttl_only_drop_parts = 0

?插入數據:

INSERT INTO my_table1
SELECT
? ? now() - INTERVAL intDiv(number, 1000) SECOND AS event_time, ?-- 控制時間分布在最近3分鐘
? ? number AS id,
? ? concat('message_', toString(number)) AS message
FROM numbers(1000000);

這條 SQL 語句的作用是:my_table1 表插入 1,000,000 條數據,這些數據的 event_time 字段分布在最近 3 分鐘內

此時100W的數據中,會有兩個分區生成:2025-06-30 12:00:00,2025-06-30 13:00:00。

過了一段時間后,由于2025-06-30 12:00:00中已經有部分數據達到過期時間,所以會生成一個1751284800_2_2_1的part,它的active字段為1。

而之前的那個老分區直接設置active字段為0即可,表示為不活躍。

用圖解可以表示為:

過一段時間之后:

此時可以看到1751284800_2_2_0中的部分數據也達到了過期時間,之后生成一個名字為1751284800_2_2_1的分區,剩余數據為168000行,相當于過期了1000行。

此部分可以用圖解表示為:

再過一段時間可以看到:

此時cleanup后臺線程進行了清理后,剩下了最后兩個part:?

這里大家可能會有疑問?為什么最后兩個part遲遲沒有刪除呢,它們明明已經到達了最大過期時間了啊?

這個結論放在 <分區到達過期時間卻未刪除> 這一小節說明。

梳理part的轉變

我們也可以從part_log中梳理關于這個表TTL merge:

1??最初插入的數據,ClickHouse 生成了以下兩個原始 part:

TimeEventPart NameRows分區
13:02:48NewPart1751284800_2_2_08310002025-06-30 13:00:00
13:02:48NewPart1751288400_1_1_01690002025-06-30 12:00:00

這兩個 part 加起來就是插入的 1,000,000 行 ?

2?? ClickHouse 執行 TTL 刪除合并1:

TimeEventPart NameRows類型
13:02:48MergePartsStart1751284800_2_2_10開始 TTL 合并
13:02:48MergeParts1751284800_2_2_111000TTL 合并后剩下的數據

3?? ClickHouse 執行 TTL 刪除合并2:

TimeEventPart NameRows類型
13:03:00MergePartsStart1751288400_1_1_10開始 TTL 合并
13:03:00MergeParts1751288400_1_1_1168000TTL 合并后剩下的數據

4??清理不活躍的分區

TimeEventPart NameRows說明
13:12:12RemovePart1751284800_2_2_0831000被后臺clean線程刪掉
13:12:12RemovePart1751288400_1_1_0169000被后臺clean線程刪掉

分區到達過期時間卻未刪除

在上面,我們看到了分區達到過期時間,但是卻未刪除的場景,這是為什么呢?

此時os time:

$ date
Mon Jun 30 01:41:14 PM UTC 2025

這與一個參數有關系:merge_with_ttl_timeout

官網鏈接如下:Manage Data with TTL (Time-to-live) | ClickHouse Docs

對于后臺merge線程選擇一個TTL Merge任務(也就是類型為TTLDelete的merge任務)后,它會推遲這個分區向后merge_with_ttl_timeout 毫秒,才能再次選擇這個分區。

例如依據上面的示例來說,假如2025-06-30 13:00:00在13:03:00執行,那么下次能選擇到分區為2025-06-30 13:00:00的part進行merge,至少在13:03:00 + 4h =?15:03:00 才能發生。

4h為merge_with_ttl_timeout的默認值(轉化為小時)。

關鍵代碼位置,更新分區的選擇時機:

void MergeTreeDataMergerMutator::updateTTLMergeTimes(const MergeSelectorChoice & merge_choice, const MergeTreeSettingsPtr & settings, time_t current_time)
{chassert(!merge_choice.range.empty());const String & partition_id = merge_choice.range.front().info.getPartitionId();switch (merge_choice.merge_type){case MergeType::Regular:/// Do not update anything for regular merge.return;case MergeType::TTLDelete:next_delete_ttl_merge_times_by_partition[partition_id] = current_time + (*settings)[MergeTreeSetting::merge_with_ttl_timeout];return;case MergeType::TTLRecompress:next_recompress_ttl_merge_times_by_partition[partition_id] = current_time + (*settings)[MergeTreeSetting::merge_with_recompression_ttl_timeout];return;}
}

選擇part去merge的調用棧:

chooseMergeFrom()? ? ? ? ->

????????MergeSelectorApplier::chooseMergeFrom()? ? ? ? ->

? ? ? ? ? ? ? ? if 如果有TTL...? then?tryChooseTTLMerge()? ? ? ? ->

????????????????????????ITTLMergeSelector::select()? ? ? ?->

????????????????????????????????ITTLMergeSelector::findCenter()

判斷位置,是否推遲的邏輯關鍵函數為needToPostponePartition:

std::optional<ITTLMergeSelector::CenterPosition> ITTLMergeSelector::findCenter(const PartsRanges & parts_ranges) const

{

? ? assert(!parts_ranges.empty());

? ? std::optional<CenterPosition> position = std::nullopt;

? ? for (auto range = parts_ranges.begin(); range != parts_ranges.end(); ++range)

? ? {

? ? ? ? assert(!range->empty());

? ? ? ? const auto & range_partition = range->front().info.getPartitionId();

? ? ? ? if (needToPostponePartition(range_partition))

? ? ? ? ? ? continue;

? ? ? ? for (auto part = range->begin(); part != range->end(); ++part)

? ? ? ? {

? ? ? ? ? ? if (!canConsiderPart(*part))

? ? ? ? ? ? ? ? continue;

? ? ? ? ? ? time_t ttl = getTTLForPart(*part);

? ? ? ? ? ? if (!ttl || ttl > current_time)

? ? ? ? ? ? ? ? continue;

? ? ? ? ? ? if (!position || ttl < getTTLForPart(*position->center))

? ? ? ? ? ? ? ? position.emplace(range, part);

? ? ? ? }

? ? }

? ? return position;

}

needToPostponePartition內部邏輯為:

bool ITTLMergeSelector::needToPostponePartition(const std::string & partition_id) const

{

? ? if (auto it = merge_due_times.find(partition_id); it != merge_due_times.end())

? ? ? ? return it->second > current_time;

? ?

? ? return false;

}

而這個merge_due_times就是每次merge完之后的調整的next_delete_ttl_merge_times_by_partition。

最后附上TTL執行的部分調用棧:

TODO:調小merge_with_ttl_timeout,驗證。

第二種情況: 有ttl_only_drop_parts配置

如果配置了這個參數,ck并不會在某個part中的部分數據達到過期時間時,進行過期數據的刪除。而是整個part的數據都達到過期時間時才會進行刪除(這里的刪除并不是物理刪除,而是邏輯上的刪除,即將這個part標記為inactive,對應system.parts關于這個part的記錄的active字段為0)。

之后MergeTree / ReplicatedMergeTree 的cleanup線程會進行刪除(這是物理刪除,即刪除磁盤中的文件)的動作。

由此可見,不管配沒配置這個參數,ck在TTL Merge任務的時候并不會做真正刪除過期數據的操作,只是邏輯刪除,真正的刪除交給后臺cleanup線程。

核心代碼位置:

執行階段:

直接跳過:

具體的執行邏輯可以看日志:

部分日志是我手動添加日志的,例如:merge_type = XXX. 這部分。

TODO: 設置system.parts的active字段為0的位置。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/87005.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/87005.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/87005.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

elementui修改radio字體的顏色和圓圈的樣式

改完 <div class"choose"><el-radio-group v-model"radioNum"><el-radio label"1" size"large">Option 1</el-radio><el-radio label"2" size"large">Option 2</el-radio>&l…

力扣3381. 長度可被 K 整除的子數組的最大元素和

由于數據范圍是2*10^5所以必然是遍歷一次&#xff0c;子數組必定要用到前綴和&#xff0c;之前的題目中總是遇到的是子數組的和能不能被k整除&#xff0c;而這里不一樣的是子數組的長度能不能被k整除&#xff0c;如果單純的枚舉長度必定超時&#xff0c;而看看題解得出的思路&a…

基于SSM的勤工助學系統的設計與實現

第1章 摘要 基于SSM框架的勤工助學系統旨在為學生、用工部門和管理員提供高效便捷的管理平臺。系統包括學生端、用工部門端和管理員端&#xff0c;涵蓋了從崗位發布、申請審核、工時記錄、薪資管理到數據統計等完整的功能需求。 學生可以通過系統首頁瀏覽最新的崗位信息和公告&…

2025年06月30日Github流行趨勢

項目名稱&#xff1a;twenty 項目地址 URL&#xff1a;https://github.com/twentyhq/twenty項目語言&#xff1a;TypeScript歷史 star 數&#xff1a;31,774今日 star 數&#xff1a;1,002項目維護者&#xff1a;charlesBochet, lucasbordeau, FelixMalfait, Weiko, bosiraphae…

creo 2.0學習筆記

Creo軟件從入門到精通——杜書森 1.1 Creo基本建模過程介紹 新建-零件-改名稱-取消使用默認模板&#xff0c;是因為默認的是英制尺寸&#xff0c;自定義可選擇mmns_part_solid&#xff0c;模板主要是設置模型的單位拉伸-選取FRONT-點擊草繪視圖&#xff0c;可進行草繪旋轉——…

ZNS初步認識—GPT

1. ZNS SSD 的基本概念 Zoned Namespace (ZNS): ZNS 是一種新的NVMe接口規范&#xff0c;它將SSD的邏輯塊地址空間劃分為多個獨立的、固定大小的“區域”&#xff08;Zones&#xff09;。區域 (Zone): ZNS SSD 的基本管理單元。每個區域都有自己的寫入指針&#xff08;write p…

【seismic unix生成可執行文件-sh文件】

Shell腳本文件&#xff08;.sh文件&#xff09;簡介 Shell腳本文件&#xff08;通常以.sh為擴展名&#xff09;是一種包含Shell命令的文本文件&#xff0c;用于在Unix/Linux系統中自動化執行任務。它由Shell解釋器&#xff08;如Bash、Zsh等&#xff09;逐行執行&#xff0c;常…

Debezium日常分享系列之:在 Kubernetes 上部署 Debezium

Debezium日常分享系列之&#xff1a;在 Kubernetes 上部署 Debezium 先決條件步驟部署數據源 (MySQL)登錄 MySQL db將數據插入其中部署 Kafka部署 kafdrop部署 Debezium 連接器創建 Debezium 連接器 Debezium 可以無縫部署在 Kubernetes&#xff08;一個用于容器編排的開源平臺…

利潤才是機器視覺企業的的“穩定器”,機器視覺企業的利潤 = (規模經濟 + 技術差異化 × 場景價值) - 競爭強度

影響機器視覺企業盈利能力的關鍵因素。這個公式本質上反映了行業的核心動態:利潤來自成本控制(規模化效應)和差異化優勢(技術壁壘與場景稀缺性的協同),但被市場競爭(內卷程度)所侵蝕。下面我將一步步拆解這個公式,結合機器視覺行業的特點(如工業自動化、質檢、安防、…

EPLAN 中定制 自己的- A3 圖框的詳細指南(一)

EPLAN 中定制 BIEM - A3 圖框的詳細指南 在智能電氣設計領域&#xff0c;圖框作為圖紙的重要組成部分&#xff0c;其定制的規范性和準確性至關重要。本文將以北京經濟管理職業學院人工智能學院的相關任務為例&#xff0c;詳細介紹在 EPLAN 軟件中定制 BIEM - A3 圖框的全過程…

macbook開發環境的配置記錄

前言&#xff1a;好多東西不記錄就會忘記 git ssh配置 當我們的沒有配置git ssh的時候&#xff0c;使用ssh下載的時候會顯示報錯“make sure you have the correct access rights and respository exits" 如何解決&#xff0c;我們先在命令行檢查檢查一下用戶名和郵箱是…

GitLab 18.1 高級 SAST 已支持 PHP,可升級體驗!

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

[學習]M-QAM的數學原理與調制解調原理詳解(仿真示例)

M-QAM的數學原理與調制解調原理詳解 QAM&#xff08;正交幅度調制&#xff09;作為現代數字通信的核心技術&#xff0c;其數學原理和實現方法值得深入探討。本文將分為數學原理、調制解調原理和實現要點三個部分進行系統闡述。 文章目錄 M-QAM的數學原理與調制解調原理詳解一、…

圖書管理系統練習項目源碼-前后端分離-使用node.js來做后端開發

前端學習了這么久了&#xff0c;node.js 也有了一定的了解&#xff0c;知道使用node也可以來開發后端&#xff0c;今天給大家分享 使用node 來做后端&#xff0c;vue來寫前端&#xff0c;做一個簡單的圖書管理系統。我們在剛開始學習編程的時候&#xff0c;需要自己寫大量的項目…

【甲方安全視角】企業建設下的安全運營

文章目錄 一、安全運營的概念與起源二、安全運營的職責與定位三、安全運營工程師的核心能力要求四、安全運營的典型場景與應對技巧1. 明確責任劃分,避免“醫生做保姆”2. 推動機制:自下而上 vs. 自上而下3. 宣傳與內部影響力建設五、安全運營的戰略意義六、為何需要安全原因在…

03認證原理自定義認證添加認證驗證碼

目錄 大綱 一、自定義資源權限規則 二、自定義登錄界面 三、自定義登錄成功處理 四、顯示登錄失敗信息 五、自定義登錄失敗處理 六、注銷登錄 七、登錄用戶數據獲取 1. SecurityContextHolder 2. SecurityContextHolderStrategy 3. 代碼中獲取認證之后用戶數據 4. 多…

IPLOOK 2025上半年足跡回顧:連接全球,步履不停

2025年上半年&#xff0c;IPLOOK積極活躍于全球通信舞臺&#xff0c;足跡橫跨亞洲、歐洲、非洲與北美洲&#xff0c;我們圍繞5G核心網、私有網絡、云化架構等方向&#xff0c;向來自不同地區的客戶與合作伙伴展示了領先的端到端解決方案&#xff0c;深入了解各地市場需求與技術…

【Kafka】docker 中配置帶 Kerberos 認證的 Kafka 環境(全過程)

1. 準備 docker 下載鏡像 docker pull centos/systemd&#xff0c;該鏡像是基于 centos7 增加了 systemd 的功能&#xff0c;可以更方便啟動后臺服務 啟動鏡像 使用 systemd 功能需要權限&#xff0c;如果是模擬 gitlab services 就不要使用 systemd 的方式啟動 如果不使用 s…

用Python構建一個可擴展的多網盤聚合管理工具 (以阿里云盤為例)

摘要 本文旨在從開發者視角&#xff0c;探討并實踐如何構建一個命令行界面的、支持多網盤聚合管理的工具。我們將以阿里云盤為例&#xff0c;深入解析其API認證與核心操作&#xff0c;并用Python從零開始實現文件列表、重命名、分享等功能。更重要的是&#xff0c;本文將重點討…

筑牢網絡安全屏障

在數字化浪潮席卷全球的今天&#xff0c;網絡空間已成為繼陸、海、空、天之后的 “第五疆域”&#xff0c;深刻影響著國家政治、經濟、軍事等各個領域。“沒有網絡安全就沒有國家安全”&#xff0c;這句論斷精準道出了網絡安全與國家安全之間密不可分的關系。? 網絡安全關乎國…