且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

通过shell脚本来统计段大小

更新时间:2022-08-14 16:20:13

今天到公司之后,就收到客户的邮件,他们提供了一个列表,希望我们能够们配合提供一份比较详细的报告,得到某个表在生产环境中所占的空间大小,他们需要根据这些信息来分析一个需求做相应的处理,这个问题处理起来还是很容易的,感觉分分钟搞定,但是自己去查看的时候,发现还是要考虑一些细节,
比如这个表如果是分区表,segment_type就会为TABLE PARTITION,对应的Index的segment_type就为INDEX PARTITION,如果表中含有lob列,就会在有两个相应的段,一个是数据lob段,一个是索引lob段。
所以像下面这样的表结构情况,就会生成4个段了。
create table a_part (id number,name varchar2(100),status varchar2(10),content clob)
partition by range(id)
(
partition p1 values less than (10),
partition p2 values less than (50),
partition p3 values less than (100)
);

因为列表比较长,一个一个去查也太没水平了,磨刀不误砍柴工,我就索引写了个shell脚本,很快就得到了结果,而且对于信息的分析也更加详实。
shell脚本的内容如下:
sqlplus -s n1/n1 set linesize 200
col segment_name format a25
set pages 50
set feedback off
set linesize 200
col table_name format a25
col segment_name format a25
 select s.segment_name table_name,
       s.segment_name,
       s.segment_type,
       sum(bytes) / 1024 / 1024 size_MB
  from user_segments s
 where segment_name = upper('$1')
   and segment_type in ('TABLE', 'TABLE PARTITION')
 group by s.segment_name, s.segment_type
union all
select l.table_name,s.segment_name, s.segment_type, sum(s.bytes)/1024/1024 size_MB
  from user_segments s, user_lobs l
 where s.segment_name = l.segment_name
   and l.table_name = upper('$1')
   and s.segment_type in ( 'LOB PARTITION')
   group by l.table_name, s.segment_name, s.segment_type
union all
 select s.segment_name table_name,
       s.segment_name,
       s.segment_type,
       sum(bytes) / 1024 / 1024 size_MB
  from user_segments s
 where segment_name segment_name in
       (select index_name from user_indexes where table_name = upper('$1'))
   and segment_type in ('INDEX', 'INDEX PARTITION')
 group by s.segment_name, s.segment_type;
EOF

脚本运行的结果如下:
TABLE_NAME                SEGMENT_NAME              SEGMENT_TYPE          SIZE_MB
------------------------- ------------------------- ------------------ ----------
A_PART                    A_PART                    TABLE PARTITION            11
                          SYS_LOB0000091627C00004$$ LOB PARTITION           .1875
                          SYS_IL0000091627C00004$$  INDEX PARTITION         .1875
                          IDX_A_PART                INDEX PARTITION            12
可以看到对于表A_PART,得到的段信息也是一目了然,如果需要统计多个维度的信息,稍作修改即可,还是比较方便的。
如果为非分区表,结果就相对简单很多,也是一目了然。
TABLE_NAME                SEGMENT_NAME              SEGMENT_TYPE          SIZE_MB
------------------------- ------------------------- ------------------ ----------
TEST                      TEST                      TABLE                       2
                          IDX_TEST                  INDEX                      .5