news 2026/10/1 4:29:49

StarRocks查表占用存储全攻略:从SHOW DATA到BE物理文件排查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
StarRocks查表占用存储全攻略:从SHOW DATA到BE物理文件排查

某天下午我正盯着监控面板,群里突然有人发来一条消息:"BE-03磁盘使用率92%了,赶紧看看是哪张表在吃空间。"这也是我在日常运维StarRocks时最常被问的问题之一。StarRocks把数据打散存储在一组BE节点上,一份数据还有多个副本,想弄清楚某张表到底占了多大存储,远没有在MySQL里执行一条information_schema来得直接。不同口径下"大小"可以差出两三倍:是压缩前还是压缩后?算不算副本?逻辑表大小和BE磁盘上的物理占用又对不上。这篇文章我从实际运维视角,把StarRocks查看每张表占用存储的常用方法和踩坑经验完整梳理一遍,适合正在管理StarRocks集群的DBA、数据开发,以及刚接手集群想知道"底细"的朋友。

1. 为什么在StarRocks里查"表大小"和MySQL完全不是一个逻辑

先说一个最容易被忽略的背景:StarRocks并不是把一张表当成一个文件存在某台机器上。表的每个分桶对应一个tablet,tablet按照副本数(默认3)分散到不同BE节点上。一份数据实际上被拆成了很多"小格子",每个格子又有三份拷贝,错落地放在不同磁盘里。

所以"这张表占用多少存储"这句话本身就有至少三种理解角度:

  • 逻辑数据量:不考虑副本、不计算索引和元数据开销,纯粹看数据内容有多大。
  • 含副本的数据量:一个tablet存了三份,三份都算进去,磁盘空间确实被吃掉了三份。
  • 物理磁盘占用:数据文件、索引文件、compaction中间产物、还没清理的垃圾文件,全部算进去,这才是真正让磁盘告警的那个数字。

我常用一个类比来解释:一张表像一大箱货,StarRocks会把货拆成若干小格子(tablet),每个格子复制三份分别锁进三台不同仓库。有人问"这箱货多大",你得先反问回去——你问的是单份重量、三份合计,还是连同货架和库房过道一起算的占地面积?这三个数字差异巨大,但没有一个算是错的。

搞清楚这一点后,后面所有命令和脚本就都不会看迷糊了。接下来我从最轻量、最常用的入口开始,再逐步深入到BE文件系统层面。

2. SHOW DATA:最轻量的入口,但Size口径要弄清楚

如果你只是想快速知道哪个库哪张表大,SHOW DATA是StarRocks里最直接的命令,也是我在巡检时用得最多的一个。

2.1 基本用法与输出列解读

最简单的用法是直接执行:

SHOW DATA;

这会列出所有库下所有表的汇总信息。指定库和表也可以:

SHOW DATA FROM db_name; SHOW DATA FROM db_name.table_name;

当指定到某张表时,输出会细到每个Index(主表以及表上的物化视图/rollup),这对定位"是不是某个物化视图把空间吃掉了"很有用。

典型的输出列大致包含这些:

字段含义
TableName表名,或者Index名
Size数据大小,字节为单位
ReplicaCount副本数
RowCount行数
RemoteSize远端存储大小(存算分离环境下出现,一般本地部署没有)

注意,不同小版本对列的命名和展示略有差异,我看到过的输出里就有多一个RemoteSize列的情况,但核心的Size、RowCount基本都在。

2.2 Size数字里藏着两层口径:压缩和副本

这是最容易误解的地方,我单独拿出来说。

官方文档里的说法是:Size代表整个表的数据大小,展示数值为副本中数据大小的总和。结合我自己的实测,这里有两个关键点:

  • **Size是压缩后的数据量。**StarRocks是列式存储,本身就带压缩,遇到重复度高的数值型字段,压缩比可以非常夸张。我见过一个线上表,导入源文件大约10GB,SHOW DATA里Size只显示2.3GB,刚开始以为数据丢了,后来才确认是压缩效果。
  • **Size默认包含了所有副本。**一张默认3副本的表,如果单份数据量是10GB,Size一般会显示30GB左右。如果这张表当时被改成了2副本,那Size就是20GB,以此类推。

所以当你想估算单份数据大小时,可以简单用Size / ReplicaCount来折算。但折算出来的也只是逻辑数据量,不是物理文件占用。

2.3 快速找出Top大表的土办法

用客户端执行SHOW DATA的结果通常是几十行甚至几百行,肉眼去扫很费劲。我一般直接在shell里处理:

mysql -h fe_host -P 9030 -u root -e "SHOW DATA FROM dwd;" \ | awk 'NR>1 {print $1, $2}' \ | sort -k2 -hr \ | head -20

这里假设输出里第二列是Size字节数,NR>1跳过头两行(表头和一个分隔行)。sort -k2 -hr按数字倒序排,取前20个。这套组合拳几秒钟就能告诉我"今天又该收拾哪张表了"。

不过SHOW DATA的粒度只到表或Index,没法回答"这张表哪个分区最大""哪个BE上副本分布最不均匀"这类问题。一旦需要下钻,就要用到第三节的information_schema表。

3. information_schema.be_tablets:精确到表、分区、副本

SHOW DATA够用但不够细。真正做存储治理的时候,我更依赖information_schema.be_tablets这张系统表。它把每个BE上每个tablet的元数据都暴露出来,粒度直接到tablet,可以聚合出任意维度的存储分布。

3.1 先确认你环境里的字段

不同StarRocks版本里,be_tablets的字段有差异,尤其是列名大小写和一些新增字段。稳妥起见,先看一眼再写SQL:

DESC information_schema.be_tablets;

我用的版本里常见字段有这些:

  • DATABASE_NAME、TABLE_NAME:库名、表名
  • PARTITION_NAME:分区名
  • TABLEt_ID:tablet id
  • BE_ID:tablet副本所在BE
  • DATA_SIZE:该副本的数据大小
  • ROW_COUNT:行数
  • STORAGE_PATH:tablet目录所在的存储路径
  • INDEX_NAME:Index名

如果你执行DESC发现字段名大小写不一样,就把后面SQL里的列名相应替换一下,原理完全一样。

3.2 按表聚合:一张SQL拿到全局TopN

我最常跑的聚合查询长这样:

SELECT DATABASE_NAME, TABLE_NAME, ROUND(SUM(DATA_SIZE) / 1024 / 1024 / 1024, 2) AS size_gb, SUM(ROW_COUNT) AS row_count, COUNT(*) AS tablet_count FROM information_schema.be_tablets GROUP BY DATABASE_NAME, TABLE_NAME ORDER BY size_gb DESC LIMIT 20;

这个结果和SHOW DATA的Size总体对得上,因为每个tablet在哪个BE上都会单独占一行,SUM(DATA_SIZE)天然就是把所有副本都算了进去。如果某张表是3副本,这里看到的数值大致就是单份数据量的3倍。

如果想知道单份数据量,可以按表的实际副本数折算,也可以先按DATABASE_NAME, TABLE_NAME去重后,对每个BE只取属于该表的一份副本。不过运维场景下,我更习惯直接看含副本的合计值,因为磁盘告警是由物理占用触发的,而物理占用恰恰是副本都算上的。

3.3 按分区、按BE继续下钻

这是be_tablets相比SHOW DATA最大的优势。排查"某个大分区表哪一天的数据最肥"时,直接按PARTITION_NAME聚合:

SELECT PARTITION_NAME, ROUND(SUM(DATA_SIZE) / 1024 / 1024 / 1024, 2) AS size_gb, SUM(ROW_COUNT) AS row_count, COUNT(*) AS tablet_count FROM information_schema.be_tablets WHERE DATABASE_NAME = 'dwd' AND TABLE_NAME = 'dwd_order_detail' GROUP BY PARTITION_NAME ORDER BY size_gb DESC LIMIT 20;

想确认集群里BE之间是否均衡,就按BE_ID聚合:

SELECT BE_ID, ROUND(SUM(DATA_SIZE) / 1024 / 1024 / 1024, 2) AS size_gb, COUNT(*) AS tablet_count FROM information_schema.be_tablets GROUP BY BE_ID ORDER BY size_gb DESC;

这两个SQL可以快速回答两个高频问题:哪张表哪个分区最占空间、哪个BE的副本总重量已经冒尖了。

有个权限上的坑需要提前提醒:be_tablets里的信息来自BE上报给FE的统计,普通低权限账号有可能查不到,或者查询返回空。我遇到过的情况是业务账号执行上面SQL直接报错。可以先跑一句SELECT COUNT(*) FROM information_schema.be_tablets;自测一下,如果没权限,找管理员给账号授权后再用。

4. 落到BE磁盘上验证物理占用

逻辑口径只能帮你"定位嫌疑表",一旦遇到磁盘真的快满、需要确认物理文件到底占了多少的情况,就得落到BE节点上看实际文件。这一步才是让告警消失的闭环。

4.1 先从BE的web端和指标接口看水位

每个BE默认会在be_http_port(通常是8040)上提供HTTP服务。浏览器访问http://BE_IP:8040,能看到该BE的基本信息入口,包括磁盘使用情况。如果集群接了Prometheus监控,在BE的metrics接口里也能直接拉到磁盘容量和实际占用相关指标。

这一步主要确认一个问题:告警的那台BE,到底是整块数据盘都满了,还是某一块盘被某个大表目录撑满了。只有确定了是哪块盘,下一步才值得去做。

4.2 tablet目录对应关系与单个大tablet的验证

BE上tablet的落盘路径大致是这样的结构:

{storage_root_path}/data/{cluster_id}/{tablet_id}/{schema_hash}

tablet_id就是be_tablets里的TABLEt_ID,schema_hash是表的哈希标识。里面主要是数据文件和索引文件,例如.dat、.idx、.meta、.gc之类。

当你通过information_schema.be_tablets找到了某张表最大的几个tablet,就可以直接登录BE节点,用du验证物理目录大小:

# 在BE节点执行,查看某个大tablet的物理目录占用 du -sh /mnt/disk1/starrocks/data/10001/106234/*

这里mnt/disk1/starrocks是假设的storage_root_path,10001是cluster_id,106234是tablet_id。如果结果和DATA_SIZE基本一致,说明这个tablet没有太多垃圾文件堆积;如果大出很多,多半是compaction没跟上,或存在未回收的旧版本文件。

4.3 整批统计:某个BE上每张表的物理占用

很多tablet要一个个du太慢,我建议按下面的思路做批量统计:

  1. 在FE上执行SQL,拉出目标BE上所有tablet_id、表名、DATA_SIZE:
SELECT TABLEt_ID, TABLE_NAME, DATABASE_NAME, DATA_SIZE FROM information_schema.be_tablets WHERE BE_ID = 10003 ORDER BY DATA_SIZE DESC;
  1. 把结果保存成tablet_list.tsv,然后登录BE节点。

  2. 在BE上用一个循环脚本统计每个tablet目录的真实大小:

#!/bin/bash # 在BE节点执行 ROOT=/mnt/disk1/starrocks/storage CLUSTER_ID=$(ls ${ROOT}/data | head -1) while read tablet_id table_name; do size_bytes=$(du -sb "${ROOT}/data/${CLUSTER_ID}/${tablet_id}" 2>/dev/null | awk '{print $1}') echo -e "${tablet_id}\t${table_name}\t${size_bytes}" done < /tmp/tablet_list.tsv > /tmp/be_tablet_sizes.tsv

注意,如果BE上tablet数量非常大,全量du -sb会非常慢,几十万级目录可能要跑很久。我通常只对DATA_SIZE排在前面的几百个tablet做物理验证,而不会全量做。

  1. 把统计结果与FE侧的SQL结果合并,就能得到"BE磁盘层面,哪张表实际吃掉了多少空间"。

4.4 为什么物理占用总是比DATA_SIZE大

这是我每次做磁盘专项排查都会遇到的问题。一个tablet的DATA_SIZE是5GB,但du出来可能有6GB甚至更多。多出来的部分主要来自:

  • segment索引和元数据文件:.idx、.meta这类文件不计入DATA_SIZE,但真实占据磁盘。
  • compact过程中产生的临时文件:合并还没完成时会存在两份文件。
  • 尚未被GC清理的垃圾文件:表结构变更、分区删除、副本迁移后,旧文件并不立即物理删除,而是等待垃圾回收机制处理。
  • 小文件过多:tablet数量大但每个tablet数据量很小,文件系统层面Inode和最小块开销反而更明显。

所以如果你发现du的结果比SHOW DATA折算出来的大不少,先别急着认为是统计错了,绝大多数情况下是物理文件合理开销。

5. 一套可复用的排查模板:Top表、Top分区、倾斜诊断

到这里,方法论基本齐了。我把平时真正会用到的排查流程固定成了四步模板,遇到"磁盘告警"类问题直接按顺序跑一遍,基本能在十分钟内定位到根因。

5.1 四步法:从全局看到单表

第一步,看全局Top20表。用第三节的聚合SQL,或者直接SHOW DATA,确定哪些表是大头。

第二步,对Top表按分区下钻。找到最占空间的分区,看一下是不是某个近期分区异常膨胀,还是历史分区没有按预期清理。

SELECT PARTITION_NAME, ROUND(SUM(DATA_SIZE) / 1024 / 1024 / 1024, 2) AS size_gb, SUM(ROW_COUNT) AS row_count, COUNT(*) AS tablet_count FROM information_schema.be_tablets WHERE DATABASE_NAME = 'dwd' AND TABLE_NAME = 'dwd_order_detail' GROUP BY PARTITION_NAME ORDER BY size_gb DESC LIMIT 20;

第三步,对嫌疑表按BE分组,看存储是否倾斜。如果某张表的tablet在BE-01上有大量副本、在BE-02上很少,说明数据分布不均衡,这在后续分桶策略调整时要重点考虑。

第四步,拉出最大tablet明细。如果一个tablet的单副本体积明显大于同表其他tablet,数值上几十倍的话,基本可以判断分桶键选择有问题,或者出现了数据倾斜:

SELECT TABLET_ID, BE_ID, ROUND(DATA_SIZE / 1024 / 1024, 2) AS size_mb, ROW_COUNT FROM information_schema.be_tablets WHERE DATABASE_NAME = 'dwd' AND TABLE_NAME = 'dwd_order_detail' ORDER BY DATA_SIZE DESC LIMIT 20;

5.2 不同方法的对比,方便按场景选

我在内部文档里维护了一张简单对照表,每次写排查报告也会附上:

方法粒度是否含副本是否压缩精确性是否需要BE权限
SHOW DATA表 / Index含压缩后逻辑大小中,有汇总延迟无需BE权限
be_tablets聚合表 / 分区 / tablet / BE含,每个副本一行压缩后逻辑大小较高,来自BE上报需要information_schema权限
BE文件系统du单个BE上的目录级单节点上的副本物理压缩后大小最高需要登录BE

这个表解决的核心问题是"该信哪个数字"。结论是:日常巡检信SHOW DATA,下钻定位信be_tablets,磁盘到底满没满必须信du。

5.3 顺手算一下单行平均大小,也能发现隐患

用be_tablets聚合出大小和行数之后,可以顺手算一算单行平均大小:

SELECT DATABASE_NAME, TABLE_NAME, ROUND(SUM(DATA_SIZE) / SUM(ROW_COUNT), 2) AS avg_row_size, ROUND(SUM(DATA_SIZE) / 1024 / 1024 / 1024, 2) AS size_gb FROM information_schema.be_tablets WHERE ROW_COUNT > 0 GROUP BY DATABASE_NAME, TABLE_NAME ORDER BY avg_row_size DESC LIMIT 20;

如果一张表行数不多,但单行平均大小异常高,多半是里面有超宽字段、长字符串,或者分桶设计不合理导致压缩率上不去。这个指标对优化表结构很有参考价值。

6. 那些年查表大小时踩过的坑

前面每一节其实都埋了一些坑,但有几个坑是反复出现的,值得集中说一说,免得你走弯路。

6.1 "数据少了"的惊吓

第一次用SHOW DATA看一张刚导入完的表时,Size比源文件小了太多,我当时第一反应是数据是不是没导全。核对行数没问题后,才反应过来是列式存储压缩的效果。数值型数据里大量重复的维度值、枚举值,压缩比可以非常夸张。后来我就养成了习惯:**拿源文件大小和表Size对比的时候,只用来估算压缩比,不要用来验证数据完整性。**验证数据完整性的靠谱方式是行数和关键字段SUM值,不是大小。

6.2 副本数改了以后,所有历史统计口径都变了

有段时间我们把一批冷表从3副本降到了2副本。降完以后SHOW DATA和be_tablets聚合出来的数值都变小了,因为副本少了一份。如果拿这个数字去跟降副本之前比,会误以为"清理出了1/3空间"。实际上逻辑数据量单份没变,只是冗余少了。所以在任何存储趋势报表里,务必记录每张表的副本数,或者干脆统一按单份口径折算,否则趋势线会被副本调整的假象带偏。

6.3 删了分区,BE磁盘空间却不掉

这可能是最让人抓狂的坑。SHOW DATA FROM已经看不到某个分区了,be_tablets里也查不到对应tablet,但df -h一看,磁盘占用纹丝不动。原因就是删除分区是标记删除,tablet数据文件要等待GC线程真正回收,而GC经常有延迟,尤其在tablet数量非常多的时候。遇到这种情况,先等一等,观察BE日志里的gc信息;如果迟迟不回收,需要检查GC是不是被卡住了。记住一个原则:逻辑上删除和物理上释放是两件事,中间隔着compaction和gc。

6.4 be_tablets的权限和版本差异

低版本StarRocks不一定有information_schema.be_tablets,就算有,字段命名在不同版本之间也可能不一致。我在2.x和3.x的环境里就遇到过DATA_SIZE和data_size写法的差异,直接照抄网上的SQL可能报错。所以每次在新环境里第一次用这个表,我都先执行DESC information_schema.be_tablets;确认一下,再写聚合SQL。另外权限问题前面也提过,普通账号很可能查不到,拿管理员账号先跑通,再决定怎么给业务账号授权。

6.5 不要依赖客户端格式化输出做脚本自动化

如果你们是直接执行SHOW DATA然后接awk处理,有个细节要留神:某些管理平台或客户端会把Size显示成"2.3 GB"这种人类可读格式,而不是纯数字字节。这时候sort -hr还能勉强用,但如果你做的是精确汇总,建议统一走be_tablets按字节算,不要在格式化字符串上做运算。我在写自动化巡检脚本时踩过这个坑,后来所有统计一律以information_schema.be_tablets为准,SHOW DATA只用来人工肉眼巡检。

我个人现在的日常习惯是:每日巡检用SHOW DATA看有没有表的Size突然异常增长;出了磁盘告警,立刻用be_tablets做表、分区、BE三轮下钻;如果还定位不到,直接上BE节点对前几百个大tablet目录做du验证。这套流程基本覆盖了我遇到过的所有"表把磁盘吃满了"的场面。最后再分享一个小经验:把这些SQL固化成一个巡检脚本,每周跑一次,把Top表和Top分区的变化趋势记下来,很多存储问题在爆发前其实是有苗头的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 4:28:58

微博评论文本分类实战:数据清洗、TF-IDF基线到BERT微调

简介&#xff1a;一套完整的微博评论文本分类工程包&#xff0c;基于PyTorch搭建&#xff0c;面向nlp入门学习者与文本情感分析实践者。数据采用ChineseNlpCorpus中的weibo_senti_100k&#xff0c;含119988条带情感标注的微博评论&#xff0c;正负样本各约6万条&#xff0c;类别…

作者头像 李华
网站建设 2026/10/1 4:28:33

群晖 Docker 容器日志驱动初始化失败排查与修复

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 4:28:15

人脸支付与智慧城市安防的工程落地实践

1. 项目概述&#xff1a;当人脸识别不再只是“刷脸开门”&#xff0c;而是城市运行的神经末梢“AI应用与产业赋能层&#xff1a;身份识别与安防监控&#xff08;人脸支付与智慧城市安防&#xff09;”——这个标题里藏着两个正在真实改变我们日常生活的技术切口&#xff1a;一个…

作者头像 李华
网站建设 2026/10/1 4:28:15

ONNXRuntime部署UFLDv2车道线检测:从PyTorch到CPU推理的完整指南

简介&#xff1a;面向自动驾驶与智能交通领域&#xff0c;ONNXRuntime 部署 Ultra-Fast-Lane-Detection-v2 车道线检测工程给出了 C 与 Python 两套完整推理源码&#xff0c;适合有一定深度学习基础、希望快速上手 ONNX 模型落地的开发者&#xff1b;工程围绕 ONNXRuntime 完成…

作者头像 李华
网站建设 2026/10/1 4:26:19

DeepSeek Harness开源AI工作台:工程化落地LLM技能编排

1. 这不是又一个“AI玩具”&#xff0c;而是一套能真正跑通需求闭环的工程化工作台你有没有过这样的经历&#xff1a;产品经理甩来一句“做个智能客服&#xff0c;能自动回复用户关于退货政策的问题”&#xff0c;你点头说好&#xff0c;转身打开Hugging Face搜模型、搭API、写…

作者头像 李华
网站建设 2026/10/1 4:25:11

Python生成器与yield实战:从内存优化到数据管道

开门见山说一个我早期踩过的坑&#xff1a;处理一份几GB的服务端日志&#xff0c;我傻乎乎地用了列表推导式把每一行都读进内存&#xff0c;程序瞬间吃掉好几个G内存&#xff0c;同事在旁边看了一眼说“这玩意儿用生成器不就行了”。那时候我只知道生成器是个“节省内存的迭代工…

作者头像 李华