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任务中一次性完成,以降低开销。
使用示例
对未开启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);