ORA-1652: unable to extend temp segment by 128 in tablespace xxx Troubleshootin

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORA-1652: unable to extend temp segment by 128 in tablespace xxx Troubleshootin相关的知识,希望对你有一定的参考价值。

当收到告警信息ORA-01652: unable to extend temp segment by 128 in tablespace xxxx 时,如何Troubleshooting ORA-1652这样的问题呢? 当然一般xxx是临时表空间,也有可能是用户表空间。

 

我们先来模拟一下这个情况,在两个会话窗口执行下面SQL语句,这个视图比较特殊(因为比较懒,不想去构造一个大量消耗临时段的SQL,便使用手头的一个案例脚本),它里面有一个DISTINCT操作会消耗TEMP表空间中大量的临时段

 

 

SQL> select count(*) from v_ies_go_information;

 

 

开启两个会话窗口执行上面这个SQL,此时这两个会话会耗大量临时段,那么你用下面SQL语句就能捕获到这个SQL,如下所示:

 

 

For 8.1.7 to 9.2

 

SELECT A.USERNAME, A.SID, A.SERIAL#, A.OSUSER, B.TABLESPACE, B.BLOCKS, C.SQL_TEXT

FROM V$SESSION A, V$SORT_USAGE B, V$SQLAREA C

WHERE A.SADDR = B.SESSION_ADDR

AND C.ADDRESS= A.SQL_ADDRESS

AND C.HASH_VALUE = A.SQL_HASH_VALUE

ORDER BY B.TABLESPACE, B.BLOCKS;

 

 

For 10.1 and above:

COL  USERNAME FOR A16;

COL  OSUSER FOR A16;

COL  TABLESPACE FOR A10;

COL  SQL_TEXT FOR A160;

SELECT A.USERNAME, A.SID, A.SERIAL#, A.OSUSER, B.TABLESPACE, B.BLOCKS, C.SQL_TEXT

FROM GV$SESSION A, GV$TEMPSEG_USAGE B, GV$SQLAREA C

WHERE A.SADDR = B.SESSION_ADDR

AND C.ADDRESS= A.SQL_ADDRESS

AND C.HASH_VALUE = A.SQL_HASH_VALUE

ORDER BY B.TABLESPACE, B.BLOCKS;

 

 

当然消耗临时表空间的BLOCKS是一直变化的,下面只是其中一次查询结果的截图

 

 

clip_image001

 

 

当然这个也可以通过下面SQL查询当前消耗TEMP临时段的SQL_ID以及具体大小信息。这些信息都是实时变化的。

 

 
 
SQLSELECT SQL_ID,SUM(BLOCKS) FROM GV$TEMPSEG_USAGE GROUP BY SQL_ID ORDER BY 2 DESC;
 
SQL_ID        SUM(BLOCKS)
------------- -----------
cw4d8h5fudg6b      456704
 
SQL> SELECT TABLESPACE_NAME,TOTAL_BLOCKS,USED_BLOCKS,FREE_BLOCKS FROM V$SORT_SEGMENT;
 
TABLESPACE_NAME                 TOTAL_BLOCKS USED_BLOCKS FREE_BLOCKS
------------------------------- ------------ ----------- -----------
TEMPSCM2                             1048320      506368      541952
 
SQL> SELECT TABLESPACE_NAME,TOTAL_BLOCKS,USED_BLOCKS,FREE_BLOCKS FROM V$SORT_SEGMENT;
 
TABLESPACE_NAME                 TOTAL_BLOCKS USED_BLOCKS FREE_BLOCKS
------------------------------- ------------ ----------- -----------
TEMPSCM2                             1048320     1030144       18176

 

clip_image002

 

 

在另外一个窗口,不时执行下面SQL语句观察临时表空间的消耗使用情况,也能看到临时表空间的消耗变化情况, 如下所示:

 

 

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=\'TEMPSCM2\'                                      

 

clip_image003

 

 

 

但是很多时候,当我们收到告警日志的告警邮件时,其实该SQL语句其实已经结束了。就像我这个测试会话中,如果已经收到ORA-1652 错误提示,其实会话已经结束,返回错误提示了。

 

 

clip_image004

 

Mon Aug 07 22:23:40 CST 2017

ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMPSCM2

Mon Aug 07 22:23:40 CST 2017

ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMPSCM2

 

此时你用上面SQL其实已经不能捕获到相关信息了,因为PMON已经释放、回收了这些会话占用的临时段,如下所示,测试环境已经查不到任何信息,如果是生产环境,那么有可能查到是不准确的信息(查到的是非引起问题的SQL)。上面只适合查询当前临时表空间的使用情况,而不适合用来追查已经出现的ORA-1652错误。

 

clip_image005

 

clip_image006

 

 

那么此时我们应该怎么办呢? 其实我们可以使用ASH报告来帮忙定位消耗了大量临时段的SQL语句,如果收到ORA-01652告警后,最好及时生成一个快照,然后根据告警日志里面ORA-01652出现的时间,生成ASH报表,例如,此次试验ORA-01652出错的时间为22:23:40,那么我们生成22:20 ~ 22:25这个时间段的ASH报告。当然这个时间适当调整,尽量缩小范围,可以精准定位问题SQL。

 

SQL> @?/rdbms/admin/ashrpt.sql

 

clip_image007

 

 

然后从ASH报告的TOP SQL里面找到对应的TOP SQL的SQL ID,然后使用awrsqrpt报告找到具体SQL的执行计划, 如下所示, 然后分析SQL是否耗用了大量的临时段,当然生产环境肯定会复杂很多,TOP SQL里面肯定有多个,我们需要仔细甄别。这个分析也是一个耗时费力的体力活,所以上述ASH报告的时间段非常关键。

 

 

clip_image008

 

 

如下所示,通过awrsqrpt找到对应SQL_ID的具体执行计划,发现HASH UNIQUE这个DISTINCT操作使用了接近3G的临时段排序。再加上一些其他的操作需要消耗临时段,所以两个会话的同时执行就引起了ORA-1652的错误。

 

 

clip_image009

(c)2006-2024 SYSTEM All Rights Reserved IT常识