全部產品
Search
文件中心

Hologres:Compaction

更新時間:Sep 05, 2026

當離線匯入大量資料或大量執行delete、update操作後,可能會由於資料檔案的片段化導致讀寫效能下降,此時需要執行壓縮(Compaction)操作。Compaction操作將多個資料檔案合并成一個更大的資料檔案,執行Compaction操作有助於重新組織資料存放區結構,提高讀寫效率。本文介紹在Hologres中如何進行Compaction操作。

背景資訊

Hologres的資料寫入模型使用了與LSM-Tree類似的資料結構,資料都是以Append Only的方式寫入儲存的。這種資料結構可以將隨機寫變為順序寫,這是一種面向寫最佳化的資料結構,能夠有效提升寫入的輸送量。寫入的資料檔案需要通過Compaction合并成一個更大的資料檔案。

Hologres中存在兩類Compaction操作:

  • Auto Compaction

    Hologres的Auto Compaction是分層的。最多有五層,當單層檔案超過五個時,會自動觸發Compaction,Compaction完成後的檔案會放到下一層。例如Level 0的檔案達到五個後,會自動觸發Compaction,將五個檔案合并,合并後的檔案預設最大為64 MB,如果檔案大小超過64 MB後,會產生多個檔案,合并後的檔案會放到Level 1,示意圖如下所示:

    image.png

  • Full Compaction

    Auto Compaction只會發生在某層內部,不會跨層合并檔案。Full Compaction會將所有層的所有檔案進行合并,合并後每個檔案預設的最大的大小為64 MB,合并後的檔案會放到最後一層。

使用限制

  • 僅Hologres V2.1及以上版本支援手動觸發Full Compaction,如果您的執行個體是V2.1以下版本,請您使用自助升級或加入即時數倉Hologres交流群申請升級執行個體,詳情請參見如何擷取更多的線上支援?

  • 僅列存表和行列共存表可以主動觸發Full Compaction。

  • 行列共存表執行Full Compaction之後,僅列存部分會執行Full Compaction。

使用說明

  • 使用情境:

    對於如下情境可以主動觸發Full Compaction,合并小檔案,提升查詢效率:

    • 離線匯入大量資料後。

    • 大量執行delete或者update操作之後。

    說明

    Full Compaction時會佔用大量IO和CPU資源,請在寫入低峰期執行。一般執行會持續10分鐘以上。

  • 命令文法:

    SELECT hologres.hg_full_compact_table(
      '<SCHEMA_NAME.TABLE_NAME>'
      [,'max_file_size_mb=<VALUE>']
    );
  • 參數說明:

    參數名稱

    說明

    是否必填

    預設值

    schema_name.table_name

    需要執行Full Compaction操作的表名稱。

    是

    無

    max_file_size_mb

    (不推薦隨意更改)指定需要執行Full Compaction後組建檔案大小的最大值,取值必須是正整數,單位為MB。

    若調小此參數值,會導致資料檔案變多,檔案過多會導致查詢變慢。

    否

    64

  • 使用樣本:

    • 對錶public.lineitem執行Full Compaction操作:

      SELECT hologres.hg_full_compact_table( 'public.lineitem');
    • 對錶public.lineitem執行Full Compaction操作,指定合并後輸出的檔案大小最大為256 MB:

      SELECT hologres.hg_full_compact_table(
       'public.lineitem',
       'max_file_size_mb=256'
      );

表級Compaction參數

除手動觸發Full Compaction外,Hologres還支援通過表屬性(Table Property)對單張表的自動Compaction行為進行精細化調整,包括並發控制、檔案選擇策略與觸發頻率等,適用於大量匯入前臨時暫停Compaction、小檔案治理、後台資源爭搶處置等情境。

表級參數使用限制

  1. 僅Hologres V4.0及以上版本支援本章節所述的表級Compaction參數。低於V4.0的執行個體設定這些參數不會生效,請先升級執行個體。

  2. 本章節所述參數僅對列存表和行列共存表生效,其中行列共存表僅列存部分受這些參數控制。對行存表設定這些參數不會產生效果。

  3. 絕大多數情境下自動Compaction無需人工幹預。除核心參數online_config_compaction_semaphore外,其餘進階參數與並發參數存在耦合,建議在支援人員指導下用於特定問題的定向處置,處置完成後恢複預設值。

參數設定方式

表級Compaction參數通過SET_TABLE_PROPERTY設定,參數名統一帶online_config_首碼,值統一為字串。設定後對後續調度的Compaction任務生效,運行中的任務不受影響,無需重啟執行個體或重建表。

-- 文法
CALL SET_TABLE_PROPERTY('<SCHEMA_NAME>.<TABLE_NAME>', 'online_config_<PROPERTY_NAME>', '<VALUE>');

-- 樣本:將表public.orders的Compaction並發臨時設定為0(暫停調度新任務)
CALL SET_TABLE_PROPERTY('public.orders', 'online_config_compaction_semaphore', '0');

恢複預設(reset)

值reset表示刪除該表級覆蓋值,恢複為執行個體預設行為。

CALL SET_TABLE_PROPERTY('public.orders', 'online_config_compaction_semaphore', 'reset');
重要

如果調整前該表已經存在一個業務上需要的覆蓋值(例如之前特意設定過4),恢複時應寫回原值而不是reset。調整前請先查詢並儲存原狀態,詳情請參見查詢當前設定。

查詢當前設定

SELECT property_key, property_value
FROM hologres.hg_table_properties
WHERE table_namespace = '<SCHEMA_NAME>'
  AND table_name = '<TABLE_NAME>'
  AND property_key LIKE 'online_config_%';

查詢結果為空白表示該表沒有任何錶級覆蓋值,使用執行個體預設行為。

核心參數

online_config_compaction_semaphore

該參數是日常調優的首選參數,控製表的每個資料分區(Tablet)的Compaction並發上限,而不是整張表的總並發。每個資料分區即Compaction的一個調度單元,兩者在本文中指同一對象。一張表在每個Shard上通常有一個或多個分區,例如行列共存表的行存、列存部分是各自獨立的分區,因此整表理論並發上限約為分區總數 × 該參數值,實際還會受Worker級總並發和資源餘量限制。

取值

含義

適用情境

0

暫停該表新的Compaction任務。

大大量匯入前的臨時視窗(用完必須恢複)。

1

最低限度保留合并能力。

Compaction明顯影響線上業務時降載。

2

預設值。

絕大多數情境。

3~8

提高合并吞吐。

檔案持續積壓且執行個體資源有餘量時,每次加1,小步調整。

設定為0的確切語義

  • 阻止該表新的Compaction任務執行。

  • 不會取消已經在啟動並執行任務,已運行任務會自然執行完畢。

  • 該表已被選出、等待執行的任務仍會佔用Worker級總並發額度,因此同時對大量表設定為0會擠占其他表的合并並發。

  • 從0恢複為大於0的值後,已在排隊的任務會繼續執行,但尚未被調度的積壓檔案不一定會自動重新觸發合并,尤其是沒有新寫入時,建議恢複後手動執行一次VACUUM(VACUUM的確切語義請參見使用樣本)。

從0恢複並觸發積壓檔案合并的樣本如下:

CALL SET_TABLE_PROPERTY('public.orders', 'online_config_compaction_semaphore', '2');
VACUUM public.orders;

邏輯分區表說明

邏輯分區表會根據當前活躍分區數適當調大並發,單個調度單元的並發上限為min(online_config_partition_table_compaction_semaphore_max, active_partition_count × online_config_compaction_semaphore),預設封頂為8。其中active_partition_count為當前活躍分區數,由系統在運行時統計得出,不是可設定的表屬性。

風險提示

  • 不要長期保持為0:檔案數和被刪除資料會持續積壓,查詢效能和儲存空間都會惡化,且積壓越久恢複後的合并壓力越大。

  • 不要批量對大量表設定為0或批量調大:所有表共用Worker級總並發,大量設定為0會讓被暫停表的排隊任務佔住全域並發額度,批量調大則容易造成全域排隊和資源衝擊。

  • 建議一次只調一張表、一個參數,步長儘可能小,觀察一個業務周期後再進行下一步。

進階參數

以下參數影響Compaction的檔案選擇策略和觸發頻率,與並發參數存在耦合,建議在支援人員指導下使用,處置完成後恢複預設值。

參數

預設值

含義

online_config_partition_table_compaction_semaphore_max

8

邏輯分區表單個調度單元的Compaction並發封頂值,與online_config_compaction_semaphore共同決定實際並發,計算公式請參見核心參數。

online_config_parts_to_merge

5

單次Compaction任務最多選取的輸入檔案數。

online_config_trigger_compaction_picker_threshold

5

候選檔案數達到該值才觸發一次Compaction,實際生效閾值取該值與online_config_parts_to_merge的較小者。

online_config_orc_max_total_size_to_merge_mb

256

列存表或行列共存表(列存部分)單次Compaction選取檔案的總大小上限,單位為MB,間接決定合并產物的檔案規模。

online_config_max_total_size_to_merge_mb

512

非列存資料路徑單次Compaction選取資料量上限,單位為MB。

online_config_deletion_compaction_ratio

30

檔案中被刪除行佔比超過該百分比時,觸發原地合并回收空間。

online_config_ignore_level_compaction

false

選檔案時忽略層級約束,允許跨層合并。用於清理每層都有幾個小檔案但都達不到觸發閾值的長尾小檔案。

online_config_bottom_level_compaction

true

是否允許最底層檔案參與Compaction。

說明

Worker級Compaction總並發(單個Worker節點上所有表共用的總並發上限)是執行個體級配置,不是表屬性,無法通過SET_TABLE_PROPERTY調整。確有需要請聯絡支援人員評估。

使用樣本

樣本一:大大量匯入前暫停Compaction,匯入後恢複

-- 1. 記錄原狀態(結果為空白表示原本無覆蓋值)
SELECT property_key, property_value FROM hologres.hg_table_properties
WHERE table_namespace = 'public' AND table_name = 'orders'
  AND property_key = 'online_config_compaction_semaphore';

-- 2. 暫停新的Compaction任務
CALL SET_TABLE_PROPERTY('public.orders', 'online_config_compaction_semaphore', '0');

-- 3. 執行大量匯入(期間觀察CPU、IO與匯入速度)

-- 4. 恢複:以下兩條二選一,按步驟1的查詢結果選擇
-- 4a. 步驟1結果為空白(原本無覆蓋值)時執行:
CALL SET_TABLE_PROPERTY('public.orders', 'online_config_compaction_semaphore', 'reset');
-- 4b. 步驟1查到原值時,寫回原值(把<ORIGINAL_VALUE>替換為步驟1的property_value):
-- CALL SET_TABLE_PROPERTY('public.orders', 'online_config_compaction_semaphore', '<ORIGINAL_VALUE>');

-- 5. 觸發積壓檔案合并(建議低峰執行)
VACUUM public.orders;

以下樣本二、樣本三涉及進階參數,建議在支援人員指導下執行,處置完成後恢複預設值。

樣本二:長尾小檔案清理

適用於每層檔案數都小於觸發閾值,合計幾十個小檔案無法合并的情境。

CALL SET_TABLE_PROPERTY('public.orders', 'online_config_ignore_level_compaction', 'true');
VACUUM public.orders;
-- 檔案數收斂後務必改回,否則長期寫入的表會放大Compaction頻率和CPU、IO佔用
CALL SET_TABLE_PROPERTY('public.orders', 'online_config_ignore_level_compaction', 'reset');

樣本三:單分區資料量大、檔案數多,希望合并成更大的檔案

CALL SET_TABLE_PROPERTY('public.orders', 'online_config_orc_max_total_size_to_merge_mb', '512');
VACUUM public.orders;
-- 檔案數收斂後恢複預設值
CALL SET_TABLE_PROPERTY('public.orders', 'online_config_orc_max_total_size_to_merge_mb', 'reset');
說明

關於VACUUM:Hologres中VACUUM <TABLE_NAME>的作用是觸發該表Flush並等待Compaction任務收斂,是發起一次自動Compaction的手段(尤其在online_config_compaction_semaphore從0恢複後,或修改策略參數後),不等價於Full Compaction,不會強制跨層合并所有檔案。

注意事項

  1. 參數名拼字不做校正:online_config_首碼後接任意名字都能設定成功,SQL不會報錯;寫錯參數名時系統匹配不到對應配置,將靜默無效。因此:

    • 參數名請從本文表格中複製,不要手動輸入。

    • 設定後應通過hologres.hg_table_properties查詢確認已寫入。

    • 應通過觀測手段(如hologres.hg_table_file_status返回的檔案數與檔案大小變化)確認行為確實發生了變化,不要僅憑SQL返回成功判斷生效。

  2. 物理分區表:對分區父表執行SET_TABLE_PROPERTY不會作用於已存在的分區子表,屬性唯寫入父表自身,而父表不持有資料,因此對存量分區的Compaction行為無實際效果。父表屬性只會被之後建立的分區子表在建立時一次性拷貝(含動態分區自動建立的子表),父表後續再修改也不會同步到已建子表。調整分區表的Compaction行為時,應直接對目標資料分割子表執行SET_TABLE_PROPERTY並逐個核對子表屬性;若希望未來新分區預設帶上該配置,可同時在父表上設定。

  3. 觀測與驗收:調優應有觀測閉環。可通過SELECT * FROM hologres.hg_table_file_status('<SCHEMA_NAME>.<TABLE_NAME>'::regclass);即時查看錶級檔案數與檔案大小(邏輯分區表可使用hologres.hg_partition_file_status按分區查看),通過hologres.hg_table_info(每日產出一次)複盤趨勢。調優驗收的核心判據為:檔案總數下降且平均檔案大小上升。合并過程中舊檔案延遲清理可能造成儲存量短時上升,屬正常現象。

遠端Compaction

從Hologres V5.0版本開始,您可以將Compaction任務的合并(Merge)階段卸載到獨立的計算群組(Warehouse)資源上執行,避免Compaction佔用主Warehouse的計算資源,從而保障線上查詢與寫入的效能穩定性。該功能稱為遠端Compaction(Compaction Offload)。

遠端Compaction使用限制

  1. 僅Hologres V5.0及以上版本支援遠端Compaction功能。

  2. 行存表、列存表和行列共存表均支援配置遠端Compaction,但部分內部Compaction策略不支援卸載,這類Compaction任務仍會在本地執行。

  3. 遠端Compaction僅負責Compaction的檔案合并階段,資料讀取和寫入仍在主Warehouse執行。

  4. 遠端Compaction執行失敗時,預設不回退到本地執行,Compaction任務直接失敗並由後台調度自動重試。如需開啟失敗回退本地的行為,請設定全域參數enable_compaction_offload_fallback為true。

配置compaction_resource

通過表屬性compaction_resource指定單張表的Compaction任務使用的目標Warehouse。設定後立即生效,無需重啟執行個體。

文法

-- 將表的Compaction卸載到指定Warehouse
CALL SET_TABLE_PROPERTY('<SCHEMA_NAME>.<TABLE_NAME>', 'compaction_resource', '<WAREHOUSE_NAME>');

-- 恢複為本Warehouse執行(預設)
CALL SET_TABLE_PROPERTY('<SCHEMA_NAME>.<TABLE_NAME>', 'compaction_resource', 'local');

使用樣本

-- 將public.orders表的Compaction卸載到名為readonly的Warehouse
CALL SET_TABLE_PROPERTY('public.orders', 'compaction_resource', 'readonly');

-- 查詢當前配置
SELECT property_key, property_value
FROM hologres.hg_table_properties
WHERE table_namespace = 'public'
  AND table_name = 'orders'
  AND property_key = 'compaction_resource';

查詢結果為空白或值為local表示該表使用本地Compaction。

查看Compaction運行狀態

您可以通過hologres.hg_show_compactions()函數查看當前正在運行和已完成的Compaction任務記錄,包括遠端執行的記錄。

說明

hologres.hg_show_compactions()的記錄為記憶體態,執行個體重啟後記錄會清空;運行態記錄按Compaction的結束時間保留,已進入終態的記錄預設保留600秒(10分鐘)。

-- 查看所有Compaction記錄
SELECT * FROM hologres.hg_show_compactions();

-- 查看遠端執行的Compaction記錄
SELECT table_name, status, compaction_reason, execution_location,
       warehouse_name, start_time, end_time, extended_cost, last_error
FROM hologres.hg_show_compactions()
WHERE execution_location = 'warehouse'
ORDER BY start_time DESC;

返回欄位說明如下。

欄位名

說明

database_name

資料庫名,僅返回當前資料庫的記錄。

schema_name

Schema名。

table_name

表名。

table_id

表ID。

shard_id

資料分區編號。

task_id

Compaction任務標識。

status

任務狀態,取值為QUEUED(排隊中)、RUNNING(執行中)、SUCCEEDED(成功)、FAILED(失敗)、CANCELLED(已取消)。

compaction_reason

觸發原因,例如kFullCompaction表示手動觸發Full Compaction,kLevelL0FilesNum表示自動觸發。

configured_resource

生效的compaction_resource配置,取值為local或目標Warehouse名稱。

execution_location

實際執行位置,local表示本地執行,warehouse表示遠端執行。

warehouse_name

遠端執行時使用的Warehouse名稱,本地執行時為空白。

start_time

任務進入調度隊列的時間。

end_time

任務進入終態的時間,運行中為空白。

progress

進度,預留欄位,當前固定為0。

extended_cost

各階段耗時,JSON格式。

extended_stats

輸入輸出統計資訊,JSON格式。

last_error

任務失敗時的錯誤資訊,成功時為空白。

遠端Compaction使用樣本

以下樣本展示如何將表的Compaction卸載到遠端Warehouse並手動觸發Full Compaction。

-- 1. 確保目標Warehouse已建立
--    (通過控制台或API建立Warehouse,例如名為readonly的Warehouse)

-- 2. 配置表使用遠端Compaction
CALL SET_TABLE_PROPERTY('public.lineitem', 'compaction_resource', 'readonly');

-- 3. 手動觸發Full Compaction(合并階段將在readonly Warehouse上執行)
SELECT hologres.hg_full_compact_table('public.lineitem');

-- 4. 等待Compaction完成
SELECT hologres.hg_wait_table_full_compact('public.lineitem');

-- 5. 查看遠端Compaction執行記錄
SELECT table_name, status, compaction_reason, execution_location,
       warehouse_name, start_time, end_time, extended_cost,
       extended_stats, last_error
FROM hologres.hg_show_compactions()
WHERE table_name = 'lineitem'
  AND execution_location = 'warehouse'
ORDER BY start_time DESC;