Hologres V3.1版本支援邏輯分區表。相比於物理分區表,邏輯分區表可有效解決表數量過多、中繼資料膨脹而可能產生的穩定性問題。本文為您介紹如何將物理分區表遷移為邏輯分區表。
使用情境
針對如下情境建議您由物理分區表遷移為邏輯分區表:
Table Group下的物理分區表的子分區表數量多(例如大於10000張),中繼資料規模大。
每日新增分區數量多,DDL操作次數多。
遷移方案
方案一:先雙寫驗證再遷移業務
使用該方案進行分區表遷移,能夠最大程度降低對業務的影響,保證業務穩定性。流程如下:
停止原物理分區表資料匯入任務,建立邏輯分區表,並完成存量資料移轉。存量資料移轉方案,詳情請參見存量資料移轉。
如果表結構不需改變,且資料量適中,推薦使用CLONE文法。
如果表結構需要改變,或資料量較大、資料移轉壓力大,推薦使用手動遷移方式。
對新邏輯分區表建立資料匯入任務,同時啟動新老分區表的資料匯入任務(即雙寫)。
新邏輯分區表業務驗證。
業務遷移,通過如下兩個方式。
(推薦)將查詢隨即轉移到新邏輯分區表上,即修改查詢任務的目標表名為新邏輯分區表名,同時按需增加分區過濾條件。
將新邏輯分區表RENAME為原物理分區表名,並修改對原物理分區子表的寫入與查詢任務,改為寫入與查詢父表並增加分區過濾條件。命令如下:
BEGIN; ALTER TABLE <source_table_name> RENAME TO <source_table_name_archive>; ALTER TABLE <target_table_name> RENAME TO <source_table_name>; COMMIT;
營運任務適配。
(不推薦)方案二:快速遷移
若您能夠接受較長的變更時間視窗,並且允許部分讀寫任務出現失敗,則可以採用REBUILD文法進行遷移。流程如下:
停止原物理分區表資料匯入任務。
使用Rebuild文法完成存量資料移轉。詳情請參見REBUILD文法。
修改匯入任務,並啟動匯入任務。
查詢任務適配。
營運任務適配。
分區表遷移
表結構轉換
邏輯分區表與原物理分區表相比,在建表語句方面,涉及如下轉換工作。
DDL需增加LOGICAL關鍵字,並增加分區鍵的NOT NULL約束。
(可選)物理分區表僅支援一個分區鍵,邏輯分區表支援最多兩個分區鍵,您可根據需要增加分區鍵數量。
樣本如下。
建立物理分區表:
BEGIN; CREATE TABLE user_profile ( a TEXT, b TEXT, ds TEXT ) PARTITION BY LIST (ds); CREATE TABLE user_profile_202503 PARTITION OF user_profile FOR VALUES IN ('202503'); CREATE TABLE user_profile_202504 PARTITION OF user_profile FOR VALUES IN ('202504'); COMMIT;建立邏輯分區表:
保持1個分區鍵。
CREATE TABLE user_profile_lp_1 ( a TEXT, b TEXT, ds TEXT NOT NULL) LOGICAL PARTITION BY LIST (ds);改為年和月,保持2個分區鍵。
CREATE TABLE user_profile_lp_2 ( a TEXT, b TEXT, yy TEXT NOT NULL, mm TEXT NOT NULL) LOGICAL PARTITION BY LIST (yy, mm);
表映射關係
在表屬性、分區屬性等方面,邏輯分區表與物理分區表的映射關係如下表:
如果原物理分區表分區鍵使用TEXT等非時間類型,且使用了動態分區管理功能,則轉換為邏輯分區表時,暫不支援到期自動清理(參數partition_expiration_time)、到期自動轉冷(參數partition_keep_hot_window)。
模組 | 功能 | 物理分區表 | 邏輯分區表 |
父表動態分區管理 | 開啟動態分區管理功能 | auto_partitioning_enable | 無對應參數,無需關注。 |
時間單位 | auto_partitioning_time_unit | 無需單獨配置,但僅支援時間類型分區。 | |
時區 | auto_partitioning_time_zone | 無對應參數,無需關注。 | |
預建立分區數量 | auto_partitioning_num_precreate | 無對應參數,無需關注。 | |
保留歷史分區數量 | auto_partitioning_num_retention | 通過partition_expiration_time實現到期自動清理。 | |
保留熱分區數量 | auto_partitioning_num_hot | 通過partition_keep_hot_window實現到期自動轉冷。 | |
動態分區管理調度時間 | auto_partitioning_schd_start_time | 無對應參數,無需關注。 | |
分區子表日期時間格式 | auto_partitioning_time_format | 無對應參數,無需關注。 | |
子表/子分區管理 | 分區是否保留 | keep_alive | keep_alive |
分區是否保持冷/熱存 | storage_mode | storage_mode | |
Binlog | 父表Binlog開關 | binlog_level | binlog_level |
父表Binlog生命週期 | binlog_ttl | binlog_ttl | |
按分區動態管理Binlog | 不支援。 | partition_generate_binlog_window | |
子分區Binlog開關 | 繼承父表,不支援修改。 | generate_binlog | |
子分區Binlog生命週期 | 子表支援修改。 | 繼承父表,不支援修改。 | |
索引及其他表屬性 | 子分區bitmap_columns | 子表支援修改。 | 繼承父表,不支援修改。 |
子分區dictionary_encoding_columns | 子表支援修改。 | 繼承父表,不支援修改。 | |
orientation、table_group等其他表屬性 | 繼承父表,不支援修改。 | 繼承父表,不支援修改。 | |
primary key、distribution_key、clustering_key等其他索引 | 繼承父表,不支援修改。 | 繼承父表,不支援修改。 |
存量資料移轉
CLONE
如果您的表結構不需改變,且資料量適中,推薦使用CLONE文法。
該命令會自動建立一張新的邏輯分區表,並將原表資料複製到新表,表結構完全相同。原物理分區表不刪除。
如果原表有即時寫入任務:
CLONE前,建議手動停止即時寫入任務。
CLONE完成後,建議建立即時寫入任務,讓即時寫入的資料來源同時寫入CLONE前後的兩張表,以保證兩張表資料一致且完整。
遷移完成後,充分驗證新老分區表的資料與功能情況,完成匯入任務、查詢任務、營運任務適配後,清理原物理分區表。
使用樣本:
CALL hg_clone_to_logical_partition('user_profile', 'user_profile_logical');如果遷移資料較多,已耗用時間很長,推薦使用ASYNC命令在後台執行。命令提交成功後會返回CALL對應的query_id,可以使用此query_id在Query洞察進一步查看非同步任務的執行狀況。
SET statement_timeout = 0;
ASYNC CALL hg_clone_to_logical_partition('user_profile', 'user_profile_logical');手動遷移
如果您的表結構需要改變,或資料量較大、資料移轉壓力大,推薦使用手動遷移方式,以便更靈活地控制遷移節奏。
該方式需要手動建立新的邏輯分區表,並將原表資料複製到新表。由於手動建表,因此可靈活最佳化表屬性,靈活控制遷移節奏。
如果原表有即時寫入任務:
匯入資料前,建議手動停止即時寫入任務。
匯入資料完成後,建議建立即時寫入任務,讓即時寫入的資料來源同時寫入匯入資料前後的兩張表,以保證兩張表資料一致且完整。
遷移完成後,充分驗證新老分區表的資料與功能情況,完成匯入任務、查詢任務、營運任務適配後,清理原物理分區表。
遷移步驟:
建立表。
詳情請參見本文建立邏輯分區表。
匯入歷史資料,推薦使用hg_insert_overwrite。
CALL hg_insert_overwrite('logical_partition_table', '{20250601, 20250602}'::text[], 'SELECT * FROM tb');
REBUILD文法(不推薦使用)
若您能夠接受較長的變更時間視窗,並且允許部分讀寫任務出現失敗,則可以採用REBUILD文法進行遷移。詳情請參見REBUILD(Beta)。
注意事項如下:
使用REBUILD功能遷移分區表,遷移後的邏輯分區表的表名不變。原物理分區表的表名會改為
tmp_rebuild_old_<query_id>_<unique_id>_<table_name>。遷移完成後,需要進一步完成剩餘事項適配,包括匯入任務、查詢任務、營運任務適配。
適配工作完成前,相關任務可能由於相容性產生報錯,因此不推薦使用該方式遷移分區表。
使用樣本:
-- 為分區欄位增加NOT NULL約束
ASYNC REBUILD TABLE user_profile ALTER ds SET NOT NULL;
-- 物理分區錶轉換為邏輯分區表,並保留原物理分區表
ASYNC REBUILD TABLE user_profile WITH (keep_source) TO logical partition;匯入任務適配
如果原物理分區表的資料匯入任務為匯入父表(通過Fixed Plan),則無需修改任務。
如果原物理分區表的資料匯入任務為匯入子表,則需要做如下適配:
刪除建立分區子表的語句。邏輯分區表沒有物理子表,無需手動建立。
匯入任務中的子表的表名改為邏輯分區表的父表的表名。
情境一:新增子表/子分區並匯入資料
-- 原物理分區表匯入任務
CREATE TABLE user_profile_202505 PARTITION OF user_profile FOR VALUES IN ('202505');
INSERT INTO user_profile_202505 SELECT a, b, ds FROM <source_table> WHERE ds = '202505';
-- 新邏輯分區表匯入任務
INSERT INTO user_profile_lp_1 SELECT a, b, ds FROM <source_table> WHERE ds = '202505';情境二:回刷子表/子分區資料
如果原物理分區表使用預存程序hg_insert_overwrite實現子表資料回刷,並且一次回刷多張子表,當遷移為邏輯分區表並使用原生INSERT OVERWRITE文法後,建議按分區分割任務實現串列。詳情請參見INSERT OVERWRITE。
-- 原物理分區表回刷任務(通過建立暫存資料表實現INSERT OVERWRITE)
-- 建立暫存資料表並匯入資料
CREATE TABLE tmp_user_profile_202505(a text, b text, ds text);
INSERT INTO tmp_user_profile_202505 SELECT a, b, ds FROM <source_table> WHERE ds = '202505';
-- 暫存資料表RENAME並ATTACH到父表
BEGIN;
DROP TABLE IF EXISTS user_profile_202505;
ALTER TABLE tmp_user_profile_202505 RENAME TO user_profile_202505;
ALTER TABLE user_profile ATTACH PARTITION user_profile_202505 FOR VALUES IN ('202505');
COMMIT;
-- 原物理分區表回刷任務(通過hg_insert_overwrite命令)
CALL hg_insert_overwrite('user_profile' , '202505', $$SELECT a, b, mm FROM <source_table> WHERE ds='202505'$$);
-- 新邏輯分區表回刷任務(通過原生Insert Overwrite文法)
INSERT OVERWRITE user_profile_lp_1 PARTITION (ds = '202505') SELECT a, b, ds FROM <source_table> WHERE ds='202505';查詢任務適配
如果原物理分區表的資料查詢任務為查詢父表,則無需修改任務。
如果原物理分區表的資料查詢任務為查詢子表,則需改為查詢父表,並增加分區過濾條件。樣本如下:
-- 原物理分區表的子表查詢任務 SELECT * FROM user_profile_202504; -- 原邏輯分區表的查詢任務 SELECT * FROM user_profile_lp_1 WHERE ds = '202504';
營運任務適配
對於原物理分區表與新邏輯分區表的日常營運任務,也可能存在差異。部分情境對比如下:
查詢類別 | 物理分區表 | 邏輯分區表 | 說明 |
查詢父表DDL | 函數 | 無差異。 | |
查詢父表的表屬性 | 系統資料表 | 無差異。 | |
查詢分區列表 | 系統資料表 | 有差異。 | |
查詢分區屬性 | 系統資料表 | 系統資料表 | 有差異。 |
查詢父表格儲存體 | 系統資料表 | 系統資料表 | 有差異。 |