Hologres支援通過ALTER TABLE文法對部分表結構、表屬性、列屬性進行修改,但對於影響表格儲存體的屬性,則不支援通過ALTER TABLE文法進行修改。從Hologres V3.1版本起支援REBUILD文法。通過REBUILD文法,您可以靈活修改表的各類參數。本文為您介紹Hologres中REBUILD的使用方法。
文法
命令格式
ASYNC REBUILD TABLE [ IF EXISTS ] <table_name>
[ WITH ( <rebuild_parameter> [= <value>] [, ... ] )]
<action> [, ... ];
WHERE action IS ONE OF:
ADD [ COLUMN ] <column_name> <data_type> [ column_constraint [ ... ] ]
ALTER [ COLUMN ] <column_name> [ SET DATA ] TYPE <data_type> [ USING <expression> ]
ALTER [ COLUMN ] <column_name> SET DEFAULT <expression>
ALTER [ COLUMN ] <column_name> DROP DEFAULT
ALTER [ COLUMN ] <column_name> { SET | DROP } NOT NULL
ALTER PRIMARY KEY (<column_name> [, ...])
TO [LOGICAL] PARTITION [BY LIST(<column_name> [, <column_name>])]
SET ( <parameter> [= <value>] [, ... ] )
WHERE rebuild_parameter IS ONE OF:
keep_source
binlog_mode
rebuild_guc_<guc_name> = '<guc_value>'參數說明
參數 | 子項 | 說明 |
ASYNC | 聲明該REBUILD任務非同步執行,執行後會返回任務的 | |
table_name | 需要REBUILD的目標表名。 | |
column_name | 目標表的列名。 | |
data_type | 列的資料類型。 | |
action | ADD COLUMN | 增加列。支援增加非空列並設定預設值。 |
ALTER COLUMN TYPE | 修改列的資料類型。 | |
ALTER COLUMN SET/DROP DEFAULT | 為列設定/取消預設值。舊資料的NULL值不會改變。 | |
ALTER COLUMN SET/DROP NOT NULL | 為列設定/取消非空約束。 | |
ALTER PRIMARY KEY | 修改表的主鍵。如果新主鍵存在資料衝突,則會在非同步執行過程中報錯,請及時關注任務的執行狀態。 | |
TO [LOGICAL] PARTITION | 轉為邏輯/物理分區表,支援如下情境:
| |
SET ( <parameter> [= <value>]) | 修改表屬性,常用情境如下:
| |
WITH (<rebuild_parameter> [= <value>]) | 設定REBUILD任務相關參數,常用參數包括:
| |
注意事項
僅支援非同步ASYNC,無需長時間佔用串連。
REBUILD任務提交後會很快執行成功,並返回任務的
query_id。您可基於此query_id進一步查看REBUILD任務執行狀態。如果提交任務後一直未成功,可能是由於當前執行個體下的非同步調度任務較多,建議等待一段時間,待返回query_id後查看任務執行狀態。使用REBUILD功能修改表參數涉及底層資料重分布,需要消耗計算資源。因此,建議您在業務低峰期對錶執行REBUILD任務,或採用Serverless Computing資源進行此操作,以確保業務的穩定性。
REBUILD任務執行期間,其中一個步驟會將該表設為唯讀,在此階段時間內表無法進行寫入操作。
Rebuild暫不支援有Dynamic Table或物化視圖依賴的表,支援有普通視圖依賴的表。
如果需要修改多個參數,推薦在同一個REBUILD任務中一次性完成,以降低開銷。
物理分區表REBUILD後,動態分區管理屬性暫不支援繼承,需要在REBUILD結束後自行設定,包括:
分區父表的
auto_partitioning屬性。分區子表的
keep_alive等屬性。物理分區表REBUILD後,分區子表獨立設定的屬性暫不支援繼承,均與父表保持一致,如
bitmap_columns、dictionary_encoding_columns等。
REBUILD目前不支援以下情況的表:
設定了列屬性(如開啟JSONB類型列的列式儲存最佳化)或列約束(如向量列)的表。
設定了全文索引、全域二級索引的表。
含Serial、Bigserial類型列的表。
使用樣本
對未開啟Binlog的表執行REBUILD
-- 建立表並匯入資料
CREATE TABLE rebuild_test (
a TEXT,
b TEXT,
ds TEXT
);
INSERT INTO rebuild_test VALUES ('1', '1', '2025-04-01'), ('2', '2', '2025-04-02'), ('3', '3', '2025-04-03');
-- 新增非空列並設定預設值
ASYNC REBUILD TABLE rebuild_test ADD COLUMN c text NOT NULL DEFAULT 'a';
-- 將主鍵改為a列
ASYNC REBUILD TABLE rebuild_test ALTER PRIMARY KEY (a);
-- 使用Serverless資源執行Rebuild任務,為表設定distribution_key和clustering_key,並改為行列共存
ASYNC REBUILD TABLE rebuild_test
WITH (
rebuild_guc_hg_computing_resource = 'serverless'
)
SET (
distribution_key = 'a',
clustering_key = 'a',
orientation = 'row,column'
);
-- 將非分區錶轉為邏輯分區表,分區鍵設為ds(同時為ds列增加NOT NULL屬性)
ASYNC REBUILD TABLE rebuild_test
ALTER COLUMN ds SET NOT NULL,
TO LOGICAL PARTITION BY LIST(ds);對開啟Binlog的表執行REBUILD
REBUILD不支援保留錶的歷史Binlog資料,因此常規模式下,不支援對開啟了Binlog的表執行REBUILD。您需在REBUILD任務中配置binlog_mode參數,並按下文步驟執行REBUILD,以保證歷史Binlog資料已被下遊100%消費完成。
執行REBUILD。
ASYNC REBUILD TABLE rebuild_test WITH ( binlog_mode ) <your_action>;對已設定
binlog_mode參數的REBUILD任務,且在set_readonly步驟執行完成後,任務會自動暫停,可以通過如下SQL查詢進度。此時系統已將該表設為唯讀,該表無法寫入資料,也即沒有新的Binlog資料產生。postgres=# SELECT step, status, progress FROM hologres.rebuild_progress('<query_id>'); step | status | progress -------------------------------+--------+---------- prepare | done | 1/1 create_tmp_table | done | 1/1 get_src_table_snapshot | done | 1/1 insert | done | 1/1 set_readonly | done | 1/1 check_snapshot | | 0/1 re-insert | | - check_additional_child_table | | - create_additional_child_table | | - insert_additional_child_table | | - swap | | 0/1 (11 rows)等待下遊用戶端將存量Binlog消費完成,然後手動執行如下SQL繼續執行REBUILD任務。任務繼續執行期間,原表仍保持唯讀,不產生新的Binlog資料。
RESUME '<query_id>';REBUILD任務成功執行後,新表會自動開啟Binlog,此時可以重啟下遊Binlog消費任務,從
lsn = 0開始消費新表的Binlog。
監控與營運
查看REBUILD任務執行狀態
REBUILD任務以非同步方式執行,只要任務提交成功,任務本身便會返回成功狀態和query_id。您需要通過系統資料表hologres.rebuild_progress查看非同步執行的子任務狀態,全部成功才表示該表REBUILD完成。命令如下:
SELECT * FROM hologres.rebuild_progress('<rebuild_query_id>');系統資料表的列以及相關說明如下:
列名稱 | 說明 |
job_name | REBUILD任務的query_id。 |
step_id | 步驟ID。REBUILD的子任務按照此ID順序依次執行。 |
step | 步驟名:
|
status | 子任務狀態。
|
progress | 子任務進度: |
start_time | 子任務的開始時間。 |
end_time | 子任務的結束時間。 |
queryid | 子任務的query_id。 |
pid | 服務進程id。 |
message | 子任務的message。如果子任務報錯,則報錯資訊記錄在該欄位中。 |
結果樣本如下:

停止與重啟REBUILD任務
停止
REBUILD非同步任務。SUSPEND '<query_id>';繼續執行
CANCEL掉的非同步任務。RESUME '<query_id>';
REBUILD任務異常處理
如果REBUILD任務執行過程中發生報錯導致任務中斷,或您手動執行SUSPEND命令暫停了REBUILD任務,您可以通過RESUME命令繼續執行該REBUILD任務,也可以通過如下步驟結束REBUILD任務以恢複原表。
通過如下命令清理REBUILD過程中產生的暫存資料表。
CALL hg_clean_rebuild_tmp_tables('<query_id>');如果原表被REBUILD任務置為唯讀狀態後任務中斷,則需通過如下命令取消原表的唯讀狀態,恢複寫入。
ALTER TABLE <table_name> SET (readonly = false);