Liquid Table是Hologres V4.2.0版本新增的表存储模式,支持在表创建之后在线动态修改表所属的Table Group(即在线修改Shard数),整个过程无需重建表、无需停服、无需手工迁移数据。
功能概述
什么是Liquid Table
Liquid Table是Hologres提供的一种新型表存储模式,其最核心的能力是:
支持在表创建之后,在线动态修改表所属的Table Group(即在线修改Shard数),整个过程无需重建表、无需停服、无需手工迁移数据。
这一能力解决了传统数仓在数据量变化后无法低成本调整分片粒度的痛点:
痛点(传统模式) | Liquid Table解决方式 |
表初始Shard数选错,后续只能重建表 | 直接 |
数据量翻倍后查询并发不足,需迁移数据 | 在线扩容Shard数,后台自动重分布数据 |
缩容场景需重建表回收资源 | 在线缩容,自动Compaction到新Shard |
扩缩容期间业务不可用 | 修改期间读写请求不失败(写延迟可能有短暂上升,读延迟无影响) |
核心能力一览
在线Resharding:通过
ALTER TABLE在线调整分片数,业务无感。多存储格式:支持列存(column)、行存(row)、行列共存(row,column)。
数据重分布可控:可选自动后台重分布,或跳过重分布换取更快的元数据切换。
分区窗口控制:仅对最近N天/月的分区做重分布,降低IO开销。
跨功能兼容:可与Dynamic Table、GSI、全文索引、向量索引(HGraph)、Time Travel(MVCC)、Binlog、逻辑分区表等组合使用。
典型适用场景
业务初期Shard数估算保守,后期数据量增长快:初期16 shard,半年后扩容到64 shard。
大促/活动前的临时扩容:活动前扩容Shard提升查询并发,活动后缩容回收资源。
冷热表统一管理:历史冷分区缩容、活跃热分区扩容。
AI向量检索+弹性扩缩容:向量表随召回量增长动态扩容,索引自动保持可用。
前提条件
Hologres实例版本为V4.2.0及以上。如何查看实例版本,请参见SQL命令列表。
快速开始
创建Liquid Table
只需在建表语句中增加WITH (liquid_table = 'true')即可:
-- 列存(默认,OLAP场景)
CREATE TABLE my_table (
id INT NOT NULL,
name TEXT,
ts TIMESTAMPTZ,
PRIMARY KEY(id)
) WITH (liquid_table = 'true');
-- 行存(点查/高频更新场景)
CREATE TABLE my_row_table (
id INT NOT NULL,
name TEXT,
PRIMARY KEY(id)
) WITH (liquid_table = 'true', orientation = 'row');
-- 行列共存(点查+OLAP混合场景)
CREATE TABLE my_hybrid_table (
id INT NOT NULL,
name TEXT,
PRIMARY KEY(id)
) WITH (liquid_table = 'true', orientation = 'row,column');修改Shard数(Resharding)
通过修改表所在的Table Group完成Shard数变更:
-- 准备一个目标Table Group(如还没有)
CALL hg_create_table_group('tg_64', 64);
-- 一键扩容(同步生效)
ALTER TABLE my_table SET (table_group = 'tg_64');
-- 一键缩容
ALTER TABLE my_table SET (table_group = 'tg_16');修改完成后,ALTER命令立即返回,新写入和新查询使用新的Shard分布;存量数据由后台异步进行重分布。
验证当前Shard配置
-- 查看表当前所属Table Group与Shard数
SELECT property_key, property_value
FROM hologres.hg_table_properties
WHERE table_name = 'my_table'
AND property_key = 'table_group';
-- 查看Table Group元信息
SELECT * FROM hologres.hg_table_group_properties
WHERE tablegroup_name = 'tg_64';表属性参考
建表属性
属性 | 类型 | 默认值 | 说明 |
liquid_table | BOOLEAN | false | 是否启用Liquid Table。只能在建表时指定,老表无法直接ALTER启用。 |
orientation | STRING | column | 存储格式: |
liquid_table_enable_data_reorganization | BOOLEAN | true | Resharding后是否进行异步数据重分布。 |
liquid_table_reorganization_partition_window | STRING | 全部分区 | 仅对指定时间窗口内的分区做重分布,如 |
liquid_table_enable_data_reorganization取值建议
取值 | 行为 | 适用场景 |
true(默认) | Resharding后后台自动将旧数据重分布到新Shard,会有一定IO开销。 | 长期保留的活跃表,需要保证查询性能稳定。 |
false | 不做异步重分布,老数据查询性能可能下降。 | 即将归档/即将清空的表;扩容倍数较小、查询性能下降可接受的临时场景。 |
关于false模式的性能预期:Hologres内部会对单分区数据量做最多8倍的oversharding优化,典型2~4倍扩容场景下接近无损;当扩容倍数远超oversharding上限(例如16倍以上),未重分布的老数据查询性能最坏情况可能有等比下降。
分区窗口示例
-- 仅对最近30天分区做重分布(要求分区键为时间类型)
ALTER TABLE order_log SET (
table_group = 'tg_64',
liquid_table_reorganization_partition_window = '30 day'
);适用场景:超长保留的日志/事实表,历史冷分区不再访问,仅扩容当前热分区即可。
与其它功能的组合使用
兼容矩阵(V4.2.0)
功能组合 | 是否支持 | 备注 |
Dynamic Table作为Liquid Table | 支持 | Resharding后,Dynamic Table会进行一次全量重建,刷新延迟较长,后续会恢复为增量计算。 |
Liquid Table作为Dynamic Table的源表 | 支持 | Resharding后,Dynamic Table会进行一次全量重建,刷新延迟较长,后续会恢复为增量计算。 |
全局二级索引(GSI) | 支持 | V4.2已支持有GSI表的Resharding。 |
全文倒排索引(Fulltext) | 支持 | Resharding后索引保持可用。 |
向量索引(HGraph) | 支持 | Resharding后索引保持可用,近似检索结果稳定。 |
逻辑分区表(Logical Partition) | 支持 | 支持Resharding,自动分区正常。 |
Time Travel(MVCC) | 支持 | Resharding后历史数据仍可查。 |
Binlog | 需开启实验性GUC | 需开启实验性GUC,且对消费端有特殊要求。 |
物理分区表 | 不支持 | 不支持,请使用逻辑分区表替代。 |
物化视图(MV) | 不支持 | |
老表直接ALTER为Liquid Table | 不支持 | 必须通过Rebuild迁移。 |
MaxCompute直读Liquid Table | 不支持 | 暂不支持。 |
索引共存示例
-- 全文索引
CREATE INDEX ft_idx ON my_table USING FULLTEXT (content)
WITH (tokenizer = 'jieba');
-- GSI(全局二级索引)
CREATE GLOBAL INDEX gsi_name ON my_table(name) INCLUDE (ts);
-- 向量索引(通过vectors属性)
ALTER TABLE my_table SET (vectors = '{
"embedding": {
"algorithm": "HGraph",
"distance_method": "Cosine"
}
}');上述索引在Liquid Table上创建后,可直接执行ALTER TABLE ... SET (table_group = '...')进行Resharding,索引在新Shard上自动保持可用。
Resharding对业务的影响
本章是数仓开发与DBA在执行ALTER TABLE ... SET (table_group = ...)之前必须了解的内容。
Resharding在Hologres内部分为两个阶段:
元数据切换阶段(同步):
ALTER TABLE命令本身的执行过程,秒级完成,命令返回时新的Shard拓扑已生效。数据重分布阶段(后台异步):将旧Shard上的存量数据搬迁/合并到新Shard上,时长取决于数据量、扩缩容倍数与IO资源。
整个过程中业务读写请求预期不失败、不被阻塞;但写入延迟与老数据查询性能在Resharding期间会受到不同程度的影响,请务必按"会有可观测影响"来规划变更窗口与回滚预案,不要按"完全无感"来设计。
总体影响概览
维度 | 元数据切换阶段(秒级) | 数据重分布阶段(后台异步) |
业务可用性 | 预期不中断 | 预期不中断 |
请求是否失败 | 预期不失败(极端情况下可能出现少量瞬时错误,需依赖客户端重试) | 预期不失败 |
写入延迟 | 会出现明显抖动,量级从毫秒级到秒级,部分场景可能更长 | 后台IO占用可能引起延迟轻微上浮 |
写入吞吐 | 切换前后会有可观测的下降 | 与实例IO水位强相关,可能受到挤压 |
新数据查询性能 | 基本不受影响 | 基本不受影响(已按新Shard写入) |
老数据查询性能 | 可能立即下降 | 可能持续下降直至重分布完成,下降幅度可能较大,典型场景(如2倍扩缩容)可显著避免下降 |
索引可用性 | 保持可用 | 保持可用(性能可能受底层IO抢占影响) |
事务一致性 | 保证 | 保证 |
上表中的"预期不中断""预期不失败"等表述表示"在常见场景下预期表现良好",并非绝对保证。实际表现受实例规格、数据量、并发负载、扩缩容倍数等因素综合影响,强烈建议先在测试环境演练后再在生产执行。
对写入的影响
1)请求预期不会失败,但应做好客户端重试。Resharding期间写入请求预期被正常接收和处理。在元数据切换的瞬间,少量并发请求可能出现瞬时错误(例如连接超时),客户端/Connector应配置好自动重试。不会出现表持续不可写等长时间异常。
2)写入延迟会出现可观测的抖动,并非"无感"。元数据切换的瞬间,正在执行的写入需要等待新拓扑生效,延迟会明显上升。抖动量级通常在毫秒到秒级,但在以下情况下可能更长:
表上有未结束的长事务。
实例IO水位较高。
扩缩容跨度较大(例如从8 shard直接扩到128 shard)。
3)数据重分布阶段写入虽不被阻塞,但延迟可能轻微上浮。
后台数据搬迁会消耗实例IO,可能与前台写入争抢资源。
在IO水位较紧的实例上,写入延迟在重分布期间会较稳态略高,吞吐也可能略有下降。
建议在重分布期间持续观察实例IO与写入RT监控。
4)COPY/批量导入场景:大批量导入强烈建议在Resharding完全结束后再启动。在Resharding进行中导入大量数据,会显著延长后台重分布的实际完成时间,并放大写入延迟波动。
对查询的影响
1)查询请求预期不会失败、不会被阻塞。
元数据切换期间,新到达的查询会基于新拓扑执行。
已经在执行的查询会正常完成。
极端情况下,切换瞬间发起的查询可能因路径重路由而少量超时,需依赖客户端重试。
2)读延迟在切换瞬间通常较小,但不能视为"零影响"。
与写入相比,读路径受切换的影响通常较小。
切换瞬间命中的查询会经历路径重路由,对延迟敏感的实时接口仍可能感知到毫秒级抖动。
高QPS在线点查场景,建议视为"会有短暂抖动"来规划上游超时配置。
3)老数据的查询性能在数据重分布完成前可能显著下降:
场景 | 老数据查询性能变化 |
2的整数次幂扩容且Shard数是2的幂(32→64) | 由于内部oversharding优化,性能轻微下降 |
2的整数次幂扩容但Shard数非2的幂(20→40) | 内部oversharding优化仍然生效,但性能下降幅度大于Shard数是2的幂的情况 |
非2的整数次幂或非整数倍扩容 | 性能一定程度下降,一般不会超过2倍 |
极大幅度扩容(例如相比初始Shard数扩容16倍以上) | 按照扩容倍数/8等比下降,最坏情况下查询不可用窗口持续到重分布完成 |
整数倍缩容(32→16) | 查询并发度降低,性能轻微到中等下降 |
非整数倍缩容、Shard数非2的幂 | 性能一定程度下降,一般不会超过2倍 |
关于内部oversharding优化:Hologres引擎内部默认会后台异步对数据进行8倍的oversharding来缓解扩缩容带来的性能损失,在Shard数是2的幂的情况下,优化后的数据在Reshard场景下的查询性能损失如下表所示(生产环境中可能由于下面所列的原因导致优化后的数据比例低于100%,实际性能损失会比表中的略大)。
扩容倍数 k | 性能损失 |
缩容 50% (0.5x) | 0% |
1x | 0% |
1.5x (扩50%) | 12.5% |
2x | 0% |
2.5x | 15% |
3x | 25% |
4x | 0% |
5x | 40% |
6x | 50% |
7x | 75% |
8x | 0% |
一般情况下,大部分数据都经过了oversharding优化,典型扩缩容场景(2倍4倍)下接近无性能损失。但这只是缓解、不是根除。
如果Shard数非2的幂,典型扩缩容仍然会有一定程度的性能损失。
当扩容倍数超出oversharding容忍范围(例如超8倍),oversharding将无法有效避免性能损失。
当单Shard数据量过小时,可能不会应用oversharding优化。
当写入压力过大时,可能会有较多新写入的数据未应用oversharding优化。
当数据分布、Shard Key选择不理想时,性能下降幅度可能仍然明显。
请勿基于oversharding兜底假设"必然无损"。
4)新写入数据的查询性能基本不受影响。
新数据按新Shard拓扑写入,查询性能与稳态一致。
但若查询同时跨新老数据(例如时间范围扫描),整体RT仍受老数据下降的拖累。
5)索引(GSI/全文/向量)查询基本可用,但不能假设性能稳定。索引在Resharding后保持可用,但索引检索的物理IO仍可能与后台数据重分布争抢资源,RT在重分布期间可能高于稳态。大P99/长尾查询场景应密切监控。
对延迟敏感型业务的特别提醒
如果你的业务属于以下任意一种,请将Resharding视为一次有风险的变更,按变更管理流程处理:
业务类型 | 建议预案 |
实时大屏/BI即席查询 | 必须选业务低峰期执行;扩容尽量采用2的整数次幂;提前与业务方对齐变更窗口。 |
在线点查(CRM/风控/账号接口) | 行存表对Resharding性能影响相对更小,可优先采用;提前调高客户端超时;准备降级预案(限流、缓存兜底)。 |
Flink实时写入下游 | 提前调高Connector重试与背压参数;监控源端lag;变更窗口内做好上游堆积应对。 |
Binlog订阅下游 | 必须走Binlog场景特别说明章节流程;提前通知所有下游做无状态重启;预留消费追平时间。 |
高频UPSERT任务 | 必须选业务低峰期执行;扩容尽量采用2的整数次幂。 |
SLA严苛的OLAP报表 | 评估查询性能下降幅度后再决策;必要时拆分为多次小幅扩容。 |
影响时长预估(保守口径)
阶段 | 保守时长量级 | 影响范围 |
元数据切换 | 秒级,等待长事务时可能数分钟 | 写入延迟可观测抖动;少量瞬时请求可能需重试 |
数据重分布(小表<100 GB) | 数十分钟级 | 老数据查询性能持续下降;写入受IO抢占影响 |
数据重分布(中表100 GB~1 TB) | 数小时~半天起步 | 老数据查询性能持续下降;建议在低峰期完成 |
数据重分布(大表>1 TB) | 一天以上,部分场景需数天 | 老数据查询性能可能长时间下降;强烈建议配合 |
一句话总结
Resharding全程业务不中断、请求不失败,但要按"有影响"来规划:写入延迟会有可观测的抖动(毫秒~秒级,极端情况更长);老数据查询性能在后台数据重分布完成前会下降,幅度与扩缩容倍数及是否为2的整数次幂强相关,最坏情况下可能持续较长时间;典型场景下(2倍扩缩容)内部oversharding优化可以大幅缓解。
Binlog场景特别说明(重要)
如果你的Liquid Table开启了Binlog(binlog_level = 'replica'),Resharding行为与普通表存在差异,请务必通读本节再执行操作。
默认行为
开启Binlog的Liquid Table默认不允许Resharding,直接执行ALTER TABLE ... SET (table_group = ...)会报错。
强制Resharding步骤
-- 第1步:开启实验性GUC(仅当前session生效)
SET hg_experimental_enable_liquid_resharding_for_table_with_binlog = on;
-- 第2步:执行Resharding
ALTER TABLE my_binlog_table SET (table_group = 'tg_64');
-- 第3步:清理旧Shard上的delta数据
CALL hg_liquid_resharding_drop_non_current_delta('my_binlog_table');对Binlog消费任务的影响
行为 | 说明 |
Resharding期间 | Binlog消费任务(Connector)会报错并自动failover,但offset已错乱,作业进入不可用状态。 |
扩容(shard数变大) | failover大概率成功,但仍不可信,必须无状态重启。 |
缩容(shard数变小) | failover必定失败。 |
Resharding完成后 | 必须让消费任务无状态重启。 |
SQL查询Binlog | 只能查询到本次Resharding之后产生的Binlog,历史Binlog不可见。 |
DBA操作清单:1)通知所有Binlog下游消费方(Flink/Connector/自研订阅服务);2)在变更窗口内:暂停消费→执行Resharding→调用清理→下游无状态重启;3)切勿在不通知下游的情况下对带Binlog的Liquid Table做Resharding。
老表迁移到Liquid Table
由于老表无法直接ALTER为Liquid Table,需要通过以下两种方式之一完成迁移。
方式一:通过REBUILD转换(推荐)
从Hologres V4.2版本起,支持通过ASYNC REBUILD TABLE将普通表原地异步重建为Liquid Table,无需新建表和手动迁移数据,表名保持不变。REBUILD的详细用法请参见REBUILD。
-- 将普通表原地转换为Liquid Table(表名保持不变)
ASYNC REBUILD TABLE my_table
SET (
liquid_table = 'true'
);方式二:新建表迁移
新建一张Liquid Table,将老表数据迁移后,通过事务原子性重命名完成切换。
-- 1. 新建一个Liquid Table(保持与老表结构一致)
CREATE TABLE my_table_new (
id INT NOT NULL,
name TEXT,
ts TIMESTAMPTZ,
PRIMARY KEY(id)
) WITH (liquid_table = 'true');
-- 2. 数据迁移
INSERT INTO my_table_new SELECT * FROM my_table_old;
-- 3. 重建索引(如有)
CREATE INDEX ... ON my_table_new ...;
-- 4. 切换:使用事务原子性重命名
BEGIN;
ALTER TABLE my_table_old RENAME TO my_table_bak;
ALTER TABLE my_table_new RENAME TO my_table;
COMMIT;
-- 5. 验证后删除备份
DROP TABLE my_table_bak;使用限制
Hologres实例版本必须为V4.2.0及以上。如果您的实例是V4.2.0以下版本,请先升级实例。
liquid_table属性只能在建表时指定,已有的普通表不能通过ALTER TABLE直接转为Liquid Table。需通过Rebuild迁移模式完成转换。不支持物理分区表。对Liquid Table使用物理分区语法将报错
Physical partitioned table of liquid table is not supported。如需分区能力,请使用逻辑分区表替代。不支持在Liquid Table上创建物化视图(Materialized View)。如需类似能力,请使用Dynamic Table替代。
MaxCompute暂不支持直读Liquid Table。如果下游有MC直读需求,当前版本无法使用Liquid Table。
包含Liquid Table的实例无法降级到不支持该功能的旧版本。一旦创建了Liquid Table,请确认不会回退版本。
Resharding(修改Table Group)期间,写入延迟会出现可观测的抖动(毫秒~秒级,极端情况可能更长),老数据查询性能可能显著下降。
ALTER TABLE ... SET (table_group = ...)必须等待该表上当前所有DML运行完成才能开始执行。大DML/长事务存在期间,ALTER命令会被阻塞。liquid_table_reorganization_partition_window参数仅对单个时间类型的分区键生效。多分区键或非时间类型分区键不支持此参数。开启了Binlog的Liquid Table默认不允许Resharding。如需执行,必须开启实验性GUC
hg_experimental_enable_liquid_resharding_for_table_with_binlog,并确保Binlog下游可承受无状态重启。Resharding后,通过SQL查询Binlog只能获取到最近一次Resharding后产生的增量数据,历史Binlog不可见。
仍有表attach在Table Group中时,不能删除该Table Group。
Liquid Table的Resharding是不可逆操作——元数据切换完成后不存在"回滚到旧Table Group"的快捷途径;如需回退,只能再次ALTER到原TG。
当前版本暂未提供Resharding进度查询接口,无法实时查看数据重分布完成百分比。
最佳实践
何时启用Liquid Table
强烈建议启用:
数据量预期在生命周期内会发生显著变化(增长5倍以上)。
业务有大促/秒杀/季节性流量波动,需弹性Shard。
实时数仓的核心明细表/宽表。
AI向量检索表。
可暂缓启用:
数据量稳定的小维表。
强依赖物理分区表的场景。
强依赖MaxCompute直读的场景。
Shard数规划经验
单Shard数据量 | 建议动作 |
< 10 GB | 关注是否过度分片,可考虑缩容 |
10 GB~50 GB | 健康区间 |
50 GB~100 GB | 关注查询性能,准备扩容 |
> 100 GB | 建议立即扩容 |
Resharding执行建议
避开高峰期:选择业务低峰窗口执行ALTER。
避开大DML:先确认无大批量INSERT/UPDATE/DELETE在跑。
整数倍扩缩容优先:例如16→32→64,比16→50性能更平滑。
大表用分区窗口:对超长生命周期分区表使用
liquid_table_reorganization_partition_window限制重分布范围。Binlog表全链路演练:先在测试环境完整演练Resharding+下游重启。
监控建议
重分布完成前:定期对比新老Shard上的查询RT,确认重分布进度。
实例资源水位:Resharding期间会有额外的IO开销,建议关注CPU/IO使用率。
Binlog Cursor:对开启Binlog的表,关注下游消费lag。
FAQ
Q1:Liquid Table和普通表有什么本质区别?
A:内部采用base + delta的存储模型,使得修改Shard时无需重写全部数据。普通表在创建时Shard分布即固化,修改Shard必须重建表。
Q2:Resharding会不会丢数据?
A:不会。Resharding期间读写请求保持事务一致性,已写入的数据不会丢失。验收测试中Resharding前后数据完整性100%保持。
Q3:Resharding期间业务会不会不可用?
A:Resharding期间业务不中断、请求预期不失败,但写入延迟会有可观测抖动(毫秒到秒级),老数据查询性能在重分布完成前可能下降。详见「Resharding对业务的影响」章节。
Q4:Resharding需要多久?
A:ALTER TABLE命令本身同步且快速返回(秒级),实际数据重分布是后台异步进行,时长取决于数据量和扩容倍数。
Q5:可以反复Resharding吗?
A:可以。但每次Resharding都会触发后台数据重分布,建议规划好目标Shard数后一次到位,避免频繁切换。
Q6:能否查询Resharding进度?
A:当前版本暂未提供官方进度查询接口,可通过观察后台Compaction任务和查询RT间接判断;该能力在产品Roadmap中。
Q7:缩容是否会立即释放存储空间?
A:缩容会立即将数据归并到更少的Shard,存储空间在后台Compaction完成后释放。
Q8:Liquid Table是否会带来额外存储开销?
A:base + delta模式在delta未被合并前会有少量额外开销,后台Compaction会自动消除。整体存储开销与普通表持平。
Q9:可以同时存在多种索引(GSI+全文+向量)吗?
A:可以。V4.2已支持多索引共存的Liquid Table进行Resharding。
Q10:使用了Liquid Table后,能不能回退到普通表?
A:可以通过反向Rebuild:新建一张普通表,INSERT INTO ... SELECT迁移数据,再RENAME切换。但实例本身一旦使用了Liquid Table,不支持降级到不支持该功能的旧版本。
速查清单
-- 建表
CREATE TABLE t (...) WITH (liquid_table = 'true');
-- Resharding
ALTER TABLE t SET (table_group = 'tg_xxx');
-- 控制是否后台重分布
ALTER TABLE t SET (liquid_table_enable_data_reorganization = 'false');
-- 仅重分布最近30天分区
ALTER TABLE t SET (
table_group = 'tg_xxx',
liquid_table_reorganization_partition_window = '30 day'
);
-- Binlog表Resharding(实验性,需配合下游重启)
SET hg_experimental_enable_liquid_resharding_for_table_with_binlog = on;
ALTER TABLE t SET (table_group = 'tg_xxx');
CALL hg_liquid_resharding_drop_non_current_delta('t');