OceanBase查看表大小和索引大小,正常来说只需在OCP上进入任意普通租户下,选择左侧菜单资源管理即可查看,但是最近我发现,这里显示的索引大小与实际后台SQL(见下文)查看的索引大小数据不一致,经过官方问答社区帖子询问:https://ask.oceanbase.com/t/topic/35609708/11,又仔细研究了下相关视图,于是有了这篇文章。
在 ob 4.x 版本之前,大部分情况下都是使用 __all_virtual_ 等内部表做相关统计信息查询,但是在 ob 4.x 版本之后,官方更建议直接按需使用对应的视图表来查询各种信息,不建议直接使用__all_virtual_这种内部表做查询了。
例如涉及表大小和索引大小的视图表有:
sys租户下的
oceanbase.CDB_OB_TABLE_LOCATIONS
oceanbase.CDB_OB_TABLET_REPLICAS
以及普通租户下的
oceanbase.DBA_OB_TABLE_LOCATIONS
oceanbase.DBA_OB_TABLET_REPLICAS。
一、查看表大小
1、sys租户下查询
如果想查询表的所有副本大小,则去掉条件 t1.role='leader',如果只想查单副本大小,则加上条件 t1.role='leader'。
select /*+ READ_CONSISTENCY(WEAK) */t1.table_name,concat(round(sum(t2.data_size/1024/1024/1024), 2), 'G') data_size_gb ,concat(round(sum(t2.required_size)/1024/1024/1024, 2), 'G') required_size_gbfrom dba_ob_tenants t,cdb_ob_table_locations t1,cdb_ob_tablet_replicas t2where t.tenant_id=t1.tenant_idand t1.svr_ip=t2.svr_ipand t1.tenant_id=t2.tenant_idand t1.ls_id=t2.ls_idand t1.tablet_id=t2.tablet_id-- and t1.role='leader'and t.tenant_name='ob_test'and t1.database_name='fanchen'and t1.table_name='t_fan_chen_du_shu_lou'group by t1.table_nameorder by 3 desc;+------------------------+--------------+------------------+| table_name | data_size_gb | required_size_gb |+------------------------+--------------+------------------+| t_fan_chen_du_shu_lou | 683.39G | 790.73G |+------------------------+--------------+------------------+1 row in set (3.96 sec)
data_size_gb:数据实际大小,required_size_gb:数据分配空间大小。数据存储以宏块(2MB)为最小单位,所以 REQUIRED_SIZE >= DATA_SIZE。
2、普通租户下查询
select /*+ READ_CONSISTENCY(WEAK) */t1.table_name,concat(round(sum(t2.data_size/1024/1024/1024), 2), 'G') datasize_primary_replica ,concat(round(sum(t2.required_size)/1024/1024/1024, 2), 'G') requiredsize_primary_replicafrom dba_ob_table_locations t1,dba_ob_tablet_replicas t2where t1.svr_ip=t2.svr_ipand t1.ls_id=t2.ls_idand t1.tablet_id=t2.tablet_id-- and t1.role='leader'and t1.database_name='fanchen'and t1.table_name='t_fan_chen_du_shu_lou'group by t1.table_nameorder by 3 desc;
二、查看索引大小
sys租户下查不了普通租户下表的索引大小,必须在普通租户下查询。
select /*+ READ_CONSISTENCY(WEAK) */t1.table_name,round(sum(t2.data_size/1024/1024/1024), 2) data_size_gb ,round(sum(t2.required_size)/1024/1024/1024, 2) required_size_gbfrom dba_ob_table_locations t1,dba_ob_tablet_replicas t2where t1.svr_ip=t2.svr_ipand t1.ls_id=t2.ls_idand t1.tablet_id=t2.tablet_id-- and t1.role='leader'and t1.database_name='fanchen'and (t1.table_name='t_fan_chen_du_shu_lou'or t1.data_table_id in (select table_id from dba_ob_table_locations where table_name='t_fan_chen_du_shu_lou' limit 1))group by t1.table_nameorder by 3 desc;
三、根据表名查询表、索引、lob大小
有了上面2个SQL模板,能不能一条SQL实现查询表大小和索引大小呢?
通过了解 oceanbase.CDB_OB_TABLE_LOCATIONS 表,我发现对于ob而言,索引对象也是一种表,大对象 LOB 数据也是一种表,于是有了4种表类型:
USER TABLE:用户表
SYSTEM TABLE:系统表,系统自建的表
INDEX:索引表
LOB AUX TABLE:LOB 辅助表,系统自建的表,用于辅助实现 LOB 列。
于是SQL改写如下:
with table_info as ( select table_id, table_name, database_name from dba_ob_table_locations where database_name = 'fanchen' and table_name = 't_fan_chen_du_shu_lou' limit 1)select /*+ READ_CONSISTENCY(WEAK) */ t1.database_name, CASE WHEN data_table_id is null THEN t1.table_name WHEN table_type = 'LOB AUX TABLE' THEN t1.table_name ELSE t1.index_nameEND AS object_name, round(sum(t2.data_size) / 1024 / 1024 / 1024, 2) as data_size_gb, round(sum(t2.required_size) / 1024 / 1024 / 1024, 2) as required_size_gbfrom dba_ob_table_locations t1, dba_ob_tablet_replicas t2, table_info twhere t1.svr_ip = t2.svr_ip and t1.ls_id = t2.ls_id and t1.tablet_id = t2.tablet_id and t1.database_name = t.database_name -- and t1.role='leader' and ( t1.table_name = t.table_name or t1.data_table_id = t.table_id )group by t1.database_name, t1.table_nameorder by 4 desc;