當離線匯入大量資料或大量執行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,示意圖如下所示:

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、小檔案治理、後台資源爭搶處置等情境。
表級參數使用限制
僅Hologres V4.0及以上版本支援本章節所述的表級Compaction參數。低於V4.0的執行個體設定這些參數不會生效,請先升級執行個體。
本章節所述參數僅對列存表和行列共存表生效,其中行列共存表僅列存部分受這些參數控制。對行存表設定這些參數不會產生效果。
絕大多數情境下自動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的檔案選擇策略和觸發頻率,與並發參數存在耦合,建議在支援人員指導下使用,處置完成後恢複預設值。
參數 | 預設值 | 含義 |
| 8 | 邏輯分區表單個調度單元的Compaction並發封頂值,與 |
| 5 | 單次Compaction任務最多選取的輸入檔案數。 |
| 5 | 候選檔案數達到該值才觸發一次Compaction,實際生效閾值取該值與 |
| 256 | 列存表或行列共存表(列存部分)單次Compaction選取檔案的總大小上限,單位為MB,間接決定合并產物的檔案規模。 |
| 512 | 非列存資料路徑單次Compaction選取資料量上限,單位為MB。 |
| 30 | 檔案中被刪除行佔比超過該百分比時,觸發原地合并回收空間。 |
| false | 選檔案時忽略層級約束,允許跨層合并。用於清理每層都有幾個小檔案但都達不到觸發閾值的長尾小檔案。 |
| 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,不會強制跨層合并所有檔案。
注意事項
參數名拼字不做校正:
online_config_首碼後接任意名字都能設定成功,SQL不會報錯;寫錯參數名時系統匹配不到對應配置,將靜默無效。因此:參數名請從本文表格中複製,不要手動輸入。
設定後應通過
hologres.hg_table_properties查詢確認已寫入。應通過觀測手段(如
hologres.hg_table_file_status返回的檔案數與檔案大小變化)確認行為確實發生了變化,不要僅憑SQL返回成功判斷生效。
物理分區表:對分區父表執行
SET_TABLE_PROPERTY不會作用於已存在的分區子表,屬性唯寫入父表自身,而父表不持有資料,因此對存量分區的Compaction行為無實際效果。父表屬性只會被之後建立的分區子表在建立時一次性拷貝(含動態分區自動建立的子表),父表後續再修改也不會同步到已建子表。調整分區表的Compaction行為時,應直接對目標資料分割子表執行SET_TABLE_PROPERTY並逐個核對子表屬性;若希望未來新分區預設帶上該配置,可同時在父表上設定。觀測與驗收:調優應有觀測閉環。可通過
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使用限制
僅Hologres V5.0及以上版本支援遠端Compaction功能。
行存表、列存表和行列共存表均支援配置遠端Compaction,但部分內部Compaction策略不支援卸載,這類Compaction任務仍會在本地執行。
遠端Compaction僅負責Compaction的檔案合并階段,資料讀取和寫入仍在主Warehouse執行。
遠端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;