暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

DBA 必知必会 —— OB 4.x 版本如何查询磁盘空间占用情况?

原创 老纪的技术唠嗑局 2025-06-15
62

首先为大家推荐这个 OceanBase 开源负责人老纪的公众号 “老纪的技术唠嗑局”,会持续更新和 #数据库、#AI#技术架构 相关的各种技术内容。欢迎感兴趣的朋友们关注!

这是一篇纯运维向的文章。

献给所有正在了解 OB,以及准备对 OB 进行测试的朋友们。

背景

准备对 OceanBase 进行测试的朋友们,一定会测一下这款数据库的高压缩比是否如官网上所说的这么恐怖。
目前,在 OceanBase 官网上,虽然已经有 999+ 个与 “磁盘占用空间” 相关的官方文档,但依然无法阻碍用户在 OceanBase 社区论坛中提出 999+ 个与 “磁盘占用空间” 相关的问题。

为了减轻 OceanBase 社区论坛值班同学的工作量,今天简单整理了一篇与 “磁盘占用空间” 相关的文章,在这里和大家分享。欢迎大家在留言区评论、吐槽,以及合理地对作者进行谩骂。

注意:

下文中出现的命令,需要通过 sys 租户,在 oceanbase 库中执行。

文中可能会不厌其烦地备注,希望读者朋友们能够宽恕我的啰嗦。

查询集群和节点的磁盘空间

使用 sys 租户,在 oceanbase 库中,查询各个节点的磁盘占用:

SELECT SVR_IP, DATA_DISK_IN_USE / 1024 / 1024 / 1024 AS USED_GB FROM oceanbase.gv$ob_servers; +--------------+----------------+ | SVR_IP | USED_GB | +--------------+----------------+ | 12.345.67.89 | 0.300781250000 | +--------------+----------------+ 1 row in set (0.02 sec)

查询租户的的磁盘空间

使用 sys 租户,在 oceanbase 库中,查询指定租户的磁盘占用。需要在 SQL 中填写 tenant_id = xxx:

SELECT svr_ip, svr_port, tenant_id, sum(used_size) / 1024 / 1024 / 1024 AS used_gb FROM oceanbase.__all_space_usage WHERE tenant_id = xxx AND file_type IN ('tenant file data', 'tenant meta data', 'tenant tmp data') GROUP BY svr_ip, svr_port; +--------------+----------+-----------+----------------+ | svr_ip | svr_port | tenant_id | used_gb | +--------------+----------+-----------+----------------+ | 12.345.67.89 | 22602 | 1002 | 0.026878356934 | +--------------+----------+-----------+----------------+

查询 DataBase 的的磁盘空间

使用 sys 租户,在 oceanbase 库中,查询指定 database 的磁盘占用。需要在 SQL 中填写 tenant_id = xxx。

这里有必要多解释一下下面这条 SQL 中 sum 聚合函数里的 case when:

  • 如果一个 sstable 比较小的话,多个 sstable 会共用一个 2 MB 宏块,计算存储空间的方式会比较特殊。when b.nested_offset = 0 就是用于判断 sstable 是否是小 sstable 的。
    • 如果普通 sstable 的话(b.nested_offset = 0),就使用 2 MB * 宏块数量。
    • 如果是小 sstable 的话(b.nested_offset != 0),就直接用这个 sstable 的 size。
SELECT /*+ query_timeout(30000000) */ a.DATABASE_NAME, sum(CASE WHEN b.nested_offset = 0 THEN IFNULL(b.data_block_count + b.index_block_count + b.linked_block_count, 0) * 2 * 1024 * 1024 ELSE IFNULL(b.size, 0) END) / 1024 / 1024 / 1024 AS data_size_in_GB FROM oceanbase.CDB_OB_TABLE_LOCATIONS a INNER JOIN oceanbase.__all_virtual_table_mgr b ON a.svr_ip = b.svr_ip AND a.svr_port = b.svr_port AND a.tenant_id = b.tenant_id AND a.LS_ID = b.LS_ID AND a.TABLET_ID = b.TABLET_ID AND a.role = 'LEADER' AND a.tenant_id = xxx AND b.table_type >= 10 AND b.size > 0 GROUP BY a.DATABASE_NAME; +---------------+-----------------+ | DATABASE_NAME | data_size_in_GB | +---------------+-----------------+ | oceanbase | 0.003973903134 | | test | 0.000002717599 | | __recyclebin | 0.000006728805 | | mysql | 0.000002369284 | +---------------+-----------------+ 4 rows in set (0.58 sec)

查询表的磁盘空间

以下 4.x 版本,需要使用 sys 租户,在 oceanbase 库中,查询指定 table 的磁盘占用。

  • **4.2.1 BPX < 4.2.1 BP9 **
  • 4.2.2
  • 4.3.x < 4.3.2

需要在 SQL 中填写 tenant_id = xxx,如果不加 database_name = ‘xxx’ AND table_name = ‘xxx’ 查询出的结果包含。

SELECT /*+ query_timeout(30000000) */ a.TENANT_ID, a.DATABASE_NAME, a.TABLE_NAME, a.TABLE_ID, sum(CASE WHEN b.nested_offset = 0 THEN IFNULL(b.data_block_count + b.index_block_count + b.linked_block_count, 0) * 2 * 1024 * 1024 ELSE IFNULL(b.size, 0) END) / 1024 / 1024 /1024 AS data_size_in_GB FROM CDB_OB_TABLE_LOCATIONS a INNER JOIN __all_virtual_table_mgr b ON a.svr_ip = b.svr_ip AND a.svr_port = b.svr_port AND a.tenant_id = b.tenant_id AND a.LS_ID = b.LS_ID AND a.TABLET_ID = b.TABLET_ID AND a.role = 'LEADER' AND a.tenant_id = xxx AND b.table_type >= 10 AND b.size > 0 -- WHERE database_name = 'xxx' AND table_name = 'xxx' GROUP BY a.TABLE_ID; +-----------+---------------+------------+----------+-----------------+ | TENANT_ID | DATABASE_NAME | TABLE_NAME | TABLE_ID | data_size_in_GB | +-----------+---------------+------------+----------+-----------------+ | 1002 | test | t1 | 500024 | 0.000000458210 | +-----------+---------------+------------+----------+-----------------+ 1 row in set (0.66 sec)

以下版本,推荐使用下面这种更高性能查询方式。

  • 4.2.1 BPX >= 4.2.1 BP9
  • 4.2.x >= 4.2.3
  • 4.3.x >= 4.3.2

这里也有必要多解释一下下面这条 SQL 中的 occupy_size 和 required_size。

  • occupy_size:可以理解成 data_size,表示压缩后的数据量大小。比如 2 GB 数据压缩成了 1 MB,那么这个数据的 occupy_size 就是 1 MB。
  • required_size:可以理解成 used_size,表示实际给数据分配的空间。比如 2G 数据压缩成了 1 MB,然后占用了一个宏块(一个宏块的默认大小 2 MB),那么这个数据的 required_size = 2 MB。
-- 查普通用户表(非系统表) SELECT atnt.tenant_id AS TENANT_ID, avttl.table_id AS TABLE_ID, atnt.tenant_name AS TENANT_NAME, ad.database_name AS DATABASE_NAME, avt.table_name AS TABLE_NAME, sum(avtps.occupy_size) / 1024 / 1024 /1024 AS OCCUPY_SIZE_IN_GB, sum(avtps.required_size) / 1024 / 1024 /1024 AS REQUIRED_SIZE_IN_GB FROM oceanbase.__all_virtual_tablet_pointer_status avtps INNER JOIN oceanbase.__all_virtual_tablet_to_ls avttl ON avttl.tenant_id = avtps.tenant_id AND avttl.tablet_id = avtps.tablet_id INNER JOIN oceanbase.__all_tenant atnt ON atnt.tenant_id = avttl.tenant_id INNER JOIN oceanbase.__all_virtual_table avt ON avt.tenant_id = avttl.tenant_id AND avt.table_id = avttl.table_id INNER JOIN oceanbase.__all_virtual_database ad ON ad.tenant_id = atnt.tenant_id AND ad.database_id = avt.database_id INNER JOIN oceanbase.__all_virtual_ls_meta_table avlmt ON avtps.tenant_id = avlmt.tenant_id AND avtps.ls_id = avlmt.ls_id AND avtps.svr_ip = avlmt.svr_ip AND avtps.svr_port = avlmt.svr_port AND avlmt.role = 1 WHERE atnt.tenant_id = 1002 AND database_name = 'test' AND table_name = 't2' GROUP BY tenant_id, table_id ORDER BY tenant_id, table_id \G *************************** 1. row *************************** TENANT_ID: 1002 TABLE_ID: 500024 TENANT_NAME: mysql DATABASE_NAME: test TABLE_NAME: t1 OCCUPY_SIZE_IN_GB: 0.000000458210 -- 数据压缩后的真实大小 REQUIRED_SIZE_IN_GB: 0.000003814697 -- 4 MB,实际占用了两个宏块 1 row in set (0.32 sec)

What’s more ?

从 4.3.4 版本开始,开始支持使用标准 CDB 视图查询空间占用。还是需要使用 sys 租户,在 oceanbase 库中查询。

create table t1 (a int) ; Query OK, 0 rows affected (0.278 sec) select * from CDB_OB_TABLE_SPACE_USAGE\G *************************** 1. row *************************** TENANT_ID: 1002 TABLE_ID: 500024 TENANT_NAME: mysql DATABASE_NAME: test TABLE_NAME: t1 OCCUPY_SIZE: 492 REQUIRED_SIZE: 4096 1 row in set (0.52 sec)

select * from CDB_OB_SERVER_SPACE_USAGE\G *************************** 1. row *************************** TENANT_ID: 1 TENANT_NAME: sys SERVER_IP: 11.158.31.20 SERVER_PORT: 22602 SPACE_TYPE: Clog Data DATA_BYTES: 1677562658 USAGE_BYTES: 1677562658 *************************** 2. row *************************** TENANT_ID: 1 TENANT_NAME: sys SERVER_IP: 11.158.31.20 SERVER_PORT: 22602 SPACE_TYPE: Index Data DATA_BYTES: 1801 USAGE_BYTES: 16384 *************************** 3. row *************************** TENANT_ID: 1 TENANT_NAME: sys SERVER_IP: 11.158.31.20 SERVER_PORT: 22602 SPACE_TYPE: Meta Data DATA_BYTES: 17129472 USAGE_BYTES: 17129472 *************************** 4. row *************************** TENANT_ID: 1 TENANT_NAME: sys SERVER_IP: 11.158.31.20 SERVER_PORT: 22602 SPACE_TYPE: Slog Data DATA_BYTES: 16629760 USAGE_BYTES: 16629760 *************************** 5. row *************************** TENANT_ID: 1 TENANT_NAME: sys SERVER_IP: 11.158.31.20 SERVER_PORT: 22602 SPACE_TYPE: Table Data DATA_BYTES: 2012 USAGE_BYTES: 16384 *************************** 6. row *************************** TENANT_ID: 1 TENANT_NAME: sys SERVER_IP: 11.158.31.20 SERVER_PORT: 22602 SPACE_TYPE: Tmp Data DATA_BYTES: 0 USAGE_BYTES: 0

obclient> select * from CDB_OB_SPACE_USAGE\G *************************** 1. row *************************** TENANT_ID: 1 TENANT_NAME: sys ENDPOINT: NULL PATH: NULL SPACE_TYPE: Clog Data USAGE_BYTES: 1677328015 *************************** 2. row *************************** TENANT_ID: 1 TENANT_NAME: sys ENDPOINT: NULL PATH: NULL SPACE_TYPE: Local Data USAGE_BYTES: 67760128

附录

最后附上本文中出现的一些系统表的简单介绍:

  • __all_virtual_table_mgr
    • 用于通过 size 字段,查询所有 sstable、memtable 的 occupy_size。
    • 表名中带 virtual 字样的都是虚拟表,查询时实时构建。查这张表是准的,但可能比较慢。
  • __all_virtual_tablet_meta_table
    • 查询到的 occupy_size,required_size 是基线 sstable 的大小。
    • 只展示基线、多版本基线的大小(没有转储 sstable 的数据,和其他表的数据量对不上是符合预期的)。
  • __all_virtual_tablet_pointer_status
    • 查询所有 tablet 相关的信息
      • occupy_size:tablet 的 occupy_size
      • required_size:tablet 的 required_size
  • __all_space_usage
    • 实体表,定时任务,定时更新。
    • 展示每个 server 上的每个租户不同类型的空间占用信息。
    • tenant file data : 租户下所有 tablet 的 occupy_size 总和。

💌

老纪的技术唠嗑局 不仅希望能持续给大家带来有价值的技术分享,也希望能和大家一起为开源社区贡献力量。如果你对 OceanBase 开源社区认可,点亮一颗小星星 ✨ 吧!你的每一个Star,都是我们努力的动力~💕
https://github.com/oceanbase/oceanbase

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论