OceanBase 集群环境中,磁盘空间统计很不准确,如何准确查取表占用磁盘空间大小?

【 使用环境 】

  1. OceanBase 演示环境
  2. OceanBase 集群环境
    【 OB or 其他组件 】
    OceanBase社区版一键安装包 (OceanBase All in One)
    【 使用版本 】4.2.0
    【问题描述】
  3. 我有一张大表,原本表格在sqlserver数据库中占用大约10G空间。
  4. 将表格迁移到一个自己搭建的OceanBase 演示环境A中,也就是单台机器,显示此表占用20G磁盘空间。
  5. 将表格迁移到一个自己搭建的OceanBase 集群环境B中,集群使用的是3台机器(3个zone),每个zone分配一个节点的方案部署。显示表格只占用空间2G。

表在迁移后,表结构和表数据在A和B环境几乎一样,连索引我都确认是一样的。我初步认为是统计不准确,但是我无法获取准确的结果。

【复现路径】问题出现前后相关操作
【问题现象及影响】

【附件】
A环境:
image

B环境:
image


试试下面这个SQL,看看结果跟真实情况是否符合。
修改里面的 条件:tenant_iddatabase_nametable_name

WITH table_locs AS (
SELECT
	t.tenant_id,
	t.database_name,
	t.table_id,
	t.table_name,
	t.table_type tablet_type,
	t.tablet_id,
	REPLACE(concat(t.table_name,':',t.partition_name,':',t.subpartition_name),':NULL','') tablet_name,
	t.tablegroup_name,
	t.ls_id,
	t.ZONE, 
	t.ROLE,
	t.svr_ip
FROM
	oceanbase.CDB_OB_TABLE_LOCATIONS t
WHERE
	t.data_table_id IS NULL 
UNION
SELECT
	i.tenant_id,
	i.database_name,
	i.table_id,
	t.table_name,
	i.table_type tablet_type,
	i.tablet_id,
	REPLACE(
		REPLACE(concat(i.table_name,':',i.partition_name,':',i.subpartition_name) ,concat('__idx_', i.data_table_id, '_'),'')
		,':NULL',''
	) tablet_name,
	i.tablegroup_name,
	i.ls_id,
	i.ZONE, 
	i.ROLE,
	i.svr_ip
FROM
	oceanbase.CDB_OB_TABLE_LOCATIONS i
INNER JOIN oceanbase.__all_virtual_table t ON
	( i.tenant_id = t.tenant_id
		AND i.data_table_id = t.table_id  )
WHERE i.data_table_id IS NOT NULL 
)
SELECT
	t.database_name,
	t.ls_id,
	t.ROLE,
	t.svr_ip,
	t.table_name,
	t.tablet_name,
	-- group_concat(s.table_type,',') tablet_types,
	round(sum(s.size)/1024/1024/1024,2) size_gb
FROM
	table_locs t JOIN oceanbase.GV$OB_SSTABLES s 
		ON (t.tenant_id=s.tenant_id AND t.ls_id=s.ls_id AND t.svr_ip=s.svr_ip AND t.tablet_id=s.tablet_id)
WHERE
	t.tenant_id = 1004
	AND t.database_name IN ('tpccdb')
	AND t.table_name IN ('bmsql_stock2')
	AND s.table_type NOT IN ('MEMTABLE')
	-- AND t.ROLE IN ('LEADER')
GROUP BY
	t.database_name,
	t.ls_id,
	t.ROLE,
	t.svr_ip,
	t.table_name,
	t.tablet_name 
WITH ROLLUP
ORDER BY 
	t.database_name,
	t.ls_id,
	t.ROLE,
	t.svr_ip,
	t.table_name,
	t.tablet_name
;
database_name ls_id ROLE svr_ip table_name tablet_name size_gb
0.06
tpccdb 0.06
tpccdb 1001 0.02
tpccdb 1001 FOLLOWER 0.01
tpccdb 1001 FOLLOWER 10.0.0.70 0.01
tpccdb 1001 FOLLOWER 10.0.0.70 bmsql_oorder 0.01
tpccdb 1001 FOLLOWER 10.0.0.70 bmsql_oorder bmsql_oorder:p0 0.00
tpccdb 1001 FOLLOWER 10.0.0.70 bmsql_oorder bmsql_oorder:p1 0.00
tpccdb 1001 FOLLOWER 10.0.0.70 bmsql_oorder bmsql_oorder_idx1:p0 0.00
tpccdb 1001 FOLLOWER 10.0.0.70 bmsql_oorder bmsql_oorder_idx1:p1 0.00
tpccdb 1001 LEADER 0.01
tpccdb 1001 LEADER 10.0.0.66 0.01
tpccdb 1001 LEADER 10.0.0.66 bmsql_oorder 0.01
tpccdb 1001 LEADER 10.0.0.66 bmsql_oorder bmsql_oorder:p0 0.00
tpccdb 1001 LEADER 10.0.0.66 bmsql_oorder bmsql_oorder:p1 0.00
tpccdb 1001 LEADER 10.0.0.66 bmsql_oorder bmsql_oorder_idx1:p0 0.00
tpccdb 1001 LEADER 10.0.0.66 bmsql_oorder bmsql_oorder_idx1:p1 0.00
tpccdb 1003 0.04
tpccdb 1003 FOLLOWER 0.02
tpccdb 1003 FOLLOWER 10.0.0.66 0.02
tpccdb 1003 FOLLOWER 10.0.0.66 bmsql_oorder 0.02
tpccdb 1003 FOLLOWER 10.0.0.66 bmsql_oorder bmsql_oorder:p2 0.01
tpccdb 1003 FOLLOWER 10.0.0.66 bmsql_oorder bmsql_oorder:p3 0.00
tpccdb 1003 FOLLOWER 10.0.0.66 bmsql_oorder bmsql_oorder_idx1:p2 0.00
tpccdb 1003 FOLLOWER 10.0.0.66 bmsql_oorder bmsql_oorder_idx1:p3 0.01
tpccdb 1003 FOLLOWER 10.0.0.66 bmsql_oorder bmsql_oorder_idx2 0.01
tpccdb 1003 LEADER 0.02
tpccdb 1003 LEADER 10.0.0.70 0.02
tpccdb 1003 LEADER 10.0.0.70 bmsql_oorder 0.02
tpccdb 1003 LEADER 10.0.0.70 bmsql_oorder bmsql_oorder:p2 0.00
tpccdb 1003 LEADER 10.0.0.70 bmsql_oorder bmsql_oorder:p3 0.00
tpccdb 1003 LEADER 10.0.0.70 bmsql_oorder bmsql_oorder_idx1:p2 0.00
tpccdb 1003 LEADER 10.0.0.70 bmsql_oorder bmsql_oorder_idx1:p3 0.00
tpccdb 1003 LEADER 10.0.0.70 bmsql_oorder bmsql_oorder_idx2 0.01

OB 的表的总空间统计比较难,有下面几个原因:

  • LSM-Tree 数据最多有 4层。 C0 (MEMTABLE), C1(MINI SSTABLE), C2(MINOR SSTABLE), C3(MAJOR SSTABLE) 。C1-C3 在磁盘上。当发生转储或合并的时候,这三部分空间会是动态变化的,直到转储和合并结束后一段时间(老版本数据都释放了)。总空间最小的时候就是业务停写了,发起多轮 MAJOR FREEZE 后。
  • 表的总空间是要包含表和索引的。OB 表和索引使用 两个 table_id (二者通过那个 data_table_id 关联),4.x 以后为了管理方便,引入 了 tablet_id ,对应原来的分区。表和索引都可能有多个分区,就有多个 tablet_id
  • 每个 tablet_id 对应的块转储到磁盘上就有上面 C1-C3 这几部分数据。
  • 每个分区或tablet_id 的数据还有三副本。这个空间也要看。

画了个图,如有不当欢迎指出。

所以,上面这个 SQL 写的很复杂。可以结合原理看看SQL逻辑。
有问题欢迎讨论。

1 个赞

谢谢,在集群中查出来的每个zone的t_card_base表大约占用3.5G磁盘,在单机版环境中查出来的也是3.5G左右的占用,两者达成了一致,应该是一个相对靠谱的答案