表空间监控和自动添加数据文件存储过程

由于管理的库最近发生了表空间不够的问题,原本是做了每小时任务,低于30G就邮件报警的功能,但是那天由于一位同事临时导入大量数据,导致第二天空间不够。

      为了防止这种问题的继续发生,做了表空间自动添加功能:

说明:

     首先做逻辑判断,如果当前的表空间小于配置的大小 如: 40G( 表空间的剩余和自动扩展文件的总大小),

首先创建如下视图:

    

 create or replace view  dba_tablespace_free as
select a.tablespace_name,a.total_space_mb allocated_space_mb,round(b.free_space_mb,2) free_space_mb,(a.max_space-a.total_space_mb) free_allocate_mb,round(a.max_space,2) max_space_mb,
round((a.total_space_mb-b.free_space_mb)/a.total_space_mb*100,2) pct_usage,round(a.total_space_mb/a.max_space*100,2) pct_allocated
from (select tablespace_name,sum(bytes)/1024/1024 total_space_Mb,decode(sum(maxbytes/1024/1024),0,
sum(bytes)/1024/1024,sum(case when AUTOEXTENSIBLE='YES' then maxbytes
                             else bytes end)/1024/1024) max_space
 from dba_data_files  group by tablespace_name)a,(select tablespace_name, sum((bytes)/1024/1024) free_space_Mb
 from dba_free_space group by tablespace_name) b where a.tablespace_name=b.tablespace_name;


然后创建监控存储过程:

   

create or replace procedure p_monit_tbs_ceshi  as
  --created by huangchao,2011-09-13
  --监控表空间
  vMessage         varchar(250);
  vDb_name         varchar2(10);  --数据库名
  vTBS_FREE_GB     number;        --剩余表空间阀值
  monitor_date     DATE := trunc(sysdate-2);
   v_name           varchar2(200);
  cn integer;
  lv_errinfo  varchar2(200);
  v_sql      varchar2(1000);
BEGIN
  --获取数据库名
  vTBS_FREE_GB :=40;
  select name into vDb_name from v$database;
   for x in (SELECT tablespace_name,(free_space_mb+free_allocate_mb)total_free_mb FROM dba_tablespace_free

    WHERE tablespace_name NOT IN ('TEST1_DATA') loop
    if (round(x.total_free_mb/1024,2)<= vTBS_FREE_GB) then
      begin
        vMessage := '[报警] 数据库' || vDb_name ||
                    '表空间'|| x.tablespace_name||'还剩'||x.total_free_mb|| 'MB';
        --判断磁盘组是否大于200G
        select count(1) into cn  from V$asm_Diskgroup where free_mb/1024 >200;
        if cn =0 then
           for x in (select mail from Moni_Alert_Mail where flag = 1) loop
           sendmail(Subject =>'新库每个磁盘组文件不足200G' ,v_Msg => '新库每个磁盘组文件不足200G',Receipint => x.mail);
           end loop;
       else if cn>=1 then
          select name into v_name from
          (select * from V$asm_Diskgroup where free_mb/1024 >200 order by free_mb desc) where rownum =1;
         v_sql := 'alter tablespace '||x.tablespace_name||' add datafile ''+'||v_name||''' size 256M autoextend on next 100M';
          begin
          execute immediate v_sql;
           for x in (select mail from Moni_Alert_Mail where flag = 1) loop
           sendmail(Subject =>'表空间不足,自动添加数据文件成功' ,v_Msg => vmessage||chr(10)||v_sql,Receipint => x.mail);
           end loop;
          EXCEPTION
           when others THEN
          lv_errinfo := SQLERRM;
         for x in (select mail from Moni_Alert_Mail where flag = 1) loop
           sendmail(Subject =>'警告,自动添加数据文件失败' ,v_Msg => vmessage||chr(10)||v_sql,Receipint => x.mail);
           end loop;
          end;
                end if;
         end if;
      end;
    end if;
  end loop;
  COMMIT;
end;


该存储过程每隔1小时执行一次。

 


 

 

你可能感兴趣的:(表空间监控和自动添加数据文件存储过程)