跳到主要内容
版本:1.1

表语义层(实验性)

注意

语义层目前处于实验阶段,未来版本可能发生变化。没有语义元数据的表照常工作;语义层是可选的、增量式的。

语义层给每张表附加一层薄薄的元数据,让机器消费者——LLM agent、告警与仪表盘生成器、MCP server、ETL 流水线——能够把一张表对应到它所代表的可观测性概念,而不必从列名去猜。

为什么需要它

GreptimeDB 接收 OTLP 的 metrics、traces、logs,以及 Prometheus remote write、InfluxDB、OpenTSDB、Loki、Elasticsearch 的数据。每种协议在传输时都带着丰富的元数据——instrument 类型、temporality、单位、语义约定版本——而这些信息在数据落表后大多被丢掉了:

  • 一张 OTLP traces 表看起来和任何宽表没区别;signal type 和 source 只能从命名去猜。
  • metric 的单位(sBy)被行编码器丢弃,从数据里无法还原。
  • OTLP 的聚合 temporality(cumulative vs delta)在 metric 名字里看不出来。
  • Prometheus 中由 _total 后缀推断出的 counter 类型只是出来的,不是声明的——但表里从不标记这一点。

消除这些猜测所需的元数据,在写入时本来就存在。语义层把它保留下来,而不是丢弃。这样告警生成器就能在 rate() 和绝对阈值之间做选择;仪表盘生成器能按 signal type 选可视化方式;agent 能读到一份结构化的目录,而不是从列名去推断。

工作原理

语义层复用已有的 SQL 表面——没有新协议,也没有新的 DDL 关键字。它有三种机制:

  1. greptime.semantic.* 表选项——表级别的身份与血缘信息,存放在已有的 table_options 槽位里(也就是存 ttltable_data_model 等选项的同一个槽位)。
  2. COMMENT——标准 SQL,用于列级别的补充说明。
  3. information_schema.table_semantics——一个可查询的视图,是发现入口。它为每张至少带一个 greptime.semantic.* 选项的表返回一行。

词汇表

所有 key 都是 greptime.semantic. 前缀下的扁平字符串,所有 value 都是字符串。词汇表刻意保持精简——只有当一个 key 记录的信息无法从 schema、列、或消费者已经理解的 metric 命名约定里廉价地还原时,它才有资格进入。那些值已经在 metric 名字里(Prometheus 的 _total 后缀)、是常量、或只是重复某一列的 key,被故意省略。

白名单是封闭的:前缀下未被识别的 key(比如 greptime.semantic.future.key)或超出取值范围的 value 都会被拒绝。

通用 key(所有信号)

Key说明示例取值
greptime.semantic.signal_type表所代表的遥测信号类型。metric / trace / log / event / unknown
greptime.semantic.source写入数据的接入生态。opentelemetry / prometheus / influxdb / opentsdb / loki / elasticsearch / custom / mixed / unknown
greptime.semantic.pipeline内部接入数据模型。是 table_data_model 的信号无关版后继。greptime_trace_v1

Trace key

Key说明示例取值
greptime.semantic.trace.conventions数据所遵循的语义约定版本,通常是一个 OTel schema URL。https://opentelemetry.io/schemas/1.27.0 / mixed / unknown

Metric key

Key说明示例取值
greptime.semantic.metric.typeinstrument 类型。counter / gauge / histogram / summary / updown_counter / gauge_histogram / info / stateset / mixed / unknown
greptime.semantic.metric.unitUCUM 记法的单位。被行编码器丢弃,写入后无法还原。s / By / {request}
greptime.semantic.metric.temporality聚合 temporality(仅 OTLP)。在 metric 名字里看不出来。cumulative / delta / mixed / unknown
greptime.semantic.metric.metadata_qualitymetric 类型是怎么得到的——即 metric.type 有多可信。declared(协议明确声明)/ inferred(从名字后缀猜测)/ unknown
greptime.semantic.metric.original_name翻译前的 OpenTelemetry 名字,在表名被 Prometheus 化时记录。http.server.duration

metadata_quality 是面向"置信度感知"工具的关键字段:一个 inferred 的 counter,在依赖 rate() 这类语义之前应当复核。

unknownmixed 是共享的哨兵值。unknown 表示打标时无法确定取值;mixed 表示一个单值 key 在表的生命周期里看到了相互冲突的值——比如一张长期存在的表接收了来自多个 source 的数据。任何单值语义 key 都应被视为尽力而为的提示,而非强证据。

接入时的自动打标

auto-create 路径会在每种受支持的协议上打上身份标记(signal_type + source)。OTLP metrics 额外携带完整的 metric 词汇,因为 OTLP 线格式声明了 type/unit/temporality 之后又把它们丢弃了;OTLP traces 携带 pipeline 和 conventions。

接入路径signal_typesource额外 key
OTLP metricsmetricopentelemetrymetric.typemetric.unitmetric.temporalitymetric.metadata_quality = declaredmetric.original_name
OTLP tracestraceopentelemetrypipeline = greptime_trace_v1trace.conventions
OTLP logslogopentelemetry
Prometheus remote writemetricprometheus仅身份(type/unit 在 metric 名字里)
InfluxDB line protocolmetricinfluxdb仅身份
OpenTSDBmetricopentsdb仅身份
Lokilogloki仅身份
Elasticsearchlogelasticsearch仅身份

语义选项在建表时打标。目前还没有更新路径:把 metadata_qualityinferred 提升到 declared、或在后续写入时修订 trace.conventions,都暂未实现。

用 DDL 手动打标

你也可以在 CREATE TABLE ... WITH (...) 里自己设置这些选项。只接受白名单内、且取值合法的 key:

CREATE TABLE my_metrics (
ts TIMESTAMP TIME INDEX,
val DOUBLE
) WITH (
'greptime.semantic.signal_type' = 'metric',
'greptime.semantic.source' = 'custom',
'greptime.semantic.metric.type' = 'counter',
'greptime.semantic.metric.unit' = 'By'
);

这些选项会出现在 SHOW CREATE TABLE 的输出和 table_semantics 视图里。

发现语义元数据

消费者连接后的第一条查询,就能列出所有带语义标记的表:

SELECT table_schema, table_name, signal_type, source, pipeline, metadata_quality, semantic_options
FROM information_schema.table_semantics
ORDER BY table_name;

signal_typesourcepipelinemetadata_quality 被提升为独立的列;其余信号特定的 key 被折叠进 semantic_options JSON 字符串(去掉 greptime.semantic. 前缀)。完整 schema 和更多示例见 TABLE_SEMANTICS 参考文档。

GreptimeDB MCP Server 会读取这个视图,这样 AI 助手无需你逐一解释每张表的含义,就能理解你的表。