使用shell脚本监控共享池内存碎片

来源:互联网 发布:浙江海关数据 编辑:程序博客网 时间:2024/06/06 07:00
 
使用shell脚本监控共享池内存碎片

环境
[monitor:/]#uname -a
HP-UX monitor B.11.11 U 9000/785 2013813380 unlimited-user license
Release 9.2.0.6.0 - Production on Thu Oct 16 10:18:15 2008
dump共享池内存信息
SQL> oradebug setmypid
Statement processed.
SQL> oradebug dump heapdump 2
Statement processed.
SQL> oradebug tracefile_name
/oracle/app/oracle/product/920/admin/robin/udump/robin_ora_4479.trc
SQL> exit
基本原理
在Oracle9i中,管理共享池内存的Free Lists被划分为255个Bucket,每个Bucket容纳的size为一定范围的内存块chunk,通过内部视图x$ksmsp来监控shared pool的碎片情况,其中每一行都代表着shared pool中的一个chunk。从heapdump中dump出来的内存信息dump到跟踪文件后,有一定的规律和格式来记载这些信息。首先通过shell脚本对这些存储桶进行格式化,过滤出存储桶编号和对应的size范围,然后使用sed和awk对其进行处理,生成查询sql语句,实现对x$ksmsp的查询,统计每个存储桶对应的记录行数。根据chunk的数量来量度碎片程度。
使用shell脚本对robin_ora_4479.trc文件进行处理
grep Bucket robin_ora_4479.trc >tmp.lst
cat tmp.lst
sed 's/size=/ksmchsiz>=/' tmp.lst >tmp2.lst
cat tmp2.lst
sed 's/ Bucket //' tmp2.lst | sort -nr > tmp.lst
cat tmp.lst
vi hxc.sh
echo 'select ksmchidx,(case'           
cat tmp.lst | while read LINE
do
  echo $LINE | awk '{print "when " $2 " then " $1}'
done
echo 'end) bucket#,'  
echo '     count(*) free_chunks,'  
echo '     sum(ksmchsiz) free_space,'  
echo '     trunc(avg(ksmchsiz)) avg_chunk_size'  
echo 'from x$ksmsp'  
echo "where ksmchcls = 'free'"
echo 'group by ksmchidx,(case';
cat tmp.lst | while read LINE
do
  echo $LINE | awk '{print "when " $2 " then " $1}'
done
echo 'end);'   

monitor:/home/oracle $chmod 777 hxc.sh
monitor:/home/oracle $sh hxc.sh

下面是输出结果(简略):
select ksmchidx,
       (case
         when ksmchsiz >= 65560 then
          254
         when ksmchsiz >= 32792 then
          253
         when ksmchsiz >= 40 then
          1
         when ksmchsiz >= 32 then
          0
       end) bucket#,
       count(*) free_chunks,
       sum(ksmchsiz) free_space,
       trunc(avg(ksmchsiz)) avg_chunk_size
  from x$ksmsp
where ksmchcls = 'free'
group by ksmchidx,
          (case
            when ksmchsiz >= 65560 then
             254
            when ksmchsiz >= 32792 then
             253
            when ksmchsiz >= 16408 then
             2
            when ksmchsiz >= 40 then
             1
            when ksmchsiz >= 32 then
             0
          end);

可以创建一张表,将结果存储起来进行分析
create table hxc_tmp as (select ksmchidx,
       (case
         when ksmchsiz >= 65560 then
          254
         when ksmchsiz >= 32792 then
          253
         when ksmchsiz >= 40 then
          1
         when ksmchsiz >= 32 then
          0
       end) bucket#,
       count(*) free_chunks,
       sum(ksmchsiz) free_space,
       trunc(avg(ksmchsiz)) avg_chunk_size
  from x$ksmsp
where ksmchcls = 'free'
group by ksmchidx,
          (case
            when ksmchsiz >= 65560 then
             254
            when ksmchsiz >= 32792 then
             253
            when ksmchsiz >= 16408 then
             2
            when ksmchsiz >= 40 then
             1
            when ksmchsiz >= 32 then
             0
          end));
查询其中的列
select t.bucket#,t.free_chunks from tmp_hxc t;
并生成图片如下:



说明:
Size越小的高峰的峰值越多,说明共享池中的碎片越多,表明bucket经过很多次分割,分割后较小的chunk越来越多,即表明每个桶(Bucket)对应的自由的内存片越多,碎片越严重,管理越复杂,从而使得搜索时间变长,latch持有时间变长,性能变差。当然,size较大的bucket的峰值可以较高,这说明内存分割不厉害。
可以对比一下,将共享池内存flush后,看看对应的图片,可以进行简单对比。



alter system flush shared_pool;



从上面可以看出,将共享池flush之后,碎片情况有所减轻。
原创粉丝点击