GaussDB查询表空间大小语句及原理

GaussDB查询表空间大小

-- 查询版本
select version(); -- GuassDB_T_1.2.1.SPC135.B002Release b7197fd195

-- 单个Segment的物理占用字节数
select * from MY_SEGMENTS;

-- 一张表的总字节大小=该表所有Segment的BYTES之和
select 
  segment_name as 表名,
  sum(bytes) as 总字节数,  -- 汇总所有DN上的Segment大小
  sum(bytes)/1024/1024 as 总大小_MB  -- 转换为MB更易读
from MY_SEGMENTS
where 
  segment_type = 'TABLE'  -- 只保留表类型的Segment
  -- and segment_name = 'USER_INFO'  -- 指定表名(大写,GuassDB默认区分大小写)
  -- and owner = 'USER1'  -- 可选:过滤表所有者,避免歧义
group by segment_name;

一、基础前提:GuassDB 的 MPP 架构与数据分段(Segment)

GuassDB 是典型的MPP(大规模并行处理)数据库,其核心设计是将数据 “分片存储、并行计算”—— 这是理解MY_SEGMENTS作用的关键:

  • 数据节点(DN):GuassDB 集群包含多个 DN(Data Node),每个 DN 是独立的存储和计算单元;
  • 数据分段(Segment):当创建一张表时,GuassDB 会根据预设的 “分片策略”(如哈希分片、范围分片),将表的完整数据拆分成多个逻辑分片,每个分片对应一个「Segment」,并分配到不同的 DN 上存储;
  • Segment 的物理载体:每个 Segment 本质是 DN 上的一组物理数据文件(包含数据块、索引块、管理块等),表的实际数据就分散存储在这些 Segment 的物理文件中。

简单说:一张表的完整数据 = 多个 DN 上的 Segment 数据之和,表的 “字节大小” 本质是所有 Segment 物理占用空间的总和。

二、核心角色:MY_SEGMENTS 是 “Segment 元数据的系统字典表”

MY_SEGMENTS 是 GuassDB 内置的系统表(数据字典表),专门用于存储集群中所有「Segment」的元数据信息 —— 包括 Segment 对应的对象(表、索引等)、存储位置、物理大小等关键属性。

可以把它理解为 GuassDB 的 “Segment 资产台账”:每一个 Segment 在创建、修改、删除时,系统都会自动更新这张表的记录,确保元数据与实际存储状态一致。

三、关键机制:MY_SEGMENTS 如何记录 “字节大小”?

MY_SEGMENTS 能查询到表的字节大小,核心是它通过实时维护 Segment 的物理存储元数据实现的,具体分为 3 个步骤:

1. Segment 创建时:初始化元数据

当用户执行 CREATE TABLE 创建表时:

  • GuassDB 根据分片策略在多个 DN 上创建对应数量的 Segment(如 3 个 DN 则可能创建 3 个 Segment);
  • 系统自动在 MY_SEGMENTS 中插入一条 / 多条记录(每个 Segment 对应一条),并初始化关键字段:
    • SEGMENT_NAME:对应表名(或索引名,区分 Segment 类型);
    • SEGMENT_TYPE:标记 Segment 类型(TABLE表示表段、INDEX表示索引段、TEMPORARY表示临时段等);
    • BYTES:初始化为 0(此时无数据,物理占用为 0);
    • BLOCKS:初始化为 0(Segment 占用的数据块数量,与BYTES关联:BYTES = BLOCKS * 数据块大小,GuassDB 默认数据块为 8KB);
    • TABLESPACE_NAME:标记 Segment 所在的表空间(确定物理存储路径)。

2. 数据操作时:实时更新字节大小

当用户执行 INSERT/DELETE/UPDATE 等数据操作,或 ALTER TABLE 等结构调整时:

  • 数据写入 / 删除会直接修改 DN 上 Segment 对应的物理数据文件(如新增数据块、释放空块);

  • GuassDB 的存储引擎会实时计算该 Segment 物理文件的最新占用大小,并同步更新 MY_SEGMENTS

    中对应记录的 BYTES 和 BLOCKS 字段:

    • 例如:插入 1000 行数据,占用 2 个 8KB 数据块,则 BLOCKS=2BYTES=2*8192=16384(字节);

    • 例如:删除部分数据后,若释放了空数据块,BLOCKS 会减少,BYTES 也会同步降低(注:部分场景下空块可能暂不释放,需手动执行 VACUUM 清理,此时BYTES可能暂时不变)。

3. 统计信息校准:确保大小准确性

除了实时更新,GuassDB 还会通过两种方式校准 MY_SEGMENTS 的元数据准确性:

  • 自动统计(Auto ANALYZE):系统定期(默认配置)执行 ANALYZE 操作,扫描各 Segment 的物理文件,核对并修正 BYTESBLOCKS 等字段,避免因碎片、临时块等导致的大小偏差;
  • 手动统计(Manual ANALYZE):用户可执行 ANALYZE 表名 手动触发统计,适用于数据量剧变后需要即时获取准确大小的场景。

四、查询逻辑:如何从 MY_SEGMENTS 读取表的字节大小?

MY_SEGMENTS 中的 BYTES 字段直接存储了单个 Segment 的物理占用字节数,而一张表的总字节大小 = 该表所有 Segment 的 BYTES 之和。

1. MY_SEGMENTS 核心字段说明(与 “字节大小” 相关)

字段名 含义说明
SEGMENT_NAME Segment 对应的对象名(如 “USER_INFO” 表名、“IDX_USER_INFO” 索引名)
SEGMENT_TYPE Segment 类型(必须过滤为TABLE才是表的 Segment,排除索引 / 临时段等干扰)
BYTES 单个 Segment 的物理占用字节数(核心字段,直接对应 “字节大小”)
BLOCKS Segment 占用的数据块数量(辅助验证:BYTES ≈ BLOCKS * 数据块大小,默认 8KB)
TABLESPACE_NAME Segment 所在表空间(可定位物理存储路径)
OWNER Segment 的所有者(避免查询其他用户的表)

2. 实际查询表字节大小的正确逻辑

直接 select * from MY_SEGMENTS 会返回所有类型 Segment(表、索引、临时段等)的信息,需过滤 “表类型” 并汇总大小,例如:

-- 查询指定表(如USER_INFO)的总字节大小
select 
  segment_name as 表名,
  sum(bytes) as 总字节数,  -- 汇总所有DN上的Segment大小
  sum(bytes)/1024/1024 as 总大小_MB  -- 转换为MB更易读
from MY_SEGMENTS
where 
  segment_type = 'TABLE'  -- 只保留表类型的Segment
  and segment_name = 'USER_INFO'  -- 指定表名(大写,GuassDB默认区分大小写)
  and owner = 'USER1'  -- 可选:过滤表所有者,避免歧义
group by segment_name;

补充:GuassDB_T_1.2.1.SPC135.B002是企业版(T 代表企业版),MY_SEGMENTS 的核心字段(BYTESSEGMENT_TYPE)在 GuassDB 各版本中基本一致,原理通用

posted @ 2025-08-27 10:56  hqq的进阶日记  阅读(52)  评论(0)    收藏  举报