From 535ec69f62bd49210c6098cf6079e0241350b485 Mon Sep 17 00:00:00 2001 From: discord9 Date: Mon, 10 Aug 2026 18:12:56 +0800 Subject: [PATCH] docs: document streaming EXPLAIN ANALYZE HTTP API (#2719) Add the POST /v1/sql/analyze/stream (SSE) endpoint contract to the HTTP endpoint reference: request parameters, EXPLAIN ANALYZE VERBOSE statement restrictions, the metrics/final/canceled/error SSE events and payload fields, snapshot semantics (complete best-effort snapshot, adaptive coalescing), client-disconnect behavior, and the no resume/reconnect lifecycle. Synchronized to EN/ZH Nightly and v1.2. Signed-off-by: discord9 --- docs/reference/http-endpoints.md | 74 +++++++++++++++++++ .../current/reference/http-endpoints.md | 74 +++++++++++++++++++ .../version-1.2/reference/http-endpoints.md | 74 +++++++++++++++++++ .../version-1.2/reference/http-endpoints.md | 74 +++++++++++++++++++ 4 files changed, 296 insertions(+) diff --git a/docs/reference/http-endpoints.md b/docs/reference/http-endpoints.md index d375fed94..1fceaea1f 100644 --- a/docs/reference/http-endpoints.md +++ b/docs/reference/http-endpoints.md @@ -215,6 +215,80 @@ Various query APIs for sending query to GreptimeDB. For more information on the SQL API, refer to the [HTTP API documentation](/user-guide/protocols/http.md#post-sql-statements) in the user guide. +### Streaming EXPLAIN ANALYZE API + +- **Path**: `/v1/sql/analyze/stream` +- **Methods**: `POST` +- **Description**: Streams live `EXPLAIN ANALYZE VERBOSE` metrics of a running query as Server-Sent Events (SSE). + +This experimental endpoint is gated by the `http.experimental_enable_explain_analyze_stream` configuration option (defaults to `true`). When the option is disabled, the endpoint is not registered and returns `404 Not Found`. + +The endpoint is POST-only and responds with `Content-Type: text/event-stream`. Since browser `EventSource` only supports GET requests, it cannot be used with this endpoint. + +#### Request parameters + +Parameters can be passed either as query string parameters or as form fields in the POST body: + +| Parameter | Required | Description | +| --- | --- | --- | +| `sql` | Yes | The `EXPLAIN ANALYZE VERBOSE` statement to execute. | +| `db` | No | The database to run the statement against. | +| `snapshot_interval_ms` | No | Interval between `metrics` snapshots in milliseconds. Defaults to `5000`; values are clamped to the `[1000, 60000]` range. | + +Example: + +```bash +curl -N -X POST 'http://127.0.0.1:4000/v1/sql/analyze/stream' \ + -H 'Accept: text/event-stream' \ + -F 'sql=EXPLAIN ANALYZE VERBOSE SELECT * FROM monitor' +``` + +#### Statement restrictions + +The endpoint only accepts a single `EXPLAIN ANALYZE VERBOSE` statement. `EXPLAIN ANALYZE VERBOSE FORMAT JSON` is accepted as well; the `FORMAT` clause is optional and only `JSON` is supported. Any other request is rejected with a regular JSON error response (not SSE), including: + +- Non-explain statements, such as `SELECT ...` +- `EXPLAIN` or `EXPLAIN ANALYZE` without `VERBOSE` +- `EXPLAIN ANALYZE VERBOSE` with a non-JSON format, such as `FORMAT TEXT` or `FORMAT GRAPHVIZ` +- Multiple statements separated by semicolons + +#### SSE events + +Each event is sent as an `event:` line followed by a `data:` line containing a JSON payload, and events are separated by blank lines. A keep-alive comment line is sent every 15 seconds while the stream is open. + +All payloads share these fields: + +| Field | Type | Description | +| --- | --- | --- | +| `seq` | integer | Monotonically increasing sequence number of the event. | +| `state` | string | The event type: `metrics`, `final`, `canceled`, or `error`. | +| `partial` | boolean | `true` for `metrics` events, `false` for terminal events. | +| `elapsed_ms` | integer | Elapsed time in milliseconds since the request started. | +| `metrics` | array | The current `EXPLAIN ANALYZE VERBOSE` metrics snapshot: an array of `stage` / `node` / `plan` entries. Present in `metrics` and `final` events. | +| `output` | object | The final query result in GreptimeDB JSON format. Only present in `final` events. | +| `reason` | string | The reason for the failure or cancellation. Only present in `error` and `canceled` events. | +| `code` | integer | The GreptimeDB status code. Only present in `error` and `canceled` events. | + +The server emits four event types: + +- `metrics` — emitted periodically while the query runs. Each event carries a **complete best-effort snapshot** of the metrics collected so far, not a delta of the changes since the previous event. The snapshot is best-effort: metric values may change while it is being collected. Snapshots are coalesced with an adaptive interval: once a snapshot payload reaches 1 MiB, the interval is raised to at least 10 seconds; at 10 MiB, to at least 30 seconds. Snapshots are throttled but never truncated. +- `final` — terminal. Emitted when the query finishes. It carries the final metrics snapshot and the query result in the `output` field. +- `canceled` — terminal. Emitted when the query is canceled before finishing. It carries the cancellation reason and the GreptimeDB status code `1005` (`Cancelled`). +- `error` — terminal. Emitted when the query fails. It carries the error reason and the GreptimeDB status code. + +Example of a `metrics` event: + +```text +event: metrics +data: {"seq":3,"state":"metrics","partial":true,"elapsed_ms":15234,"metrics":[{"stage":0,"node":0,"plan":{"name":"MergeScanExec","param":"peers=[...]","output_rows":0,"elapsed_compute":0,"metrics":{...},"children":[...]}}]} +``` + +#### Client disconnect and lifecycle + +If the client disconnects before a terminal event, it simply stops receiving events: the SSE stream is dropped and the underlying query is best-effort canceled. A disconnected client never receives a `canceled` event. + +The stream has no resume, reconnect, or detached-execution lifecycle: the connection stays open from the request until the terminal event, and events are delivered only to the connected client. + ### PromQL API - **Path**: `/v1/promql` diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/reference/http-endpoints.md b/i18n/zh/docusaurus-plugin-content-docs/current/reference/http-endpoints.md index 3b08aa082..4530dae24 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/current/reference/http-endpoints.md +++ b/i18n/zh/docusaurus-plugin-content-docs/current/reference/http-endpoints.md @@ -215,6 +215,80 @@ curl -X POST 'http://127.0.0.1:4000/debug/prof/mem/gdump' -d 'activate=true' 有关 SQL API 的更多信息,请参阅用户指南中的 [HTTP API 文档](/user-guide/protocols/http.md#post-sql-statements)。 +### 流式 EXPLAIN ANALYZE API + +- **路径**: `/v1/sql/analyze/stream` +- **方法**: `POST` +- **描述**: 以 Server-Sent Events (SSE) 的形式流式返回运行中查询的 `EXPLAIN ANALYZE VERBOSE` 指标。 + +这是一个实验性端点,由 `http.experimental_enable_explain_analyze_stream` 配置项控制(默认为 `true`)。当该配置项被禁用时,端点不会被注册,请求将返回 `404 Not Found`。 + +该端点仅支持 POST,响应 `Content-Type` 为 `text/event-stream`。由于浏览器的 `EventSource` 只支持 GET 请求,因此无法使用该端点。 + +#### 请求参数 + +参数可以通过查询字符串或 POST 请求体中的表单字段传递: + +| 参数 | 必填 | 描述 | +| --- | --- | --- | +| `sql` | 是 | 要执行的 `EXPLAIN ANALYZE VERBOSE` 语句。 | +| `db` | 否 | 执行语句所在的数据库。 | +| `snapshot_interval_ms` | 否 | `metrics` 快照的发送间隔(毫秒)。默认为 `5000`,取值会被限制在 `[1000, 60000]` 范围内。 | + +示例: + +```bash +curl -N -X POST 'http://127.0.0.1:4000/v1/sql/analyze/stream' \ + -H 'Accept: text/event-stream' \ + -F 'sql=EXPLAIN ANALYZE VERBOSE SELECT * FROM monitor' +``` + +#### 语句限制 + +该端点仅接受单条 `EXPLAIN ANALYZE VERBOSE` 语句,也接受 `EXPLAIN ANALYZE VERBOSE FORMAT JSON`;`FORMAT` 子句可选,且仅支持 `JSON`。其他请求都会被拒绝,并返回常规的 JSON 错误响应(而非 SSE),包括: + +- 非 explain 语句,如 `SELECT ...` +- 不带 `VERBOSE` 的 `EXPLAIN` 或 `EXPLAIN ANALYZE` +- 使用非 JSON 格式的 `EXPLAIN ANALYZE VERBOSE`,如 `FORMAT TEXT` 或 `FORMAT GRAPHVIZ` +- 以分号分隔的多条语句 + +#### SSE 事件 + +每个事件由 `event:` 行和包含 JSON 负载的 `data:` 行组成,事件之间以空行分隔。流打开期间,服务器每 15 秒发送一行 keep-alive 注释。 + +所有负载都包含以下字段: + +| 字段 | 类型 | 描述 | +| --- | --- | --- | +| `seq` | 整数 | 事件的单调递增序号。 | +| `state` | 字符串 | 事件类型:`metrics`、`final`、`canceled` 或 `error`。 | +| `partial` | 布尔值 | `metrics` 事件为 `true`,终止事件为 `false`。 | +| `elapsed_ms` | 整数 | 自请求开始以来的耗时(毫秒)。 | +| `metrics` | 数组 | 当前的 `EXPLAIN ANALYZE VERBOSE` 指标快照:由 `stage` / `node` / `plan` 条目组成的数组。仅出现在 `metrics` 和 `final` 事件中。 | +| `output` | 对象 | 以 GreptimeDB JSON 格式返回的最终查询结果。仅出现在 `final` 事件中。 | +| `reason` | 字符串 | 失败或取消的原因。仅出现在 `error` 和 `canceled` 事件中。 | +| `code` | 整数 | GreptimeDB 状态码。仅出现在 `error` 和 `canceled` 事件中。 | + +服务器会发出四种事件类型: + +- `metrics` — 查询运行期间周期性发送。每个事件携带截至目前已收集指标的**完整 best-effort 快照**,而不是自上一个事件以来的增量(delta)。快照是 best-effort 的:在收集过程中指标值可能会变化。快照会以自适应间隔进行合并(coalescing):一旦单个快照负载达到 1 MiB,间隔将提升至至少 10 秒;达到 10 MiB 时,提升至至少 30 秒。快照会被限流但绝不会被截断。 +- `final` — 终止事件。查询完成时发送,携带最终指标快照以及 `output` 字段中的查询结果。 +- `canceled` — 终止事件。查询在完成前被取消时发送,携带取消原因和 GreptimeDB 状态码 `1005`(`Cancelled`)。 +- `error` — 终止事件。查询失败时发送,携带错误原因和 GreptimeDB 状态码。 + +`metrics` 事件示例: + +```text +event: metrics +data: {"seq":3,"state":"metrics","partial":true,"elapsed_ms":15234,"metrics":[{"stage":0,"node":0,"plan":{"name":"MergeScanExec","param":"peers=[...]","output_rows":0,"elapsed_compute":0,"metrics":{...},"children":[...]}}]} +``` + +#### 客户端断开与生命周期 + +如果客户端在终止事件之前断开连接,它将不再收到任何事件:SSE 流会被丢弃,底层查询会被 best-effort 取消。断开的客户端永远不会收到 `canceled` 事件。 + +该流没有 resume、reconnect 或 detached 执行的生命周期:连接会从请求开始保持到终止事件发生,事件只发送给已连接的客户端。 + ### PromQL API - **路径**: `/v1/promql` diff --git a/i18n/zh/docusaurus-plugin-content-docs/version-1.2/reference/http-endpoints.md b/i18n/zh/docusaurus-plugin-content-docs/version-1.2/reference/http-endpoints.md index 3b08aa082..4530dae24 100644 --- a/i18n/zh/docusaurus-plugin-content-docs/version-1.2/reference/http-endpoints.md +++ b/i18n/zh/docusaurus-plugin-content-docs/version-1.2/reference/http-endpoints.md @@ -215,6 +215,80 @@ curl -X POST 'http://127.0.0.1:4000/debug/prof/mem/gdump' -d 'activate=true' 有关 SQL API 的更多信息,请参阅用户指南中的 [HTTP API 文档](/user-guide/protocols/http.md#post-sql-statements)。 +### 流式 EXPLAIN ANALYZE API + +- **路径**: `/v1/sql/analyze/stream` +- **方法**: `POST` +- **描述**: 以 Server-Sent Events (SSE) 的形式流式返回运行中查询的 `EXPLAIN ANALYZE VERBOSE` 指标。 + +这是一个实验性端点,由 `http.experimental_enable_explain_analyze_stream` 配置项控制(默认为 `true`)。当该配置项被禁用时,端点不会被注册,请求将返回 `404 Not Found`。 + +该端点仅支持 POST,响应 `Content-Type` 为 `text/event-stream`。由于浏览器的 `EventSource` 只支持 GET 请求,因此无法使用该端点。 + +#### 请求参数 + +参数可以通过查询字符串或 POST 请求体中的表单字段传递: + +| 参数 | 必填 | 描述 | +| --- | --- | --- | +| `sql` | 是 | 要执行的 `EXPLAIN ANALYZE VERBOSE` 语句。 | +| `db` | 否 | 执行语句所在的数据库。 | +| `snapshot_interval_ms` | 否 | `metrics` 快照的发送间隔(毫秒)。默认为 `5000`,取值会被限制在 `[1000, 60000]` 范围内。 | + +示例: + +```bash +curl -N -X POST 'http://127.0.0.1:4000/v1/sql/analyze/stream' \ + -H 'Accept: text/event-stream' \ + -F 'sql=EXPLAIN ANALYZE VERBOSE SELECT * FROM monitor' +``` + +#### 语句限制 + +该端点仅接受单条 `EXPLAIN ANALYZE VERBOSE` 语句,也接受 `EXPLAIN ANALYZE VERBOSE FORMAT JSON`;`FORMAT` 子句可选,且仅支持 `JSON`。其他请求都会被拒绝,并返回常规的 JSON 错误响应(而非 SSE),包括: + +- 非 explain 语句,如 `SELECT ...` +- 不带 `VERBOSE` 的 `EXPLAIN` 或 `EXPLAIN ANALYZE` +- 使用非 JSON 格式的 `EXPLAIN ANALYZE VERBOSE`,如 `FORMAT TEXT` 或 `FORMAT GRAPHVIZ` +- 以分号分隔的多条语句 + +#### SSE 事件 + +每个事件由 `event:` 行和包含 JSON 负载的 `data:` 行组成,事件之间以空行分隔。流打开期间,服务器每 15 秒发送一行 keep-alive 注释。 + +所有负载都包含以下字段: + +| 字段 | 类型 | 描述 | +| --- | --- | --- | +| `seq` | 整数 | 事件的单调递增序号。 | +| `state` | 字符串 | 事件类型:`metrics`、`final`、`canceled` 或 `error`。 | +| `partial` | 布尔值 | `metrics` 事件为 `true`,终止事件为 `false`。 | +| `elapsed_ms` | 整数 | 自请求开始以来的耗时(毫秒)。 | +| `metrics` | 数组 | 当前的 `EXPLAIN ANALYZE VERBOSE` 指标快照:由 `stage` / `node` / `plan` 条目组成的数组。仅出现在 `metrics` 和 `final` 事件中。 | +| `output` | 对象 | 以 GreptimeDB JSON 格式返回的最终查询结果。仅出现在 `final` 事件中。 | +| `reason` | 字符串 | 失败或取消的原因。仅出现在 `error` 和 `canceled` 事件中。 | +| `code` | 整数 | GreptimeDB 状态码。仅出现在 `error` 和 `canceled` 事件中。 | + +服务器会发出四种事件类型: + +- `metrics` — 查询运行期间周期性发送。每个事件携带截至目前已收集指标的**完整 best-effort 快照**,而不是自上一个事件以来的增量(delta)。快照是 best-effort 的:在收集过程中指标值可能会变化。快照会以自适应间隔进行合并(coalescing):一旦单个快照负载达到 1 MiB,间隔将提升至至少 10 秒;达到 10 MiB 时,提升至至少 30 秒。快照会被限流但绝不会被截断。 +- `final` — 终止事件。查询完成时发送,携带最终指标快照以及 `output` 字段中的查询结果。 +- `canceled` — 终止事件。查询在完成前被取消时发送,携带取消原因和 GreptimeDB 状态码 `1005`(`Cancelled`)。 +- `error` — 终止事件。查询失败时发送,携带错误原因和 GreptimeDB 状态码。 + +`metrics` 事件示例: + +```text +event: metrics +data: {"seq":3,"state":"metrics","partial":true,"elapsed_ms":15234,"metrics":[{"stage":0,"node":0,"plan":{"name":"MergeScanExec","param":"peers=[...]","output_rows":0,"elapsed_compute":0,"metrics":{...},"children":[...]}}]} +``` + +#### 客户端断开与生命周期 + +如果客户端在终止事件之前断开连接,它将不再收到任何事件:SSE 流会被丢弃,底层查询会被 best-effort 取消。断开的客户端永远不会收到 `canceled` 事件。 + +该流没有 resume、reconnect 或 detached 执行的生命周期:连接会从请求开始保持到终止事件发生,事件只发送给已连接的客户端。 + ### PromQL API - **路径**: `/v1/promql` diff --git a/versioned_docs/version-1.2/reference/http-endpoints.md b/versioned_docs/version-1.2/reference/http-endpoints.md index d375fed94..1fceaea1f 100644 --- a/versioned_docs/version-1.2/reference/http-endpoints.md +++ b/versioned_docs/version-1.2/reference/http-endpoints.md @@ -215,6 +215,80 @@ Various query APIs for sending query to GreptimeDB. For more information on the SQL API, refer to the [HTTP API documentation](/user-guide/protocols/http.md#post-sql-statements) in the user guide. +### Streaming EXPLAIN ANALYZE API + +- **Path**: `/v1/sql/analyze/stream` +- **Methods**: `POST` +- **Description**: Streams live `EXPLAIN ANALYZE VERBOSE` metrics of a running query as Server-Sent Events (SSE). + +This experimental endpoint is gated by the `http.experimental_enable_explain_analyze_stream` configuration option (defaults to `true`). When the option is disabled, the endpoint is not registered and returns `404 Not Found`. + +The endpoint is POST-only and responds with `Content-Type: text/event-stream`. Since browser `EventSource` only supports GET requests, it cannot be used with this endpoint. + +#### Request parameters + +Parameters can be passed either as query string parameters or as form fields in the POST body: + +| Parameter | Required | Description | +| --- | --- | --- | +| `sql` | Yes | The `EXPLAIN ANALYZE VERBOSE` statement to execute. | +| `db` | No | The database to run the statement against. | +| `snapshot_interval_ms` | No | Interval between `metrics` snapshots in milliseconds. Defaults to `5000`; values are clamped to the `[1000, 60000]` range. | + +Example: + +```bash +curl -N -X POST 'http://127.0.0.1:4000/v1/sql/analyze/stream' \ + -H 'Accept: text/event-stream' \ + -F 'sql=EXPLAIN ANALYZE VERBOSE SELECT * FROM monitor' +``` + +#### Statement restrictions + +The endpoint only accepts a single `EXPLAIN ANALYZE VERBOSE` statement. `EXPLAIN ANALYZE VERBOSE FORMAT JSON` is accepted as well; the `FORMAT` clause is optional and only `JSON` is supported. Any other request is rejected with a regular JSON error response (not SSE), including: + +- Non-explain statements, such as `SELECT ...` +- `EXPLAIN` or `EXPLAIN ANALYZE` without `VERBOSE` +- `EXPLAIN ANALYZE VERBOSE` with a non-JSON format, such as `FORMAT TEXT` or `FORMAT GRAPHVIZ` +- Multiple statements separated by semicolons + +#### SSE events + +Each event is sent as an `event:` line followed by a `data:` line containing a JSON payload, and events are separated by blank lines. A keep-alive comment line is sent every 15 seconds while the stream is open. + +All payloads share these fields: + +| Field | Type | Description | +| --- | --- | --- | +| `seq` | integer | Monotonically increasing sequence number of the event. | +| `state` | string | The event type: `metrics`, `final`, `canceled`, or `error`. | +| `partial` | boolean | `true` for `metrics` events, `false` for terminal events. | +| `elapsed_ms` | integer | Elapsed time in milliseconds since the request started. | +| `metrics` | array | The current `EXPLAIN ANALYZE VERBOSE` metrics snapshot: an array of `stage` / `node` / `plan` entries. Present in `metrics` and `final` events. | +| `output` | object | The final query result in GreptimeDB JSON format. Only present in `final` events. | +| `reason` | string | The reason for the failure or cancellation. Only present in `error` and `canceled` events. | +| `code` | integer | The GreptimeDB status code. Only present in `error` and `canceled` events. | + +The server emits four event types: + +- `metrics` — emitted periodically while the query runs. Each event carries a **complete best-effort snapshot** of the metrics collected so far, not a delta of the changes since the previous event. The snapshot is best-effort: metric values may change while it is being collected. Snapshots are coalesced with an adaptive interval: once a snapshot payload reaches 1 MiB, the interval is raised to at least 10 seconds; at 10 MiB, to at least 30 seconds. Snapshots are throttled but never truncated. +- `final` — terminal. Emitted when the query finishes. It carries the final metrics snapshot and the query result in the `output` field. +- `canceled` — terminal. Emitted when the query is canceled before finishing. It carries the cancellation reason and the GreptimeDB status code `1005` (`Cancelled`). +- `error` — terminal. Emitted when the query fails. It carries the error reason and the GreptimeDB status code. + +Example of a `metrics` event: + +```text +event: metrics +data: {"seq":3,"state":"metrics","partial":true,"elapsed_ms":15234,"metrics":[{"stage":0,"node":0,"plan":{"name":"MergeScanExec","param":"peers=[...]","output_rows":0,"elapsed_compute":0,"metrics":{...},"children":[...]}}]} +``` + +#### Client disconnect and lifecycle + +If the client disconnects before a terminal event, it simply stops receiving events: the SSE stream is dropped and the underlying query is best-effort canceled. A disconnected client never receives a `canceled` event. + +The stream has no resume, reconnect, or detached-execution lifecycle: the connection stays open from the request until the terminal event, and events are delivered only to the connected client. + ### PromQL API - **Path**: `/v1/promql`