SYSAUX表空间使用率暴增处理方式

  • 问题版本:oracle 12.2.0.1及更高版本

最近给客户检查时发现客户的SYSAUX表空间随着业务量越增越多,排查确认是AUTO_STATS_ADVISOR_TASK客户环境中出现两种情况:一是手工执行exec prvt_advisor.delete_expired_tasks后,过期的统计信息顾问记录仍未被清除;二是本应自动清理的过期统计信息顾问记录未按时清除。经测试确认,该问题为 BUG 38326922(涉及版本≥19.27 且 < 25.1),需通过打补丁(Patch 38326922)或升级至 19.29 及以上版本修复。

若自查发现最旧的统计信息时间早于保留天数,且数据库版本在 19.26-19.28 左右,大概率是该 BUG 导致,建议尽早处理。

确认V$SYSAUX_OCCUPANTS中空间使用率占用最高的一项:

sql 复制代码
SET LINES 120   
COL OCCUPANT_NAME FORMAT A30   
SELECT OCCUPANT_NAME,SPACE_USAGE_KBYTES/1024/1024 AS SPACE_USAGE_GB FROM V$SYSAUX_OCCUPANTS ORDER BY SPACE_USAGE_KBYTES DESC;

查询DBA_SEGMENTS中SUSAUX表空间空间使用率最高的SEGMENT:

复制代码
 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;

确认使用率最大的为SM/ADVISOR与WRI$_ADV_OBJECTS时,可参考下方方法进行清理旧的Statistics Advisor

删除统计信息顾问任务(STATS_ADVISOR_ASK)

方法一:清空大量统计信息(AUTO_STATS_ADVISOR_TASK的数据全部清空,即使是bug版本也可以直接清理)

以sysdba身份执行以下命令:

复制代码
DECLARE 
v_tname VARCHAR2(32767); 
BEGIN 
v_tname := 'AUTO_STATS_ADVISOR_TASK'; 
DBMS_STATS.DROP_ADVISOR_TASK(v_tname); 
END;
/

注:情况后重新初始化才会有AUTO_STATS_ADVISOR_TASK的任务

复制代码
EXEC DBMS_STATS.INIT_PACKAGE();

方法二:手动清除过期的统计信息顾问记录

清除EXECUTION_DAYS_TO_EXPIRE的日期之前的AUTO_STATS_ADVISOR_TASK

sql 复制代码
exec prvt_advisor.delete_expired_tasks;

保留天数参考:

sql 复制代码
SELECT NAME,VALUE FROM wri$_adv_parameters WHERE task_id in (
SELECT ID FROM SYS.WRI$_ADV_TASKS WHERE NAME = 'AUTO_STATS_ADVISOR_TASK' and owner_name = 'SYS'
) AND NAME IN ('DAYS_TO_EXPIRE','EXECUTION_DAYS_TO_EXPIRE');

为避免delete数据量过大导致undo爆掉,可考虑下方的循环删除的方式:

清除30天前的统计信息,每次删除过期20天的任务

复制代码
set serveroutput on      
DECLARE      
    v_oldest INTEGER := 730;    -- 最老的数据为2年      
    v_increment INTEGER := 30;    -- 删除循环步长30天
    v_cur_age INTEGER;      
    v_min_age INTEGER := 30;     -- 保留一个月 ,该参数会影响EXECUTION_DAYS_TO_EXPIRE的结果    
BEGIN      
    v_cur_age := v_oldest;      
    WHILE v_cur_age >= v_min_age LOOP      
        dbms_sqltune.set_tuning_task_parameter(task_name => 'AUTO_STATS_ADVISOR_TASK', parameter => 'EXECUTION_DAYS_TO_EXPIRE', value => v_cur_age);      
        prvt_advisor.delete_expired_tasks;      
        v_cur_age := v_cur_age - v_increment;      
    END LOOP;      
EXCEPTION      
    WHEN OTHERS THEN      
        dbms_output.put_line('Execution halted with error number ' || sqlerrm);      
END;      
/

已执行的的统计信息时间参考SQL

sql 复制代码
select task_id, execution_name, execution_start, status
from dba_advisor_executions
where TASK_NAME='AUTO_STATS_ADVISOR_TASK'
order by execution_start desc;

https://support.oracle.com/support/?anchorId=\&documentId=KB122548\&page=sptemplate\&sptemplate=km-article

删除该任务后,重新组织表WRI$_ADV_ADTS及其索引

复制代码
SQL> ALTER TABLE WRI$_ADV_OBJECTS MOVE;   
SQL> ALTER INDEX WRI$_ADV_OBJECTS_IDX_01 REBUILD;   
SQL> ALTER INDEX WRI$_ADV_OBJECTS_PK REBUILD;  
SQL> ALTER INDEX WRI$_ADV_OBJECTS_IDX_02 REBUILD;
  • 重建后确认索引是可用的

    column index_name format a30
    select index_name,status from dba_indexes where table_name='WRI$_ADV_OBJECTS' and index_type like '%NORMAL';

  • 多租户环境,需按照以下方式进行重建:

    SQL> alter session set container=emrepdb;
    SQL> exec dbms_pdb.exec_as_oracle_script('ALTER TABLE WRI_ADV_OBJECTS MOVE'); SQL> exec dbms_pdb.exec_as_oracle_script('ALTER INDEX WRI_ADV_OBJECTS_PK REBUILD');
    SQL> exec dbms_pdb.exec_as_oracle_script('ALTER INDEX WRI_ADV_OBJECTS_IDX_01 REBUILD'); SQL> exec dbms_pdb.exec_as_oracle_script('ALTER INDEX WRI_ADV_OBJECTS_IDX_02 REBUILD');

测试执行参考命令

  • 手工执行AUTO_STATS_ADVISOR_TASK
sql 复制代码
DECLARE
  v_tname   VARCHAR2(128) := 'AUTO_STATS_ADVISOR_TASK';
BEGIN
  -- execute the task
  v_tname := DBMS_STATS.EXECUTE_ADVISOR_TASK(v_tname);
END;
/
  • 修改AUTO_STATS_ADVISOR_TASK的过期日期
sql 复制代码
EXEC DBMS_ADVISOR.SET_TASK_PARAMETER(task_name=> 'AUTO_STATS_ADVISOR_TASK', parameter=> 'EXECUTION_DAYS_TO_EXPIRE', value => 10);
  • 确认保留日期
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'; 
  • 确认执行情况
sql 复制代码
select task_id, execution_name, execution_start, status
from dba_advisor_executions
where TASK_NAME='AUTO_STATS_ADVISOR_TASK'
order by execution_start desc;
相关推荐
怣503 小时前
MySQL多表连接:全外连接、交叉连接与结果集合并详解
数据库·sql
wjhx4 小时前
QT中对蓝牙权限的申请,整理一下
java·数据库·qt
冰暮流星4 小时前
javascript之二重循环练习
开发语言·javascript·数据库
万岳科技系统开发4 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
冉冰学姐4 小时前
SSM智慧社区管理系统jby69(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·管理系统·智慧社区·ssm 框架
杨超越luckly5 小时前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强
Elastic 中国社区官方博客5 小时前
Elasticsearch:Workflows 介绍 - 9.3
大数据·数据库·人工智能·elasticsearch·ai·全文检索
仍然.5 小时前
MYSQL--- 聚合查询,分组查询和联合查询
数据库
一 乐5 小时前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
啦啦啦_99995 小时前
Redis-0-业务逻辑
数据库·redis·缓存