文章中關鍵技術解釋取自瀟湘隱者大神的博客園
地址:http://www.cnblogs.com/kerryc...html
近期公司一個項目的oracle數據庫須要優化,在優化過程當中同事發現了一個問題:
用同事給的sql進行查詢SYSAUX,'SYSTEM,UNDOTBS1,TEMP表空間時,發現TEMP表空間使用率爲100%sql
SELECT * FROM ( SELECT D.TABLESPACE_NAME, SPACE || 'M' "SUM_SPACE(M)", BLOCKS "SUM_BLOCKS", SPACE - NVL (FREE_SPACE, 0) || 'M' "USED_SPACE(M)", ROUND ( (1 - NVL (FREE_SPACE, 0) / SPACE) * 100, 2) || '%' "USED_RATE(%)", FREE_SPACE || 'M' "FREE_SPACE(M)" FROM ( SELECT TABLESPACE_NAME, ROUND (SUM (BYTES) / (1024 * 1024), 2) SPACE, SUM (BLOCKS) BLOCKS FROM DBA_DATA_FILES GROUP BY TABLESPACE_NAME) D, ( SELECT TABLESPACE_NAME, ROUND (SUM (BYTES) / (1024 * 1024), 2) FREE_SPACE FROM DBA_FREE_SPACE GROUP BY TABLESPACE_NAME) F WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+) UNION ALL SELECT D.TABLESPACE_NAME, SPACE || 'M' "SUM_SPACE(M)", BLOCKS SUM_BLOCKS, USED_SPACE || 'M' "USED_SPACE(M)", ROUND (NVL (USED_SPACE, 0) / SPACE * 100, 2) || '%' "USED_RATE(%)", NVL (FREE_SPACE, 0) || 'M' "FREE_SPACE(M)" FROM ( SELECT TABLESPACE_NAME, ROUND (SUM (BYTES) / (1024 * 1024), 2) SPACE, SUM (BLOCKS) BLOCKS FROM DBA_TEMP_FILES GROUP BY TABLESPACE_NAME) D, ( SELECT TABLESPACE_NAME, ROUND (SUM (BYTES_USED) / (1024 * 1024), 2) USED_SPACE, ROUND (SUM (BYTES_FREE) / (1024 * 1024), 2) FREE_SPACE FROM V$TEMP_SPACE_HEADER GROUP BY TABLESPACE_NAME) F WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+) ORDER BY 1) WHERE TABLESPACE_NAME IN ('SYSAUX','SYSTEM','UNDOTBS1','TEMP');
如圖所示:
數據庫
用另一個SQL查詢TEMP表空間的實際使用狀況,發現實際上TEMP已經被oracle回收,實際利用率爲0%oracle
SELECT D.tablespace_name, SPACE "SUM_SPACE(M)", blocks "SUM_BLOCKS", used_space "USED_SPACE(M)", Round(Nvl(used_space, 0) / SPACE * 100, 2) "USED_RATE(%)", SPACE - used_space "FREE_SPACE(M)" FROM (SELECT tablespace_name, Round(SUM(bytes) / (1024 * 1024), 2) SPACE, SUM(blocks) BLOCKS FROM dba_temp_files GROUP BY tablespace_name) D, (SELECT tablespace, Round(SUM(blocks * 8192) / (1024 * 1024), 2) USED_SPACE FROM v$sort_usage GROUP BY tablespace) F WHERE D.tablespace_name = F.tablespace(+) AND D.tablespace_name in ('TEMP', 'TEMP1')
固然在分析這個問題的時候發現本身當時創建表空間而且指定默認表空間的時候,錯誤的將默認表空間指給了oracle建庫的時候的臨時表空間,而本身特地劃出來的TEMP01表空間給的10G表空間一點都沒用上。。。。。因而趕忙先把臨時表空間切到TEMP01上。優化
兩種查詢結果不一致,讓我感受很好奇,因而在網上找一些資料,最後翻到瀟湘大神的博客,給出的解釋爲:spa
視圖v$temp_space_header顯示的是每個temp文件在某一個時刻使用過的最大大小,從本質上說,它顯示的是每個tempfile的初始化大小,而不是實際分配的塊大小。
因此說從視圖v$temp_space_header獲取的數據其實並非實際使用的大小,它是不許確的。那麼確定有人會問,腳本里面不是訪問的GV_$TEMP_SPACE_HEADER視圖嗎? 跟這個視圖v$temp_space_header有關係嗎? 答案是有關係,他們的數據來源是一致的,也就是說來自相同的內部表。code
呵呵,看到這裏就應該能明白了,原來第一個語句中查詢的數據庫視圖的信息是記錄了temp文件在某一時刻使用過的最大大小,這個數據庫剛創建的時候進行過impdp操做,因此確定涉及大量的數據讀寫,固然就會將oracle自帶的臨時表空間佔滿,而且默認的臨時表空間是可自動擴展的,這樣確定有一個時刻佔用率爲100%,後續即便oracle釋放了表空間,那麼按照MOS解釋,v$temp_space_header視圖確定記錄了達到100%時候的狀況,這樣用第一個語句不管怎麼查詢,TEMP表空間都會是100%。htm
根據這個現象,想到公司不少同事都遇到過臨時表空間一到100%,就瘋狂的往上擴數據文件,可是臨時表空間真的滿了嗎?經過這個例子來看,未必。也許是一直以來查詢臨時表空間的方式就有問題呢?blog
分享這個SQL,讓以前沒深刻了解過的人蔘考。get