對於SYSAUX表空間而言,如果占用過大,那么一般情況下是由於AWR信息或對象統計信息沒有及時清理引起的,具體原因可以通過如下的SQL語句查詢:
SELECT OCCUPANT_NAME "Item",SPACE_USAGE_KBYTES / 1048576 "Space Used (GB)",SCHEMA_NAME "Schema",MOVE_PROCEDURE "Move Procedure"FROM V$SYSAUX_OCCUPANTS WHERE SPACE_USAGE_KBYTES > 1048576 ORDER BY "Space Used (GB)" DESC;
或者如下語句
SELECT D.SEGMENT_NAME, D.SEGMENT_TYPE,SUM(BYTES)/1024/1024 SIZE_M FROM DBA_SEGMENTS D WHERE D.TABLESPACE_NAME = 'SYSAUX' GROUP BY D.SEGMENT_NAME, D.SEGMENT_TYPE ORDER BY SIZE_M DESC
或者如下語句,查看前十
SELECT * FROM (SELECT SEGMENT_NAME, PARTITION_NAME, SEGMENT_TYPE, BYTES / 1024 / 1024 FROM DBA_SEGMENTS WHERE TABLESPACE_NAME = 'SYSAUX' ORDER BY 4 DESC) WHERE ROWNUM <= 10;
如果OCCUPANT_NAME列為SM/AWR(Server Manageability - Automatic Workload Repository),那么表示AWR信息占用過大;如果該列為SM/OPTSTAT(Server Manageability - Optimizer Statistics History),那么表示優化器統計信息占用過大。
如上截圖,則是AWR信息過大,那么可以通過設置AWR的保留時間來減小AWR信息的存儲空間,通過如下的SQL語句可以獲取AWR的保留時間。
SELECT * FROM DBA_HIST_WR_CONTROL;
截圖中可以看出在Oracle 11g中,AWR默認保留8天。Oracle版本為11.2.0.4.0,AWR默認保留期限8天。但是為什么會占用這么多SYSAUX表空間呢?首先,要明確AWR快照信息的刪除方式:AWR報告默認是采取DELETE
的方式進行過期信息刪除的,相比TRUNCATE而言,就會產生大量的碎片,對於開啟了自動擴展數據文件的表空間而言,碎片的現會象更加嚴重。再有一點,ASH的信息在有可能不受AWR快照保留策略的控制。從如下SQL查詢可得知,從SNAP_ID為1的快照到目前為止的所有快照都還在數據庫中保存着,使用DBMS_WORKLOAD_REPOSITORY包清理過期或者不需要的AWR數據,可以回收這部分空間,但是由於是delete操作,無法降低水位線,對於自動擴展的表空間,碎片化更加嚴重。
select min(snap_id),max(snap_id) from wrh$_active_session_history;
臨時解決辦法
直接查詢出是哪些表分區
select distinct 'truncate table '||segment_name||';',s.bytes/1024/1024 from dba_segments s where s.segment_name like 'WRH$%' and segment_type in ('TABLE PARTITION', 'TABLE') and s.bytes/1024/1024>100 order by s.bytes/1024/1024/1024 desc;
然后直接truncate。
終極解決辦法
首先使用DBMS_WORKLOAD_REPOSITORY包清理快照信息(清理時間受快照數量和服務器性能影響,像我這清理大概用了四十分鍾)。
exec DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE (low_snap_id =>1,high_snap_id => 34000);
通過這種方式清理的AWR信息,再次查看SYSAUX表空間的空間,發現空間並沒有被回收,使用率還和之前一樣,這是因為清理AWR操作是通過DELETE操作實現的,表的水位線並沒有下降導致的。但是通過再次查詢可發現 WRH$_LATCH表記錄已經少了。但是表大小還是沒有變化。
對分區進行MOVE操作,回收表空間
按照以下步驟,根據實際情況,對每個表分區進行操作。這個表是分區表,分區表不支持表級別的MOVE操作,直接對分區表進行MOVE操作會遇到ORA-14511錯誤。示例如下
1、首先查看表的分區情況以及大小
select segment_name,partition_name,bytes/1024/1024/1024 gb from dba_segments where segment_name='WRH$_EVENT_HISTOGRAM';
2、對分區表進行MOVE操作,回收空間
alter table WRH$_EVENT_HISTOGRAM move partition WRH$_EVENT__2646583334_0;
alter table WRH$_EVENT_HISTOGRAM move partition WRH$_EVENT_HISTO_MXDB_MXSN;
3、MOVE后,重建分區表索引
##查看分區表索引信息 select index_name from dba_indexes where table_name='WRH$_EVENT_HISTOGRAM';
##重建分區表索引
SQL> select index_name from dba_indexes where table_name='WRH$_EVENT_HISTOGRAM';
INDEX_NAME
------------------------------
WRH$_EVENT_HISTOGRAM_PK
SQL> alter index WRH$_EVENT_HISTOGRAM_PK rebuild partition WRH$_EVENT__2646583334_0;
SQL> alter index WRH$_EVENT_HISTOGRAM_PK rebuild partition WRH$_EVENT_HISTO_MXDB_MXSN;
使用toad查看水位已經降了下來
其他表也照此操作處理即可。
流程可以參考下圖,先在plsql上查詢top10和編輯語句,直接復制到服務器sql窗口執行,方便快捷。
經過處理幾個表后,水位線已經降下大半,由於該測試操作的數據庫后期已經不再使用,剩下的就不處理了,實際情況需要根據生產情況確定。
------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
今日發現一個博客,說了一些處理上的風險,部分數據庫可以參考這個清理,尤其對那些繁忙的數據庫。
地址如下
http://blog.itpub.net/26148431/viewspace-2135213/
參考原文鏈接:https://blog.csdn.net/lihuarongaini/article/details/101298827