oracle12.2 rac清理sysaux表空间

时间:2024-04-07 17:45:36

1、需求背景

通过zmc日常监控发现oracle rac数据库的syaux表空间使用率达到91.6%。

oracle12.2 rac清理sysaux表空间

 

进一步查询该表空间的大表对象:

oracle12.2 rac清理sysaux表空间

 

可以看到占用前三的大对象,都是由统计信息导致的。1、3行是索引,第2行是表,而1,3行都是第2行的表上面的索引。

2、清理思路

由metlink可知,oracle会通过dbms_stats.purge_stats自动定时清理统计数据,但是dbms_stats.purge_stats包清理的时候是使用的delete语句,这样长久以往,会导致表的高水位不断上涨而不降,同时索引也会导致大量碎片。所以针对这个逻辑,我们清理的时候就要考虑降表的高水位,而针对索引就需要shrink或者rebuild。

3、执行步骤

3.1、前提条件检查

3.1.1、确认该大表对应索引

select OWNER,INDEX_NAME,TABLE_OWNER,TABLE_NAME,STATUS from dba_indexes t where t.table_name='WRI$_OPTSTAT_HISTGRM_HISTORY';

oracle12.2 rac清理sysaux表空间

 

3.1.2、确认users表空间大小足够

由于我们降表的高水位是使用的move,所以我们需要借助一个中间表空间,先将WRI$_OPTSTAT_HISTGRM_HISTORY该表move到一个新的表空间中,然后在move回来。而该中间表空间我们使用users。由于sysaux表空间并不大,所以对中间表空间的空间要求并不大,你也可以选取一个任意空间足够的业务表空间来操作,但是注意,如果使用非users表空间,注意要改下面的执行脚本中的users表空间为你指定的业务表空间。确认了tab_cc表空间比较大,所以如下脚本调整使用了tab_cc表空间。

3.1.3、确认收集统计时间

set lines 200

col WINDOW_NAME for a20

col REPEAT_INTERVAL for a60

col DURATION  for a20

SELECT w.window_name,

               w.repeat_interval,

               w.duration,

               w.enabled

          FROM dba_autotask_window_clients c, dba_scheduler_windows w

         WHERE c.window_name = w.window_name AND c.optimizer_stats = 'ENABLED';

oracle12.2 rac清理sysaux表空间

 

oracle12.2默认自动收集统计信息是周一到周五晚上10点,持续4个小时收集统计信息,周六周日每天6点,持续20个小时收集统计信息。执行该清理操作,最好避开这两个时间。

3.2、清理脚本

该脚本需要使用sys用户以dba的身份登录执行。

执行前查询表空间使用率:

[email protected][/home/oraclerac]$export ORACLE_SID=test1

[email protected][/home/oraclerac]$sqlplus / as sysdba

set linesize 1000

col tablespace_name format a20 ;

select t1.tablespace_name "tablespace_name",t1.flag "type",trunc(t1.bytes-nvl(t2.bytes,0),2) "used space(G)",

trunc(nvl(t2.bytes,0),2) "free space(G)",trunc(t1.bytes,2) "sum space(G)",100-round(100*nvl(t2.bytes,0)/t1.bytes,2) "used pct",

round(100*nvl(t2.bytes,0)/t1.bytes,2) "free pct",trunc(t1.maxbytes,2) "max extend space"

from (

SELECT tablespace_name,sum(d1.bytes)/1024/1024/1024bytes,'NORMAL' FLAG,

sum(decode(d1.autoextensible,'NO',d1.bytes,d1.maxbytes))/1024/1024/1024 maxbytes

FROM dba_data_files d1

GROUP BY tablespace_name

UNION all

SELECT tablespace_name,sum(d2.bytes)/1024/1024/1024bytes,'TEMP' FLAG,

sum(decode(d2.autoextensible,'NO',d2.bytes,d2.maxbytes))/1024/1024/1024 maxbytes

FROM dba_temp_files d2

GROUP BY tablespace_name ) t1,(

SELECT tablespace_name,sum(f.bytes)/1024/1024/1024 bytes

FROM dba_free_space f

GROUP BY tablespace_name ) t2

where t1.tablespace_name = t2.tablespace_name(+)

ORDER by t1.flag,t1.tablespace_name ;

oracle12.2 rac清理sysaux表空间

 

查询sysaux表空间大对象使用情况:

set linesize 1000

col segment_name format a40

col segment_type format a20

col total_mb format  99999.99

select *

  from (select segment_name, SEGMENT_TYPE, sum(bytes) / 1024 / 1024 total_mb

          from dba_segments

         where tablespace_name = 'SYSAUX'

         group by segment_name, SEGMENT_TYPE

         order by 3 desc)

 where rownum <= 20;

oracle12.2 rac清理sysaux表空间

 

执行清理脚本:

declare

  v_sql   varchar2(4000);

 TYPE tab_partion IS record(

      TABLE_OWNER dba_tab_partitions.TABLE_OWNER%TYPE,

      TABLE_NAME dba_tab_partitions.TABLE_NAME%TYPE,

      PARTITION_NAME dba_tab_partitions.PARTITION_NAME%TYPE,

      TABLESPACE_NAME dba_tab_partitions.TABLESPACE_NAME%TYPE

      );

      type t_tab_partitions is table of tab_partion index by binary_integer ;

      v_tab_partitions t_tab_partitions ;

begin

  v_sql:='ALTER INDEX I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST SHRINK SPACE' ;

  execute immediate v_sql ;

  v_sql:='ALTER INDEX I_WRI$_OPTSTAT_H_ST SHRINK SPACE' ;

  execute immediate v_sql ;

  select TABLE_OWNER,TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME

       bulk collect into v_tab_partitions

   from dba_tab_partitions t where t.table_name='WRI$_OPTSTAT_HISTGRM_HISTORY' ;

   for i in 1..v_tab_partitions.count loop

     v_sql:='alter table '||v_tab_partitions(i).TABLE_OWNER||'.'||v_tab_partitions(i).TABLE_NAME||' move partition '||v_tab_partitions(i).PARTITION_NAME||' tablespace tab_cc' ;

     execute immediate v_sql ;

     v_sql:='alter table '||v_tab_partitions(i).TABLE_OWNER||'.'||v_tab_partitions(i).TABLE_NAME||'  move partition '||v_tab_partitions(i).PARTITION_NAME||'  tablespace sysaux' ;

     execute immediate v_sql ;

   end loop ;

   v_sql:='ALTER INDEX I_WRI$_OPTSTAT_H_ST rebuild online' ;

   execute immediate v_sql ;

   v_sql:='ALTER INDEX I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST rebuild online' ;

   execute immediate v_sql ;

end ;

/

oracle12.2 rac清理sysaux表空间

 

确保执行成功。

然后在使用上面的查询表空间使用率和查询大对象的语句查询,会发现之前三个大对象的空间占用已经变小了。而sysaux表空间的使用率也已经降下来了。

4影响说明

由于使用的是oracle12.2版本的rac版本,所以上面的操作只需要在一个节点上执行就行了。虽然脚本本身已经考虑了不影响在线业务,但是也需要在业务量小的时候去做上面的操作。该操作无需任何停机。我上面的截图均是在所内测试环境中的截图,实际查询结果以执行操作的环境为准。