ORA-1652是oracle常見錯誤之一,該錯誤主要是由於臨時表空間不足導致。
1.ORACLE數據庫中涉及到排序操作的一些行為:
排序是非常消耗系統資源的操作,所以應該盡量避免或者減少.以下行為會涉及到排序操作:
創建索引
GROUP BY或者ORDER BY操作
DISTINCT操作
UNION,INTERSECT,MINUS操作
Sort-Merge join操作(如果沒有索引的情況下,等連接加上排序操作通常會采用該連接方式)
ANALYZE操作
CREATE PRIMARY KEY CONSTRAINT, ENABLE CONSTRAINT, CREATE TABLE AS SELECT
2.查詢臨時表空間使用率
臨時表空間和回滾表空間一樣,分配的extents都是可以重復使用的,他們的使用率查詢不能和普通表空間一樣查詢dba_free_space等視圖,對於臨時表空間的使用率
我們可以借助以下視圖和方法進行查詢:
V$SORT_USAG
V$SORT_SEGMENT
V$TEMP_SPACE_HEADER
V$TEMP_EXTENT_POOL
1)SQL> select 'the '||name||' temp tablespaces '||tablespace_name||' idle '||round(100-(s.tot_used_blocks/s.total_blocks)*100,3)||'% at '||to_char (sysdate,'yyyymmddhh24miss') 2)SQL> col DatafileName for a30 SQL> set lin 150 SQL> Select round((f.bytes_free + f.bytes_used) / 1024 / 1024, 2) "total MB", 2 round(((f.bytes_free + f.bytes_used) - nvl(p.bytes_used, 0)) / 1024 / 1024, 2) "Free MB" , 3 d.file_name "DatafileName", 4 round(nvl(p.bytes_used, 0)/ 1024 / 1024, 2) "Used MB", 5 round((f.bytes_free + f.bytes_used) / 1024, 2) "total KB", 6 round(((f.bytes_free + f.bytes_used) - nvl(p.bytes_used, 0)) / 1024, 2) "Free KB", 7 round(nvl(p.bytes_used, 0)/ 1024, 2) "Used KB", 8 0 "Fragmentation Index" 9 from V$TEMP_SPACE_HEADER f, DBA_TEMP_FILES d, V$TEMP_EXTENT_POOL p 10 where f.tablespace_name(+) = d.tablespace_name 11 and f.file_id(+) = d.file_id
12 and p.file_id(+) = d.file_id; 3)SQL> COL SQL_TEXT FOR A30 SQL> SELECT SESS.SID, SESS.SERIAL#, SEGTYPE, BLOCKS*8/1024 "MB" ,SESS.SQL_ID ,SQL_TEXT 2 FROM V$SORT_USAGE SORT, V$SESSION SESS ,V$SQL SQL 3 WHERE SORT.SESSION_ADDR = SESS.SADDR 4 AND SQL.SQL_ID = SESS.SQL_ID 5 ORDER BY BLOCKS DESC; 4)SQL> COL USENAME FOR A10 SQL> COL OSUSER FOR A10 SQL> COL TABLESPACE FOR A15 SQL> COL SQL_TEXT FOR A30 SQL> SELECT A.USERNAME, A.SID, A.SERIAL#, A.OSUSER, B.TABLESPACE, B.BLOCKS, C.SQL_TEXT 2 FROM V$SESSION A, V$TEMPSEG_USAGE B, V$SQLAREA C 3 WHERE A.SADDR = B.SESSION_ADDR 4 AND C.ADDRESS= A.SQL_ADDRESS 5 AND C.HASH_VALUE = A.SQL_HASH_VALUE 6 ORDER BY B.TABLESPACE, B.BLOCKS;
3. ORA-1652錯誤出現了,我們就需要找出到底是什么操作占用了大量的臨時表空間,一般我們可以通過在第二部分中提供的查詢方法去查詢正在占用大量臨時段的操作,但是
事實上當我們發現警告日志中的ORA-1652錯誤的時候,排序操作已經完成並且釋放了空間,這種情況下我們可以借助以下幾種方法來查找相應的SQL:
1)通過以下兩個個視圖來捕捉(局限:如果對應SQL被ageout就查不到了):
V$SQL_WORKAREA
V$SQL_PLAN_STATISTICS_ALL
SQL> SELECT SQL_ID,LAST_TEMPSEG_SIZE FROM V$SQL_WORKAREA WHERE SQL_ID='6r2k8sy8mtk25';
2)通過V$SQL相關幾個視圖來捕捉(局限:直接路徑讀寫還包含排序之外的其他操作):
SQL> SELECT SQL_ID,DIRECT_WRITES/DECODE(EXECUTIONS,0,1,EXECUTIONS) 2 FROM V$SQL WHERE SQL_ID='6r2k8sy8mtk25';