TDengine RSMA 降采样存储按时间窗口自动下采样并压缩历史数据的完整指南【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine本文围绕 TDengine 企业版 v3.3.8.0 起提供的降采样存储功能 RSMARollup SMASmall Materialized Aggregation展开讲解其“自动触发 手动重算”两种工作机制、CREATE/ALTER/DROP RSMA的全部语法与参数约束、ROLLUP手动计算与SHOW RETENTIONS任务观测方法并结合仓库源码与测试用例印证参数校验规则与底层实现位置。读完本文你可以为“原始数据短保存、历史数据长保存”的工业场景设计一套完整的降采样存储方案。什么是 RSMA以及它解决什么问题RSMA 是按时间窗口对用户数据做降采样downsampling并存储的一种小型物化聚合SMA。它适用于这样的场景原始数据保存时长较短如本地 SSD 只保留 30 天而降采样数据保存时长较长如低成本存储保留数年。由于降采样数据体积远小于原始数据这既能减少磁盘占用又能在查询历史数据时直接扫描降采样结果提升响应速度。基本逻辑自动触发数据由低存储层级向高存储层级迁移时自动完成降采样存储由数据库KEEPkeep0/keep1/keep2控制。多级存储的规划思路参见多级存储说明。手动触发适用于「降采样数据更新或删除后需要重算」以及「已迁移至目标存储层级但尚未降采样」等场景。语义透明RSMA 不改变查询语义。关键行为与限制降采样完成后会删除对应原始数据文件降采样数据与原始数据的时间范围不重叠。1 / 2 / 3 存储层级的数据均支持更新和删除但更新与删除不会自动触发重算。当 2 / 3 层存在乱序写入时已聚合窗口内可能出现多条数据手动重算会同时基于聚合结果与乱序数据再次聚合此时AVG/FIRST/LAST等函数的结果可能不准确而MIN/MAX/SUM不受影响。存在 RSMA 时仍可做表结构修改、建表删表这些操作在计算与重算时延迟生效。RSMA 与 S3 迁移存在依赖S3 首次迁移时需先完成 RSMA 计算。以上行为在测试用例 test_rsma.py 中有对应验证例如用例通过show retentions轮询等待 trim / rollup 任务完成后再校验降采样结果行数印证了“降采样完成后原始文件被替换”的流程。创建 RSMA语法如下CREATE RSMA [IF NOT EXISTS] rsma_name ON [dbname.]table_name FUNCTION([func_name(col_name)[, ...]]) INTERVAL(interval1[, interval2]);参数约束逐条说明命名RSMA 名称命名规则与表名相同最大长度 193。同一超级表上只能存在一个 RSMA测试用例中重复创建会报Rsma already exists in the table。作用对象只能基于超级表创建。普通表、子表、系统表均不可对应错误Rsma must be created on super table。若超级表列包含BLOB/MEDIUMBLOB类型暂不支持 RSMA。函数列表支持MIN、MAX、SUM、AVG、FIRST、LAST。每个函数参数必须为 1 个且为非主键普通列不能为标签列。非数值类型列如bool、varchar不能指定SUM/AVG等数值聚合函数复合主键列仅支持FIRST/LAST未显式指定时默认亦为LAST。FUNCTION子句可省略或为空未显式指定函数的列默认使用LAST。test_rsma.py 中的错误路径用例可以直观看到这些约束的报错信息例如表达式参数min(c01)报only one non-primary key column allowed、重复列last(c0)报Duplicated column not allowed、avg(c4)bool 列报Invalid function para type。INTERVAL至少 1 个、至多 2 个 interval。取值范围为[0, DURATION]按数据库精度换算且至少一个非 0。interval1 0表示 level 2 不降采样interval2 0表示 level 3 不降采样。时间单位须显式指定可用单位为a毫秒、b纳秒、u微秒、s秒、m分钟、h小时、d天不支持w/n/y。两个 interval 的关系当均为正数时须满足interval1 interval2且interval2为interval1的整数倍二者均不得超过数据库DURATION。DURATION必须能被各正数 interval 整除以降低跨文件边界计算的复杂度、资源消耗和碎片化。正确性保证interval2为interval1整数倍可保证MIN/MAX/SUM/FIRST/LAST相对原始数据的正确性AVG仍可能存在误差。测试用例中这些校验规则全部有对应断言如interval(0m,0m)报At least one interval value for rsma should be greater than 0、interval(2m,3m)报Second interval value for rsma should be a multiple of first interval且错误信息中会给出换算后的精度值与合法范围便于排查。示例摘自测试用例CREATE RSMA rsma7 ON d0.stb1 FUNCTION(min(c0), max(c1), avg(c2), sum(c3), first(c4), last(c5), first(c6)) INTERVAL(1m, 5m);修改与删除 RSMAALTER RSMA [IF EXISTS] [db_name.]rsma_name FUNCTION ([func_name(col_name)[, ...]]); DROP RSMA [IF EXISTS] [db_name.]rsma_name;ALTER RSMA用于修改列的聚合函数主要用于新增列场景。约束是只允许修改此前未显式指定函数的列。未指定函数的列默认聚合为LAST修改可能导致前后聚合语义不一致操作前请确认业务需求。测试用例中的两条断言印证了这一点对已显式指定函数的列执行alter rsma rsma1 function(max(c0))会报Rsma func already specified for column: c0而对此前未指定函数的c4列补上first(c4)则成功。DROP RSMA删除后再重建同样可能造成聚合函数前后不一致操作前请确认业务需求。此外删除超级表或数据库会级联删除其下的 RSMA——mndRsma.h 中声明的mndDropRsmaByStb/mndDropRsmasByDb即对应在建表删表、删库事务中清理 RSMA 元数据的入口测试用例也验证了drop stable stb1与drop database d0后show rsmas行数为 0。查看 RSMA显示单个 RSMA 的创建语句SHOW CREATE RSMA [db_name.]rsma_name;示例输出taos SHOW CREATE RSMA rsma7\G; *************************** 1.row *************************** RSMA: rsma7 Create RSMA: CREATE RSMA rsma7 ON d0.stb1 FUNCTION(min(c0),max(c1),avg(c2),sum(c3),first(c4),last(c5),first(c6)) INTERVAL(60000a,300000a) Query OK, 1 row(s) in set (0.005250s)该语句的实际价值在于输出的语句可直接复制重放。测试用例中正是用show create rsma拿到的语句去执行CREATE RSMA重建对象并逐字节比对语句内容验证了输出的完整往返一致性。显示所有 RSMASHOW [db_name.]RSMAS; SELECT * FROM information_schema.ins_rsmas [WHERE db_name {db_name}];示例输出taos SHOW RSMAS\G; *************************** 1.row *************************** rsma_name: rsma7 rsma_id: 4785417934375247480 db_name: d0 table_name: stb1 table_type: SUPER_TABLE create_time: 2025-10-03 23:03:57.577 interval: 60000a,300000a func_list: min(c0),max(c1),avg(c2),sum(c3),first(c4),last(c5),first(c6) Query OK, 1 row(s) in set (0.014238s)注意func_list只显示创建时通过FUNCTION显式指定的函数默认LAST的列不会出现在其中。手动计算 RSMAROLLUPROLLUP DATABASE db_name [start_opt] [end_opt] ROLLUP [db_name] VGROUPS IN (vgroup_ids) [start_opt] [end_opt] start_opt :: START WITH timestamp_literal -- 如 YYYY-MM-DD HH:MM:SS | START WITH unix_timestamp -- 如 1672531200 | START WITH TIMESTAMP timestamp_literal end_opt :: END WITH timestamp_literal | END WITH unix_timestamp | END WITH TIMESTAMP timestamp_literal示例taos ROLLUP DATABASE d0 START WITH 2025-12-30 10:00:00.000 END WITH 2025-12-31 10:00:00.000; result | id | reason | accepted | 53584270 | success | Query OK, 1 row(s) in set (0.009359s) taos ROLLUP d0 VGROUPS IN (2,3) START WITH 2025-12-30 10:00:00.000; result | id | reason | accepted | 1726039381 | success | Query OK, 1 row(s) in set (0.010345s)手动重算的触发规则主要用于对尚不满足多级存储迁移条件的 level 2 / 3 文件组做降采样计算与存储。未指定时间范围时计算KEEP落在[INT64_MIN, now]之间的所有文件组指定时间范围时计算该范围内的文件组。ROLLUP后若未写入新数据不会重复计算。若指定时间范围内的文件组仍在 level 1 且不满足向更高层级迁移的条件则不计算。对 level 2 / 3 文件组若上次ROLLUP后有新数据写入或更新或满足 level 2 向 level 3 迁移条件则进行计算。若需重算的文件组已在 S3 上重算生成的文件组会重新落到本地远端文件组不再生效后续再触发 S3 上传可能报错需手工删除远端文件组。该逻辑与COMPACT相同。这些规则与测试用例的行为一一对应test_rsma.py 中s6_rollup_db验证了“rollup 后无新写入则重跑无效、有新 commit 则重跑生效”s7_rollup_vgroups验证了指定不存在 vgroup 时返回Vgroup does not exist or not in db、START WITH时间晚于全部数据时不产生降采样。此外任务存在期间重复提交会报Trim or rollup already exist说明同一库上同时只允许一个 trim / rollup 任务在途。观测与中止 RSMA 任务显示 RSMA 任务SHOW RETENTIONS; SHOW RETENTION {retention_id};示例输出taos SHOW RETENTIONS; retention_id | db_name | start_time | trigger_mode | type | 857434526 | d0 | 2025-10-11 11:26:04.649 | manual | rollup | Query OK, 1 row(s) in set (0.004885s) taos SHOW RETENTION 857434526; retention_id | vgroup_id | dnode_id | number_fileset | finished | start_time | progress(%) | remain_time(s) | 857434526 | 6 | 1 | 4 | 1 | 2025-10-11 11:26:04.649 | 24 | 31 | 857434526 | 7 | 1 | 0 | 0 | 2025-10-11 11:26:04.649 | 0 | 0 | Query OK, 2 row(s) in set (0.005828s)第一条语句列出在途任务trigger_mode区分manual/ 自动type为rollup/trim第二条按 vgroup 粒度展示文件组数量、完成标记、进度百分比与预计剩余时间。中止 RSMA 任务KILL RETENTION {retention_id};查询时使用 RSMARSMA 不改变查询语义。若查询时间范围跨越多个存储层级结果中可能同时包含原始数据与降采样数据引擎负责拼装出与未降采样时一致的结果集。源码实现位置速览从源码结构看RSMA 的关键实现分布在以下位置便于进一步深入元数据管理创建/删除/级联清理mndRsma.c 与 mndRsma.h由 mndDb.c 在库级事务中协调。vnode 侧降采样计算smaRollup.c、smaCommit.c 等位于source/dnode/vnode/src/sma/目录。存储层级迁移keep0/keep1/keep2 驱动的迁移与 rollup 触发tsdbRetention.c、tsdbMigrate.c。解析与翻译CREATE RSMA/ROLLUP语法规则定义于 sql.y。系统表information_schema.ins_rsmas的查询实现见 systable.c。端到端功能回归含全部参数校验错误路径与多级 rollup 结果断言test_rsma.py。落地建议小结先规划KEEP多级保存时长如KEEP 30d,365d,36500d再按层级访问需求选择INTERVAL(1m,5m)这样的整数倍窗口DURATION尽量取能被各 interval 整除的值避免跨文件边界计算带来的开销生产写入存在乱序或更新删除时明确AVG/FIRST/LAST在重算下可能不精确关键列优先使用MIN/MAX/SUM或FIRST/LAST语义自查用SHOW RETENTIONS观测任务进度、KILL RETENTION控制任务把 ROLLUP 安排在业务低峰执行涉及 S3 远端存储时先完成 RSMA 计算再触发迁移并留意重算后远端文件组失效的问题。【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考