全部產品
Search
文件中心

Hologres:REBUILD

更新時間:Jan 15, 2026

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任務非同步執行,執行後會返回任務的query_id,您可以通過query_id監控任務的執行狀態 。暫不支援同步執行。

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>])

修改表屬性,常用情境如下:

  • 修改分布鍵distribution_key

  • 修改分段鍵event_time_column

  • 修改聚簇索引clustering_key

  • 修改表格儲存體格式orientation:行存、列存、行列共存轉換。

  • 修改表所屬的table_group

  • 其他表屬性均支援修改。

  • 位元影像索引bitmap_columns、字典編碼列dictionary_encoding_columns無需通過REBUILD修改,直接使用ALTER TABLE文法即可。

WITH (<rebuild_parameter> [= <value>])

設定REBUILD任務相關參數,常用參數包括:

  • keep_source:無需設定value。轉換後不刪除原表,原表會改名為tmp_rebuild_old_<query_id>_<unique_id>_<table_name>

  • binlog_mode : 無需設定value。可以對開啟Binlog的表執行Rebuild,需參考下文的使用樣本進行操作,以免丟失Binlog資料。

  • rebuild_guc_hg_computing_resource='serverless':使用Serverless資源執行本次REBUILD任務,無需佔用本執行個體資源,任務更加穩定。

  • rebuild_guc_<guc_name>='<guc_value>':其他GUC參數均可在此設定,詳情請參見GUC參數

注意事項

  • 僅支援非同步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_columnsdictionary_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%消費完成。

  1. 執行REBUILD。

    ASYNC REBUILD TABLE rebuild_test 
    WITH (
      binlog_mode
    )
    <your_action>;
  2. 對已設定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)
  3. 等待下遊用戶端將存量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

步驟名:

  • prepare:任務準備。

  • create_tmp_table:建立暫存資料表。

  • get_src_table_snapshot:擷取原表的資料快照。

  • insert:存量資料匯入到暫存資料表。

  • set_readonly:將待REBUILD的表設為唯讀,資料停寫。

  • check_snapshot:檢查此時表的資料快照是否與第三步擷取的相同,如果不同則進入re-insert步驟。

  • re-insert:增量資料匯入。

  • check_additional_child_table:檢查從開始REBUILD到現在是否有新的子表被使用者建立,僅針對物理分區表。

  • create_additional_child_table:為暫存資料表建立潛在的新子表,僅針對物理分區表。

  • insert_additional_child_table:存量資料匯入到新臨時子表,僅針對物理分區表。

  • swap:暫存資料表替代原表。

status

子任務狀態。

  • done:已完成。

  • doing:正在執行。

  • NULL:無需執行該步驟,或目前無法得知是否需要執行該步驟。

  • error:執行失敗。需檢查message欄位中的報錯資訊。

progress

子任務進度:m/n。n為需要執行的substep個數(一般和分區個數正相關),m為當前已執行的substep個數。

start_time

子任務的開始時間。

end_time

子任務的結束時間。

queryid

子任務的query_id。

pid

服務進程id。

message

子任務的message。如果子任務報錯,則報錯資訊記錄在該欄位中。

結果樣本如下:

opopo

停止與重啟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);