暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle水位利用存储过程实现自动检查收缩

ORACLE DBA LIFE 2021-04-21
672

Oracle水位收缩过程

原理

利用过程调用外层视图检查出对应的表,进行自动水位收缩

存储过程调用的视图

--grant select any dictionary to TEST;

--grant analyze any to TEST;

--grant create table to TEST;

--可以通过下面这个视图来指定表范围,下面的过程是调用这个视图里面最小的那张表进行碎片整理。


create or replace view test.v_shrinktable as 

select t.*,

               round((t.realkb / t.hwmkb) * 100) pct,

               s.bytes 

          from (select aa.OWNER,

                       aa.TABLE_NAME,

                       aa.NUM_ROWS,

                       aa.AVG_ROW_LEN,

                       round(blocks *

                             (select value

                                from v$parameter

                               where name = 'db_block_size') / 1024 / 1024) hwmkb

                       --,round(blocks*(select value from v$parameter where name ='db_block_size')/1024*pct_free/100) pctkb,

                      ,

                       ROUND((num_rows * avg_row_len / 1024)) realkb1,

                       ROUND((num_rows * avg_row_len / 1024 / 1024)) realkb,

                       aa.LAST_ANALYZED

                  from dba_tables aa

                 where aa.owner  in ('H2','H2LOG')

                   and aa.NUM_ROWS >= 0) t,

               dba_segments s

         where t.hwmkb > 100

           and t.owner = s.owner

           and t.table_name = s.segment_name

           and t.table_name not in ('T')  --排除表

           and round((t.realkb / t.hwmkb) * 100) < 70   --碎片情况

           and bytes < 10000000000   --表大小限制

         order by bytes;





具体存储过程内容

--对应过程

create  procedure test.shrink_table(user IN  VARCHAR2) is

v_sql long:='';

v_sqltemp long:='';

P_TOTALRECORDS number:=0;

p_date date;



BEGIN

  --记录中总记录条数

  V_SQL := 'SELECT TO_NUMBER(COUNT(*)) FROM  dba_tables where owner=(''' || user ||''')  and table_name=('''||'SHRINKTABLE_NEED_HIS'||''') ';


  EXECUTE IMMEDIATE V_SQL INTO P_TOTALRECORDS;


  IF P_TOTALRECORDS < 1 THEN

    EXECUTE IMMEDIATE 'create table  shrinktable_need_his(owner varchar2(80),table_name varchar2(80),bytes_start number,bytes_end number,pct number,shrink_time varchar2(80))';

  END IF;



for i in (select owner||'.'||table_name as tablename,t.* from (select * from (select owner,table_name,bytes as bytes_start,0 as bytes_end,pct from v_shrinktable  b  order by bytes_start) a where rownum=1) t )

     loop

         EXECUTE IMMEDIATE ( 'insert into shrinktable_need_his values ('''||i.owner||''','''||i.table_name||''','||i.bytes_start||','||i.bytes_end||','||i.pct||','''||to_char(sysdate,'yyyymmdd')||'''  )');

         EXECUTE IMMEDIATE ' alter table ' || i.tablename || ' enable row movement';

         EXECUTE IMMEDIATE ' alter table ' || i.tablename || ' shrink space cascade';

         EXECUTE IMMEDIATE ' alter table ' || i.tablename || ' disable row movement';

         dbms_stats.gather_table_stats(ownname => user,tabname  =>i.table_name,degree =>10,cascade =>true,estimate_percent =>25);     

         v_sqltemp := 'update  shrinktable_need_his a set  a.bytes_end =(select b.bytes from dba_segments b where b.owner=' ||'('''||i.owner||''')'||' and b.segment_name='||'('''||i.table_name||''') )'||

        'where a.owner=' ||'('''||i.owner||''')'||' and a.table_name='||'('''||i.table_name||''') ';

        EXECUTE IMMEDIATE( v_sqltemp);

    end loop;

commit;

end shrink_table;


exec    shrink_table('TEST');

——执行命令,括号里接schema名




文章转载自ORACLE DBA LIFE,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论