ITPub博客

首页 > 数据库 > Oracle > 遭遇Cursor:pin s wait x and Ora-04031

遭遇Cursor:pin s wait x and Ora-04031

原创 Oracle 作者:zhzhypg 时间:2014-09-16 13:39:17 0 删除 编辑

从昨天晚上开始某核心库过十几分钟就会报出Cursor:pin s wait x的告警短信,而且很频繁,第二天到公司查了下原因:

首先收集了下相应时间ASH报告和AWR报告,显示的信息如下:

[html] view plaincopy
  1. Top 5 Timed Events   
  2. Event                  Waits Time(s)  Avg Wait(ms) %    Total Call Time    Wait Class   
  3. cursor: pin S wait on X     1,091,         611 10,688 10      45.1           Concurrency   
  4. row cache lock           95,543         6,924 72           29.2           Concurrency   
  5. 收集ASH信息,间隔为15分钟,看到如下信息:  
  6. Event Event               Class       % Activity Avg    Active Sessions   
  7. cursor: pin S wait on X     Concurrency      55.94          85.03   
  8. row cache lock           Concurrency      34.39          52.28  
  9. library cache load lock     Concurrency      2.73           4.15  

可以看到Active Sessions的数量相当高,在当时堵塞的session达到85。

继续查看:

[html] view plaincopy
  1. select sample_id,session_id,  
  2.        to_char(SAMPLE_TIME,'YY-MM-DD:HH:MI:SS') samp_time,  
  3.        sql_id,  
  4.        session_state,  
  5.        event,  
  6.        p1,  
  7.        p1text,  
  8.        p2,  
  9.        p2text,  
  10.        p3,  
  11.        p3text,  
  12.        wait_time,  
  13.        time_waited  
  14. from v$active_session_history  --DBA_HIST_ACTIVE_SESS_HISTORY  
  15.   where to_char(SAMPLE_TIME,'YY-MM-DD:HH:MI:SS') between  
  16.  '12-05-16:07:00:00' and '12-05-16:08:00:00' and event like'cursor%' and p1=2057858921  
  17.   order by sample_id desc;  


查看blocking sid:

[html] view plaincopy
  1. SELECT decode(trunc(24386824306688/4294967296),  
  2.            0,trunc(24386824306688/65536),  
  3.          trunc(24386824306688/4294967296)) SID_HOLDING_MUTEX  
  4.  FROM dual;  
  5. SID_HOLDING_MUTEX  
  6. --------------------------------  
  7. 5678  

查找阻塞此session的sid为:5678,那么看看session 5678究竟在做些什么。

[html] view plaincopy
  1. select sample_id,session_id,     
  2.        sql_id,  
  3.        session_state,  
  4.        event,  
  5.        p1,         
  6.        p2,  
  7.        p3,  
  8.        wait_time,  
  9.        time_waited  
  10. from DBA_HIST_ACTIVE_SESS_HISTORY  
  11.   where to_char(SAMPLE_TIME,'YY-MM-DD:HH:MI:SS') between  
  12.  '12-05-16:07:00:00' and '12-05-16:08:00:00'  and session_id=5678  
  13.   order by sample_id desc;  
  14. SESSION_ID  SQL_ID       STATE       EVENT        P1    P2   P3    WAIT_TIME  TIME_WAITED  
  15. ---------- ------------- ------------- --------------- ----- ----- ----  ---------- ----  
  16.     5678   g3176qdxahvv9 WAITING       row cache lock   8     0    3      0          0  
[html] view plaincopy
  1. 此session也在等待,只不过等待的事件是:row cache lock。  
  2. select cache#,parameter,type,count,gets,getmisses from v$rowcache where cache#=8;  
  3.    
  4.   CACHE# PARAMETER             TYPE           COUNT    GETS     GETMISSES  
  5. -------- -------------------- ----------- ---------- ---------- ----------  
  6.      8   dc_objects            PARENT          1410  -76918095    1851821  
  7.      8   dc_object_grants      SUBORDINATE     91     840478      47918  
  8. Oracle文档对dc_objects的解释:DC_OBJECTS   
  9. Look for any object compilation activity which might require an exclusive lock and thus block online activity.   

现在看来是大量的解析导致的,难道是有什么作业在定时的做某种DDL操作,导致相关对象上的游标失效,于是,抓了个session,查看相关sql的对象,发现并没有做ddl操作。那为什么会间隔的导致如此多的硬解析呢。

此时,当我执行此SQL:select s.sid, s.username,s.sql_id,s.module,s.osuser,s.event, s.blocking_session,

s.seconds_in_wait,s.wait_time,w.p1,w.p2,w.p3

from v$session s,v$session_wait w,v$sql q

where s.sid=w.sid

and s.statein ('WAITING')

and s.sql_id=q.sql_id

and s.wait_class !='Idle'; 

数据库抛出了

ORA-04031: unable to allocate 370048 bytes of sharedmemory ("shared pool","unknown object",""sgaheap(4,0),"hng: All sessions data for API.")

ORA-0431,这个很经典的错误,导致此错误的原因也有很多,我们就不多说,看看我的错误的参数部分,sga heap(4,0),说明在第四个subpool里找不到370048bytes,那继续来看看数据库的共享池配置及使用情况:

[html] view plaincopy
  1. select  a.ksppinm  "Parameter",  
  2.         b.ksppstvl "Session Value",  
  3.         c.ksppstvl "Instance Value"  
  4. from x$ksppi a, x$ksppcv b, x$ksppsv c  
  5. where a.indx = b.indx and a.indx = c.indx  
  6. and a.ksppinm in('_kghdsidx_count','__shared_pool_size','_shared_pool_reserved_pct');  
  7. Parameter                     Session Value   Instance Value  
  8. ---------------------------- --------------- -----------------  
  9. _kghdsidx_count                7                 7    
  10. _shared_pool_size              6442450944        6442450944  
  11. _shared_pool_reserved_pct      5                 5  
  12. 系统有6G的共享池,7个subpool,另外我们的sga_target=0.  
  13. SQL> select  
  14.   2    kghlurcr,  
  15.   3    kghlutrn,  
  16.   4    kghlufsh,  
  17.   5    kghluops,  
  18.   6    kghlunfu,  
  19.   7    kghlunfs  
  20.   8  from  
  21.   9    sys.x$kghlu  
  22.  10  where  
  23.  11    inst_id = userenv('Instance')  
  24.  12  /  
  25.  RECURRENT  TRANSIENT   FLUSHED   PINS AND    ORA-4031  LAST ERROR  
  26.     CHUNKS     CHUNKS  CHUNKS   RELEASES      ERRORS       SIZE  
  27. ----------       ----------   ----------   ----------         ---------    ----------  
  28.        852        865    1367514  286598314       1280     370048  
  29.       1932      36615     597116  245240992        578     370024  
  30.       6663       7618    2208370   70999571       2037     370000  
  31.        907        960    1207376   64136373       1057     369976  
  32.        892       1141    1749793  138707112        701     369952  
  33.       1060       1297    1795660   52162243       1598     369928  
  34.       1593       2149    1295995  176694298       1386     369904  
  35.   
  36. 7 rows selected.  
  37. 可以看到last error size为370048,正好和我们的报错吻合,那么,再来看看各个Subpool的空间使用情况:  


再来看看reserved shared pool信息:

[html] view plaincopy
  1. SQL> select used_space, requests, request_misses, last_miss_size  
  2.   2  from v$shared_pool_reserved;  
  3. REM Look at the breakdown of chunks for more detail on fragmentation.  
  4.                                           Reserved  
  5.         Reserved            Total             Area          Size of  
  6.             Used         Requests           Misses        Last Miss  
  7. ---------------- ---------------- ---------------- ----------------  
  8.      232,613,024          623,742            9,324          370,048  
  9. select free_space,avg_free_size,used_space,avg_used_size,request_failures,last_failure_size  
  10. from v$shared_pool_reserved;  
  11. FREE_SPACE AVG_FREE_SIZE USED_SPACE AVG_USED_SIZE REQUEST_FAILURES LAST_FAILURE_SIZE  
  12. ---------- ------------- ---------- ------------- ---------------- -----------------  
  13.   89753440    56734.1593  232613024     147037.31             9713            370048  

参数:

_shared_pool_reserved_min_alloc     4400                      4400

可以看到request_failures>0并且last_failure_size > _shared_pool_reserved_min_alloc,name ORA-04031错误就可能是因为共享池保留空间缺少连续空间所致。要解决这个问题,可以考虑加大_shared_pool_reserved_min_allock来降低缓冲区共享池保留空间的对象数目,并增大shared_pool_reserved_size来加大共享池保留空间的可用内存。当抛出了ORA-04031,当抛出此错误的同时,此核心库的Cursor:pin s wait x再次出现,并且大量导致session堵塞,经过查看相关的监控作业,发现有个作业会定期执行一条sql(select count(*) from gv$session;).但是,为什么只有在查询v$session的时候才会引发呢?而且,这里只是一个查询信息,为什么会出现wait x?

从一开始这个问题就走入了误区,大量session的cursor:pin s wait x其实只是表象,并不是真正的问题原因。那么,有这么一种可能: Oracle会了帮助诊断4031错误,出现这个错误的时候可能会做一次SGA的dump,这个过程可能会长时间或频繁地持有一些latch,这样会导致SQL解析出现问题。但是,我发现4031生成的trace文件很小,只有0.2M,也不好确定。于是尝试修改参数,在测试一下:

Alter system set “_4031_dump_bitvec”=o scope=memory;

再次执行v$session的相关查询,查看结果,还是有大量的cursor:Pin s wait x,row cache lock.正如文章开头的信息,导致cursor:pins wait x的事件是row cache lock,那具体的是dc_objects,dc_objects_grant,所以猜测查询v$session的时候,有row cache一直没有成功装入,引起rowcache lock,影响了其他SQL的解析,但是因为系统是核心库,我尝试dump systemstat,结果CPU迅速飙升到80%,我也只好终止。所以,这个问题最后还是修改session_cached_cursor为200,重启数据库。

转载地址:http://blog.csdn.net/coast_lichao/article/details/7586496

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28786649/viewspace-1270738/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 巧妙使用ASH信息
请登录后发表评论 登录
全部评论

注册时间:2014-09-01

  • 博文量
    62
  • 访问量
    161364