ORACLE查詢臨時表空間使用率一直是100%的緣由

文章中關鍵技術解釋取自瀟湘隱者大神的博客園
地址: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');

如圖所示:
臨時表空間使用率爲100%數據庫

用另一個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')

第二種狀況發現temp實際是0%

固然在分析這個問題的時候發現本身當時創建表空間而且指定默認表空間的時候,錯誤的將默認表空間指給了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

相關文章
相關標籤/搜索