12C SYSAUX表空间使用率高的处理
上周发现一个生产库的SYSAUX空间使用率达到了95%,24326 MB,开启了自动扩展,数据库版本12.2.0.1。
MOS上有文档详细介绍了这个问题,这种情况存在于Oracle数据库版本12.2.0.1到18.3.0.0.0,由于Optimizer Statistics Advisor新特性的引入,AUTO_STATS_ADVISOR_TASK自动任务的执行,导致SYSAUX表空间使用逐渐增长,主要表象为:
1)查看v$sysaux_occupants,SM/ADVISOR的空间使用排在第一位。
2)查看dba_segments,发现SYSAUX表空间中WRI$_ADV_OBJECTS占用最大。
此问题在21C中进行了修复。
查询视图 V$SYSAUX_OCCUPANTS 显示 SM/ADVISOR 占用空间排名靠前.
SQL> SET LINES 120
SQL> COL OCCUPANT_NAME FORMAT A30
SQL> SELECT OCCUPANT_NAME,SPACE_USAGE_KBYTES FROM V$SYSAUX_OCCUPANTS ORDER BY SPACE_USAGE_KBYTES DESC;
OCCUPANT_NAME SPACE_USAGE_KBYTES
------------------------------ ------------------
SM/ADVISOR 21390272
SM/OPTSTAT 1622208
SM/AWR 407616
XDB 63872
SM/OTHER 59200
JOB_SCHEDULER 39488
LOGMNR 14976
WM 6656
SMON_SCN_TIME 3328
SQL_MANAGEMENT_BASE 2496
PL/SCOPE 1984
SQL> SELECT * FROM (SELECT SEGMENT_NAME,OWNER,TABLESPACE_NAME,BYTES/1024/1024 "SIZE(MB)",SEGMENT_TYPE FROM DBA_SEGMENTS WHERE TABLESPACE_NAME='SYSAUX' ORDER BY BYTES DESC) WHERE ROWNUM<=10;
SEGMENT_NAME OWNER TABLESPACE SIZE(MB) SEGMENT_TYPE
------------------------------ ---------- ---------- ---------- ---------------
WRI$_ADV_OBJECTS SYS SYSAUX 11243 TABLE
WRI$_ADV_OBJECTS_IDX_01 SYS SYSAUX 5689 INDEX
WRI$_ADV_OBJECTS_PK SYS SYSAUX 3792 INDEX
I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST SYS SYSAUX 576 INDEX
I_WRI$_OPTSTAT_H_ST SYS SYSAUX 293 INDEX
I_WRI$_OPTSTAT_HH_OBJ_ICOL_ST SYS SYSAUX 72 INDEX
SYS_LOB0000007349C00005$$ SYS SYSAUX 44.1875 LOBSEGMENT
WRI$_ADV_SQLT_PLANS SYS SYSAUX 42 TABLE
SYS_LOB0000008846C00040$$ SYS SYSAUX 38.1875 LOBSEGMENT
SCHEDULER$_EVENT_LOG SYS SYSAUX 34 TABLE
在12.2.0.1中,EXECUTION_DAYS_TO_EXPIRE参数被设置为UNLIMITED,这意味着旧记录永远不会被清除。
SQL> col TASK_NAME format a25
SQL> col parameter_name format a35
SQL> col parameter_value format a20
SQL> set lines 120
SQL> select TASK_NAME,parameter_name, parameter_value FROM DBA_ADVISOR_PARAMETERS WHERE task_name='AUTO_STATS_ADVISOR_TASK' and PARAMETER_NAME='EXECUTION_DAYS_TO_EXPIRE';
TASK_NAME PARAMETER_NAME PARAMETER_VALUE
------------------------- ----------------------------------- --------------------
AUTO_STATS_ADVISOR_TASK EXECUTION_DAYS_TO_EXPIRE UNLIMITED
由于没有从WRI$_ADV_OBJECTS中清除AUTO_STATS_ADVISOR_TASK记录,SYSAUX空间使用正在迅速增长。
处理过程:
1、首先通过以下命令修改保留时间,设置保留时间为 30天:
EXEC DBMS_ADVISOR.SET_TASK_PARAMETER(task_name=> 'AUTO_STATS_ADVISOR_TASK', parameter=> 'EXECUTION_DAYS_TO_EXPIRE', value => 30);
or
EXEC DBMS_SQLTUNE.SET_TUNING_TASK_PARAMETER (task_name=> 'AUTO_STATS_ADVISOR_TASK', parameter=> 'EXECUTION_DAYS_TO_EXPIRE', value => 30);
数天后查看WRI$_ADV_OBJECTS表数据还是在增长,并没有自动清除。
2、过期的统计信息顾问记录可以使用下面的命令手动清除,而不是依赖Auto-Purge窗口。这将清除超过30天保留期的旧统计顾问记录。
SQL> conn / as sysdba
SQL> exec prvt_advisor.delete_expired_tasks;
但是这个存储过程实际上用delete的方式进行的,如果表WRI$_ADV_OBJECTS中有太多和Auto Stats Advisor Task相关的记录,删除任务时可能会需要大量undo空间.
一旦发生此状况,如下方法可以用来直接清理数据而避免产生大量redo 和undo信息 。
3、truncate WRI$_ADV_OBJECTS
### 检查表 WRI$_ADV_OBJECTS和 Auto Stats Advisor Task相关的有效条数 ###
SQL> SELECT COUNT(*) FROM WRI$_ADV_OBJECTS WHERE TASK_ID=(SELECT DISTINCT ID FROM
WRI$_ADV_TASKS WHERE NAME='AUTO_STATS_ADVISOR_TASK');
### 创建新表并保留非 AUTO_STATS_ADVISOR_TASK数据 ###
SQL> CREATE TABLE WRI$_ADV_OBJECTS_NEW AS SELECT * FROM WRI$_ADV_OBJECTS WHERE TASK_ID !=
(SELECT DISTINCT ID FROM WRI$_ADV_TASKS WHERE NAME='AUTO_STATS_ADVISOR_TASK');
SQL> SELECT COUNT(*) FROM WRI$_ADV_OBJECTS_NEW;
### 截断原表 ###
SQL> TRUNCATE TABLE WRI$_ADV_OBJECTS;
### 把备份表中数据插回原表 ###
SQL> INSERT /*+ APPEND */ INTO WRI$_ADV_OBJECTS SELECT * FROM WRI$_ADV_OBJECTS_NEW;
For 19c & above, use the below insert statement to avoid ORA-54013 error as there is a new
column SQL_ID_VC added to WRI$_ADV_OBJECTS.
SQL> INSERT INTO WRI$_ADV_OBJECTS("ID" ,"TYPE" ,"TASK_ID" ,"EXEC_NAME" ,"ATTR1" ,"ATTR2"
,"ATTR3" ,"ATTR4" ,"ATTR5" ,"ATTR6" ,"ATTR7" ,"ATTR8" ,"ATTR9"
,"ATTR10","ATTR11","ATTR12","ATTR13","ATTR14","ATTR15","ATTR16","ATTR17","ATTR18","ATTR19","A
,"SPARE_N1" ,"SPARE_N2" ,"SPARE_N3" ,"SPARE_N4" ,"SPARE_C1" ,"SPARE_C2" ,"SPARE_C3"
,"SPARE_C4" ) SELECT "ID" ,"TYPE" ,"TASK_ID" ,"EXEC_NAME" ,"ATTR1" ,"ATTR2" ,"ATTR3"
,"ATTR4" ,"ATTR5" ,"ATTR6" ,"ATTR7" ,"ATTR8" ,"ATTR9" ,"ATTR10","ATTR11","ATTR12","ATTR13","ATTR14","ATTR15","ATTR16","ATTR17","ATTR18","ATTR19","AT
,"SPARE_N1" , "SPARE_N2" ,"SPARE_N3" ,"SPARE_N4" ,"SPARE_C1" ,"SPARE_C2" ,"SPARE_C3"
,"SPARE_C4" FROM WRI$_ADV_OBJECTS_NEW;
SQL> COMMIT;
### 重建索引 ###
SQL> ALTER INDEX WRI$_ADV_OBJECTS_IDX_01 REBUILD;
SQL> ALTER INDEX WRI$_ADV_OBJECTS_PK REBUILD;
最终使用第3种方式进行了处理。
最后,可以考虑从数据字典删除统计信息任务,避免再次造成问题。
DECLARE
v_tname VARCHAR2(32767);
BEGIN
v_tname := 'AUTO_STATS_ADVISOR_TASK';
DBMS_STATS.DROP_ADVISOR_TASK(v_tname);
END;
/