SHOW ANALYZE STATUS 详解:StarRocks CBO 统计信息采集任务状态查询实战指南
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
StarRocks 的 CBO(Cost-Based Optimizer,基于代价的优化器)依赖高质量的统计信息来估算执行代价、选择最优执行计划,而这些统计信息由后台的采集任务生成。SHOW ANALYZE STATUS正是用于查看这些统计信息采集任务状态的查询语句,本文将从语法、返回列语义、外部表元数据、底层实现与排查实践五个维度,结合 StarRocks 仓库源码,完整讲解如何用它监控手动与自动统计采集任务,并配合SHOW ANALYZE JOB、KILL ANALYZE完成统计任务的日常运维。读完本文,你将掌握统计采集任务的完整状态观测与故障排查方案。
背景:StarRocks 统计信息采集任务体系
在深入了解SHOW ANALYZE STATUS之前,需要先厘清 StarRocks 中的统计采集任务分类。StarRocks 支持三种统计采集方式:
- 手动采集(Manual collection):通过
ANALYZE TABLE创建,任务只运行一次,无需手动删除,运行结束后即完成使命; - 自定义自动采集(Custom automatic collection):通过
CREATE ANALYZE创建,按用户指定的调度策略周期性运行,属于"custom collection tasks"; - 系统默认自动采集(Automatic collection):StarRocks 内置的自动统计任务,按 FE 配置项(如
statistic_collect_interval_sec)周期性检查并采集。
这三类任务的调度类型(Schedule)只有两种:手动任务为ONCE,自动任务为SCHEDULE。
SHOW ANALYZE STATUS 语法与能力边界
SHOW ANALYZE STATUS从 v2.4 起支持,用于查看统计信息采集任务的状态,语法如下:
SHOW ANALYZE STATUS [WHERE]可以使用LIKE或WHERE对返回结果进行过滤,例如按表名精确过滤:
SHOW ANALYZE STATUS where `table` = 'ex_hive_tbl';需要特别强调的是该语句的能力边界:它只能查看手动采集任务和系统自动采集任务的状态,不能查看自定义采集任务(custom collection tasks)的状态。自定义任务请使用 SHOW ANALYZE JOB 查看。这一定位在 Gather statistics for CBO 文档中也有明确说明:"This statement cannot be used to view the status of custom collection tasks. To view the status of custom collection tasks, use SHOW ANALYZE JOB."
返回列详解:从文档到源码的逐列印证
SHOW ANALYZE STATUS返回 11 个字段,官方文档给出的语义如下表:
| 列名 | 说明 |
|---|---|
| Id | 采集任务的 ID。 |
| Database | 数据库名。 |
| Table | 表名。 |
| Columns | 列名。 |
| Type | 统计信息类型,包括 FULL、SAMPLE 和 HISTOGRAM。 |
| Schedule | 调度类型。ONCE表示手动,SCHEDULE表示自动。 |
| Status | 任务状态。 |
| StartTime | 任务开始执行的时间。 |
| EndTime | 任务执行结束的时间。 |
| Properties | 自定义参数。对于外部表(如 Iceberg、Hive、Paimon)采集任务,还会包含table_format、partition_count、column_count等采集元数据;对于 Iceberg 表还包含snapshot_id、total_files和total_rows。 |
| Reason | 任务失败的原因。执行成功时返回 NULL。 |
这些列在 FE 端由ShowAnalyzeStatusStmt.showAnalyzeStatus()方法逐列组装,源码位于 ShowAnalyzeStatusStmt.java,可以据此理解各列的精确语义:
Database 列:catalog 与 db 的拼接格式
源码中该列并非简单的数据库名,而是以catalogName + "." + dbName的格式输出(row.set(1, analyzeStatus.getCatalogName() + "." + analyzeStatus.getDbName())),因此实际返回形如default_catalog.stats_db或hive_catalog.tn_test。在 WHERE 过滤时使用database字段时也应按此格式书写。
Columns 列:ALL 与局部采集的区分
当采集任务针对整张表的所有可采集列时,该列返回ALL;当仅采集部分列时,返回以逗号分隔的列名列表。源码通过StatisticUtils.getCollectibleColumns(table).size()计算整表可采集列总数,只有当指定列集合非空且与总数不一致时才输出具体列名,否则保持ALL。
Type 列:对应 AnalyzeType 枚举
Type 列对应源码 StatsConstants.java 中的AnalyzeType枚举,取值包括:
SAMPLE:采样采集,通过ANALYZE SAMPLE TABLE触发,采样行数由statistic_sample_collect_rows属性控制(默认 200000,超过表实际行数时自动退化为全量采集);FULL:全量采集,是ANALYZE TABLE的默认类型;HISTOGRAM:直方图采集。
Schedule 列:对应 ScheduleType 枚举
对应ScheduleType枚举(见 StatsConstants.java):
ONCE:手动采集任务,仅运行一次;SCHEDULE:自动采集任务(含系统默认自动任务)。
Status 列:枚举映射与 RUNNING 进度
Status 列的输出逻辑最能体现该语句的"实时性"设计。底层状态对应ScheduleStatus枚举(StatsConstants.java):
| 底层枚举 | 展示值 | 说明 |
|---|---|---|
| PENDING | PENDING | 任务排队等待执行。 |
| RUNNING | RUNNING (N%) | 任务执行中,并附带实时进度百分比。 |
| FINISH | SUCCESS | 仅用于ScheduleType.ONCE任务,表示执行成功。 |
| FAILED | FAILED | 执行失败,失败原因见 Reason 列。 |
其中 RUNNING 的进度百分比由analyzeStatus.getProgress()动态提供,是判断大表异步采集进度的关键指标。
StartTime / EndTime:固定格式的时间戳
两个时间列在源码中统一使用yyyy-MM-dd HH:mm:ss格式输出(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))。注意 EndTime 在任务未结束时为空。
Reason 列:失败根因定位
仅当任务失败时输出原因,成功时为 NULL。在排查采集失败时,这一列通常直接指向问题的根因(如权限不足、元数据异常等)。
实战示例:外部表统计采集状态观测
以下示例摘自 Gather statistics for CBO 文档,演示了对 Hive 外部表ex_hive_tbl执行全量采集后查看任务状态:
ANALYZE TABLE ex_hive_tbl(k1); +----------------------------------+---------+----------+----------+ | Table | Op | Msg_type | Msg_text | +----------------------------------+---------+----------+----------+ | hive_catalog.tn_test.ex_hive_tbl | analyze | status | OK | +----------------------------------+---------+----------+----------+SHOW ANALYZE STATUS where `table` = 'ex_hive_tbl'; +-------+----------------------+-------------+---------+------+----------+---------+---------------------+---------------------+------------+--------+ | Id | Database | Table | Columns | Type | Schedule | Status | StartTime | EndTime | Properties | Reason | +-------+----------------------+-------------+---------+------+----------+---------+---------------------+---------------------+------------+--------+ | 16400 | hive_catalog.tn_test | ex_hive_tbl | k1 | FULL | ONCE | SUCCESS | 2023-12-04 16:31:42 | 2023-12-04 16:31:42 | {} | | | 16465 | hive_catalog.tn_test | ex_hive_tbl | k1 | FULL | ONCE | SUCCESS | 2023-12-04 16:37:35 | 2023-12-04 16:37:35 | {} | | | 16467 | hive_catalog.tn_test | ex_hive_tbl | k1 | FULL | ONCE | SUCCESS | 2023-12-04 16:37:46 | 2023-12-04 16:37:46 | {} | | +-------+----------------------+-------------+---------+------+----------+---------+---------------------+---------------------+------------+--------+从输出可以看出:三条记录均为ONCE(手动)任务、FULL类型、状态SUCCESS,且每执行一次ANALYZE TABLE都会生成一条新的历史记录,因此该语句实际上也承担了采集历史记录查询的功能。文档中同样提到:"You can use SHOW ANALYZE STATUS to view the history of collection tasks."
Properties 列深度解读:外部表采集元数据
Properties 列是该语句信息量最丰富的列,它默认展示采集任务的自定义参数(如果未指定,则展示fe.conf中生效的默认参数,实际生效值可通过该列核对)。对于外部表(Hive、Iceberg、Paimon、Hudi 等)的采集任务,还会附加展示采集元数据,包括:
table_format:表格式,如 hive、iceberg、paimon 等;partition_count:采集涉及的分区数;column_count:采集涉及的列数;- 对于 Iceberg 表额外包含
snapshot_id、total_files、total_rows,用于反映本次采集基于的 Iceberg 快照状态。
这些字段的写入逻辑位于 ExternalFullStatisticsCollectJob.java:采集任务运行时构建extendedInfo映射,写入table_format、partition_count、column_count,再通过table.getStatsCollectMetadata()合并快照级元数据,最终与用户自定义 Properties 合并后写入AnalyzeStatus,从而"without introducing new columns"地展示在 Properties 列中。
值得关注的是,同一份源码还展示了外部表采集的**有界成本扫描(bounded-cost scan)**能力:任务会解析connector_table_analyze_scan_bytes_cap、connector_table_analyze_scan_files_cap、connector_table_analyze_scan_rows_cap等扫描预算上限,并将实际生效的预算值一并写入 Properties(EXTERNAL_ANALYZE_SCAN_BYTES_CAP等键)。因此运维人员可以直接在SHOW ANALYZE STATUS的 Properties 列中确认某次外部表采集是否启用了有界扫描、上限是多少——这是该语句用于采集"可观测性"的一个典型场景。
权限要求与底层实现
权限模型
在 StarRocks 的 RBAC 权限框架下,用户查看某表的状态记录需要对该表拥有任意操作权限(any action)。源码中通过Authorizer.checkAnyActionOnTableLikeObject(context, analyzeStatus.getDbName(), table)进行校验,若表不存在或权限不足,该条记录会被跳过不展示(见 ShowAnalyzeStatusStmt.java)。这意味着不同权限的用户执行同一语句,看到的记录集合可能不同。
状态数据的存储与管理
任务状态由 FE 的AnalyzeMgr统一管理,核心数据结构是内存中的Map<Long, AnalyzeStatus> analyzeStatusMap(见 AnalyzeMgr.java),其关键管理操作包括:
addAnalyzeStatus()/replayAddAnalyzeStatus():新增任务状态,并在 FE 元数据回放(replay)时恢复;dropAnalyzeStatus()/dropExternalAnalyzeStatus():表被删除时同步清理对应的状态记录;clearExpiredAnalyzeStatus():周期性清理过期的状态记录,防止无界增长;save():将全量状态随 FE image 持久化(AnalyzeMgr.java),保证 FE 重启后历史记录不丢失。
从该结构可以推断,SHOW ANALYZE STATUS展示的既是任务"当前状态",也是一份可持续追溯的历史记录视图,手动任务运行一次后无需删除正是因为其历史记录天然保留在状态表中。
与其他统计语句的协作:完整排查链路
SHOW ANALYZE STATUS并非孤立存在,它与 CBO 统计体系的其他语句共同构成完整运维闭环:
| 语句 | 职责 | 与 SHOW ANALYZE STATUS 的关系 |
|---|---|---|
| ANALYZE TABLE | 创建手动采集任务(可同步或异步) | 异步模式下任务的后续状态由 SHOW ANALYZE STATUS 观察 |
| SHOW ANALYZE JOB | 查看自定义自动采集任务 | 与 SHOW ANALYZE STATUS 互补,覆盖自定义任务场景 |
| KILL ANALYZE | 取消运行中的采集任务 | 手动任务的 ID 从 SHOW ANALYZE STATUS 获取 |
| SHOW STATS META / SHOW HISTOGRAM META | 查看已采集统计信息的元数据 | 确认采集结果是否落库生效 |
一个典型的异步采集排查流程如下:
- 发起采集:对大数据量表执行异步手动采集
ANALYZE TABLE big_tbl WITH ASYNC MODE; - 监控进度:查询任务状态,关注 RUNNING 后的进度百分比
SHOW ANALYZE STATUS WHERE `table` = 'big_tbl'; - 失败定位:若 Status 为 FAILED,读取 Reason 列定位根因,并核对 Properties 列确认实际生效的采集参数;
- 取消任务:若任务耗时异常需要终止,从状态结果中取得 Id 后执行
KILL ANALYZE <ID>; - 结果验证:通过
SHOW STATS META确认统计信息元数据已更新,采集闭环完成。
关于统计信息采集的整体设计与各类配置参数(如statistic_sample_collect_rows、自动采集间隔等),可进一步阅读 Gather statistics for CBO;各语句的完整语法可参考 ANALYZE TABLE、SHOW ANALYZE JOB 与 KILL ANALYZE 的官方参考文档。
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考