場景: 客戶有一套Oracle 11.2.0.4 RAC ,現有一個監控軟件,每天定時登錄db執行一批次SQL,這幾天采集程序無法正常采集就中斷了;
軟件開發人員排查發現,只要查詢表空間涉及dba_free_space的SQL執行時間變成了2分鍾!采集程序由於查詢時間過長,超時中斷連接;
一、慢sql
具體實際SQL文本不好拿出來發博客,手工執行如下sql需要2分鍾!
select count(*) from dba_free_space where tablespace_name='xx';
二、問題處理
2.1 Hint
參考 Queries on DBA_FREE_SPACE are Slow (Doc ID 271169.1) 1) In release 10g, the view dba_free_space is modified to access sys.recyclebin$ also. SQL> select text from dba_views where view_name='DBA_FREE_SPACE'; TEXT -------------------------------------------------------------------------------- select ts.name, fi.file#, f.block#, f.length * ts.blocksize, f.length, f.file# from sys.ts$ ts, sys.fet$ f, sys.file$ fi where ts.ts# = f.ts# and f.ts# = fi.ts# and f.file# = fi.relfile# and ts.bitmapped = 0 union all select /*+ ordered use_nl(f) use_nl(fi) */ ts.name, fi.file#, f.ktfbfebno, f.ktfbfeblks * ts.blocksize, f.ktfbfeblks, f.ktfbfefno from sys.ts$ ts, sys.x$ktfbfe f, sys.file$ fi where ts.ts# = f.ktfbfetsn and f.ktfbfetsn = fi.ts# and f.ktfbfefno = fi.relfile# and ts.bitmapped <> 0 and ts.online$ in (1,4) and ts.contents$ = 0 union all select /*+ ordered use_nl(u) use_nl(fi) */ ts.name, fi.file#, u.ktfbuebno, u.ktfbueblks * ts.blocksize, u.ktfbueblks, u.ktfbuefno from sys.recyclebin$ rb, sys.ts$ ts, sys.x$ktfbue u, sys.file$ fi where ts.ts# = u.ktfbuesegtsn and u.ktfbuesegtsn = fi.ts# and u.ktfbuesegfno = fi.relfile# and u.ktfbuesegtsn = rb.ts# and u.ktfbuesegfno = rb.file# and u.ktfbuesegbno = rb.block# and ts.bitmapped <> 0 and ts.online$ in (1,4) and ts.contents$ = 0 union all select ts.name, fi.file#, u.block#, u.length * ts.blocksize, u.length, u.file# from sys.ts$ ts, sys.uet$ u, sys.file$ fi, sys.recyclebin$ rb where ts.ts# = u.ts# and u.ts# = fi.ts# and u.segfile# = fi.relfile# and u.ts# = rb.ts# and u.segfile# = rb.file# and u.segblock# = rb.block# and ts.bitmapped = 0 Note for 11g database: the dba_free_space view doesn't contain hint which could also affected by the issue. In case there
is only few entries in recyclebin, you may want to gather underlying stats of tables/dictionary to get better performance.
Oracle 11.2.0.4 確實上述hint 取消了!
新建一個視圖,hint加上! SQL執行時間從2分鍾-> 0.015s
缺陷: 1.新建了一個視圖查詢dba_free_space底層基表的記錄,帶來了其它的風險!
2.由於新建一個視圖,因此需要重新授權,以及讓業務代碼進行調整!!!
優點: 1.開發人員無需了解內部機制hint解決的SQL性能問題,/*+ hint語法能解決但是寫入到程序代碼改的越多,出錯的可能性越大;
2.這種改造SQL查詢的結果沒有改變,實際結果還是dba_free_space的記錄;
2.2 清空回收站
--繼續接上面2.1的mos文檔 2) Large number of entries in sys.recyclebin$ can slow down the select on dba_free_space. 3) This is a normal behavior. Purge the recyclebin. For example: SQL> purge recyclebin; Or, as SYSDBA for system wide purging. SQL> purge dba_recyclebin; You can refer to the below document for more information: 10g Recyclebin Features And How To Disable it( _recyclebin )(Doc ID 265253.1) https://blog.csdn.net/shipeng1022/article/details/77990404 注意:在ORACLE 12C中,各個PDB和CDB之間回收站是私有的,所以對每個PDB回收站進行單獨的清空。 SQL> ALTER SESSION SET CONTAINER=ZHIXIN; Note: On 10.2/11g, the dropped table does not show up in the *_TABLES views does not show up in *_OBJECTS does show up int the *_SEGMENT views THE RECYCLE BIN The Recycle Bin is a virtual container where all dropped objects reside. Underneath the covers, the objects are occupying the same space
as when they were created. If table EMP was created in the USERS tablespace, the dropped table EMP remains in the USERS tablespace.
Dropped tables and any associated objects such as indexes, constraints, nested tables, and other dependant objects are not moved, they
are simply renamed with a prefix of BIN$$. You can continue to access the data in a dropped table or even use Flashback Query against it. Each user has the same rights and privileges on Recycle Bin objects before it was dropped.
You can view your dropped tables by querying the new RECYCLEBIN view. Objects in the Recycle Bin will remain in the database until the
owner of the dropped objects decides to permanently remove them using the new PURGE command. The Recycle Bin objects are counted against
a user's quota. But Flashback Drop is a non-intrusive feature. Objects in the Recycle Bin will be automatically purged by the space
reclamation process if o A user creates a new table or adds data that causes their quota to be exceeded. o The tablespace needs to extend its file size to accommodate create/insert operations. There are no issues with dropping the table, behaviour wise. It is the same as in 8i / 9i. The space is not released immediately and is
accounted for within the same tablespace / schema after the drop. When we drop a tablespace or a user there is NO recycling of the objects. o Recyclebin does not work for SYS owned objects #這個文檔說明回收站功能SYS無法使用??? MOS文檔Oracle Database - Enterprise Edition - Version 10.1.0.2 and later 為啥??? 測試一下 SQL> select count(*) from RECYCLEBIN$; COUNT(*) ---------- 0 SQL> create table a(id int) tablespace system; SQL> create table b(id int) tablespace sysaux; SQL> insert into a values(1); SQL> insert into b values(1); SQL> commit; SQL> drop table a; SQL> select count(*) from RECYCLEBIN$; COUNT(*) ---------- 0 SQL> drop table b; SQL> select count(*) from RECYCLEBIN$; COUNT(*) ---------- 1 SQL> select username,default_tablespace from dba_users where username='SYS'; USERNAME DEFAULT_TABLESPACE ------------------------------ ------------------------------ SYS SYSTEM SQL> select tablespace_name,CONTENTS,EXTENT_MANAGEMENT,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces; TABLESPACE_NAME CONTENTS EXTENT_MAN SEGMEN ------------------------------ --------- ---------- ------ SYSTEM PERMANENT LOCAL MANUAL SYSAUX PERMANENT LOCAL AUTO UNDOTBS1 UNDO LOCAL MANUAL TEMP TEMPORARY LOCAL MANUAL USERS PERMANENT LOCAL AUTO 准確的理解是SYSTEM, 段空間手工管理的方式無法使用回收站的功能! 禁用回收站功能 Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - 64bi SQL> ALTER SYSTEM SET "_recyclebin"=FALSE SCOPE = BOTH; On 10gR2 and higher; recyclebin is a initialization parameter and bydefault its ON. We can disable recyclebin by using the following commands: SQL> ALTER SESSION SET recyclebin = OFF; SQL> ALTER SYSTEM SET recyclebin = OFF;
!DBA在清空回收站之后,我們再次查詢dba_free_space 確實從2分鍾->0.001s; 可以解決問題!
優點:1.代碼無需調整;
2.開發無需干預,讓DBA處理就行;
缺點:1.回收站功能長期關閉,可以避免這個問題! 但是生產環境並不建議關閉這個功能!
2.回收站功能無法關閉的情況下,無法預知什么時候有大量drop table的對象導致查詢dba_free_space視圖慢再次出現! 問題可能在后續不定期再次出現!
2.3 替換視圖
dba_free_space查詢目的是計算表空間剩余空間, 以及與dba_data_files 結合算表空間空間信息;
直接替換為dba_segments 通過tablespace_name 一樣可以得到結果
SQL替換后,測試執行時間0.09s 也是很快
優點:能解決本次問題;
缺點:1.修改了代碼,並且視圖不一樣,是否影響到了數據准確性,客戶可以接收;
2.最大的問題! 當數據庫容量一直上漲,其實最后的SQL執行效率會低於dba_free_space的視圖查詢!!!
2.4 其它可能性
Query Against DBA_FREE_SPACE is Slow After Applying 11.2.0.4 (Doc ID 1904677.1) Oracle Database - Enterprise Edition - Version 11.2.0.4 and later Some queries against the dba_free_space view perform slowly after applying the 11.2.0.4 patchset The access path for the query shows that it performs a Full Table Scan (FTS) against the fixed table X$KTFBUE: STAT #4573482064 id=19 cnt=7586689 pid=18 pos=1 obj=0 op='FIXED TABLE FULL X$KTFBUE
(cr=102462 pr=22059 pw=0 time=129742890 us cost=1 size=151579380 card=7578969)' Gathering statistics on X$KTFBUE using : EXEC dbms_stats.gather_fixed_objects_stats(); does not help. Emptying the recycle bin (RECYCLEBIN$) does not help either CHANGES Applied the 11.2.0.4 patch set. CAUSE By default, statistics are not gathered for some fixed tables(X$) and thus they use defaults; it may be too expensive to gather statistics or the volatility of the tables is such that any statistics are immediately out-dated. The sys.x$ktfbue table is one such object. SOLUTION In some cases, deleting and regenerating dictionary statistics resolves the slow performance of the queries against DBA_FREE_SPACE: exec DBMS_STATS.DELETE_DICTIONARY_STATS; exec DBMS_STATS.GATHER_DICTIONARY_STATS;
如果檢查發現是SQL最慢是消耗在TABLE FULL X$KTFBUE 基表的全表掃描執行計划中時!
1.清空回收站,無法解決這個問題;
2.收集基表統計信息無效果;
3.可以嘗試刪除數據字典統計信息后,在重新收集!!! 風險比較大,網上有另外一種替代的解決方法!
參考
https://my.oschina.net/u/4594060/blog/4513301
你可以重新創建一個新的view,比如tiger_free_space,
原hint:/*+ ordered use_nl(u) use_nl(fi) */
替換成下面內容:
/*+
FULL( "RB")
FULL( "TS")
FULL( "U")
INDEX_RS_ASC( "FI" ("FILE$"."TS#" "FILE$"."RELFILE#"))
LEADING( "RB" "TS" "U" "FI" )
USE_HASH( "TS")
USE_NL( "U")
USE_NL( "FI")
*/
這樣相當於就不用根據MOS 進行數據字典統計信息刪除、重新收集的操作!