Monitoring Open and Cached Cursors

转载 2018年04月17日 12:44:44

Open cursors
Open cursors take up space in the shared pool, in the library cache. To keep a renegade session from filling up the library cache, or clogging the CPU with millions of parse requests, we set the parameter OPEN_CURSORS.

OPEN_CURSORS sets the maximum number of cursors each session can have open, per session. For example, if OPEN_CURSORS is set to 1000, then each session can have up to 1000 cursors open at one time. If a single session has OPEN_CURSORS # of cursors open, it will get an ora-1000 error when it tries to open one more cursor.

The default is value for OPEN_CURSORS is 50, but Oracle recommends that you set this to at least 500 for most applications. Some applications may need more, eg. web applications that have dozens to hundreds of users sharing a pool of sessions. Tom Kyte recommends setting it around 1000.

Session cached cursors
There are two main initialization parameters that affect cursors, and many folks get them confused. One is OPEN_CURSORS, and the other is SESSION_CACHED_CURSORS.

SESSION_CACHED_CURSORS sets the number of cached closed cursors each session can have. You can set SESSION_CACHED_CURSORS to higher than OPEN_CURSORS, lower than OPEN_CURSORS, or anywhere in between. This parameter has no effect on ora-1000’s or on the number of cursors a session will have open. Conversely, OPEN_CURSORS has no effect on the number of cursors cached. There’s no relationship between the two parameters.

If SESSION_CACHED_CURSORS is not set, it defaults to 0 and no cursors will be cached for your session. (Your cursors will still be cached in the shared pool, but your session will have to find them there.) If it is set, then when a parse request is issued, Oracle checks the library cache to see whether more than 3 parse requests have been issued for that statement. If so, Oracle moves the session cursor associated with that statement into the session cursor cache. Subsequent parse requests for that statement by the same session are then filled from the session cursor cache, thus avoiding even a soft parse. (Technically, a parse can’t be completely avoided; a “softer” soft parse is done that’s faster and requires less CPU.)

In the session cursor cache, Oracle manages the cached cursors using a LRU list. Once more than SESSION_CACHED_CURSORS closed cursors are cached, Oracle starts dropping cached cursors off the LRU end of the list whenever it needs to make room to cache a new cursor.

Why cache cursors?
The obvious advantage to caching cursors by session is reduced parse times, which leads to faster overall execution times. This is especially so for applications like Oracle Forms applications, where switching from one form to another will close all the session cursors opened for the first form. Switching back then opens identical cursors. So caching cursors by session really cuts down on reparsing.

There’s another advantage, though. Since a session doesn’t have to go looking in the library cache for previously parsed SQL, caching cursors by session results in less use of the library cache and shared pool latches. These are often points of contention for busy OLTP systems. Cutting down on latch use cuts down on latch waits, providing not only an increase in speed but an increase in scalability.

Monitoring open cursors
I believe a lot of the confusion about open cursors vs. cached cursors comes from the names of the Oracle dynamic performance views used to monitor them. vopencursorshowscachedcursors,notcurrentlyopencursors,bysession.Ifyourewonderinghowmanycursorsasessionhasopen,dontlookinvopen_cursor. It shows the cursors in the session cursor cache for each session, not cursors that are actually open.

To monitor open cursors, query v$sesstat where name=’opened cursors current’. This will give the number of currently opened cursors, by session:

–total cursors open, by session
select a.value, s.username, s.sid, s.serial#
from vsesstata,vstatname b, v$session s
where a.statistic# = b.statistic# and s.sid=a.sid
and = ‘opened cursors current’;
If you’re running several N-tiered applications with multiple webservers, you may find it useful to monitor open cursors by username and machine:

–total cursors open, by username & machine
select sum(a.value) total_cur, avg(a.value) avg_cur, max(a.value) max_cur,
s.username, s.machine
from vsesstata,vstatname b, v$session s
where a.statistic# = b.statistic# and s.sid=a.sid
and = ‘opened cursors current’
group by s.username, s.machine
order by 1 desc;
The best advice for tuning OPEN_CURSORS is not to tune it. Set it high enough that you won’t have to worry about it. If your sessions are running close to the limit you’ve set for OPEN_CURSORS, raise it. Your goal in tuning this parameter is to set it high enough that you never get an ora-1000 during normal operations.

If you set OPEN_CURSORS to a high value, this doesn’t mean that every session will have that number of cursors open. Cursors are opened on an as-needed basis. And if one of your applications has a cursor leak, it will eventually show up even with OPEN_CURSORS set high.

To see if you’ve set OPEN_CURSORS high enough, monitor v$sesstat for the maximum opened cursors current. If your sessions are running close to the limit, up the value of OPEN_CURSORS.

SQL> select max(a.value) as highest_open_cur, p.value as max_open_cur
2> from vsesstata,vstatname b, v$parameter p
3> where a.statistic# = b.statistic#
4> and = ‘opened cursors current’
5> and ‘open_cursors’
6> group by p.value;


        1953         2500

After you’ve increased the value of OPEN_CURSORS, keep an eye on v$sesstat to see if opened cursors current keeps increasing for any of your sessions. If you have an application session whose opened cursors current always increases to catch up with OPEN_CURSORS, then you’ve likely got a cursor leak in your application code: your application is opening cursors and not closing them when it’s done.

There is nothing you, as a DBA, can do to fix a cursor leak. The application developers need to go through the code, find the cursors that are being left open, and close them. As a stopgap, the most you can do is raise OPEN_CURSORS very high and schedule times when all the application sessions will be closed and reopened (eg. by kicking the webserver).

How not to tell if you’re closing all your cursors
Frustratingly for developers, the session statistic ‘currently open cursors’ can include some cursors that the application has closed. When application code calls for a cursor to be closed, Oracle actually marks the cursor as “closeable”. The cursor may not actually be closed until Oracle needs the space for another cursor.

So it’s not possible to test to see if a complex application is closing all its cursors by starting a session, running a test, and then checking to see if currently open cursors has gone down to 1. Even if the application is closing all its cursors properly, currently open cursors may report that some “closeable” cursors are still open.

One way for application developers to tell if an application is closing all its cursors is to do a single test run, on a dedicated development box, while monitoring “opened cursors cumulative” in v$sesstat for the session that’s running the test. Then set OPEN_CURSORS to a value a little bit higher than the peak cursors open during your test run, start a new session, and run through multiple iterations of the same test run. If your application still has a cursor leak, you will see the value of OPEN_CURSORS going up, and you may hit an ORA-1000 after a reasonable number of iterations. (Don’t set OPEN_CURSORS too low or it may be used up by recursive SQL; if your single test run opens very few cursors, consider making your test run longer rather than setting OPEN_CURSORS unreasonably low.)

Monitoring the session cursor cache
v$sesstat also provides a statistic to monitor the number of cursors each session has in its session cursor cache.

–session cached cursors, by session
select a.value, s.username, s.sid, s.serial#
from vsesstata,vstatname b, vsession s  where a.statistic# = b.statistic#  and s.sid=a.sid  and = ‘session cursor cache count’ ;  You can also see directly what is in the session cursor cache by querying vopen_cursor. v$open_cursor lists session cached cursors by SID, and includes the first few characters of the statement and the sql_id, so you can actually tell what the cursors are for.

select c.user_name, c.sid, sql.sql_text
from vopencursorc,vsql sql
where c.sql_id=sql.sql_id – for 9i and earlier use: c.address=sql.address
and c.sid=&sid
If you choose to use SESSION_CACHED_CURSORS to help out an application that is continually closing and reopening cursors, you can monitor its effectiveness via two more statistics in v$sesstat. The statistic “session cursor cache hits” reflects the number of times that a statement the session sent for parsing was found in the session cursor cache, meaning it didn’t have to be reparsed and your session didn’t have to search through the library cache for it. You can compare this to the statistic “parse count (total)”; subtract “session cursor cache hits” from “parse count (total)” to see the number of parses that actually occurred.

SQL> select cach.value cache_hits, prs.value all_parses,
2> prs.value-cach.value sess_cur_cache_not_used
3> from vsesstatcach,vsesstat prs, vstatnamenm1,vstatname nm2
4> where cach.statistic# = nm1.statistic#
5> and = ‘session cursor cache hits’
6> and prs.statistic#=nm2.statistic#
7> and ‘parse count (total)’
8> and cach.sid= &sid and prs.sid= cach.sid ;

Enter value for sid: 947
old 8: and cach.sid= &sid and prs.sid= cach.sid
new 8: and cach.sid= 947 and prs.sid= cach.sid


   106        210                     104

Monitor this in concurrence with the session cursor cache count.

–session cached cursors, for a given SID, compared to max
select a.value curr_cached, p.value max_cached, s.username, s.sid, s.serial#
from vsesstata,vstatname b, vsessions,vparameter2 p
where a.statistic# = b.statistic# and s.sid=a.sid and a.sid=&sid
and = ‘session cursor cache count’ ;
If the session cursor cache count is maxed out, session_cursor_cache_hits is low compared to all parses, and you suspect that the application is re-submitting the same queries for parsing repeatedly, then increasing SESSION_CURSOR_CACHE_COUNT may help with latch contention and give a slight boost to performance. Note that if your application is not resubmitting the same queries for parsing repeatedly, then session_cursor_cache_hits will be low and the session cursor cache count may be maxed out, but caching cursors by session won’t help at all. For example, if your application is using a lot of unsharable SQL, raising this parameter won’t get you anything.

ORACLE异常——ORA-01000: maximum open cursors exceeded

Exception : java.sql.SQLException: ORA-01000: maximum open cursors exceeded 第一种情况:未释放游标造成。 很多朋友在Java...
  • uusad
  • uusad
  • 2013-08-01 11:01:21
  • 1975


处理超出打开游标的最大数异常(ORA-01000: maximum open cursors exceeded)   在执行如下代码时,经常会出现ora-01000: maximum open...
  • paul342
  • paul342
  • 2014-08-07 14:29:55
  • 1817

Errorstack诊断ORA-01000: maximum open cursors exceeded

出现ORA-01000: maximum open cursors exceeded,就要检查open_cursors的设置,如果设置太小就要适当增大。但如果已经很大了,如超过1000了,还是报问题,...
  • guogang83
  • guogang83
  • 2017-04-14 11:27:41
  • 1145

oracle ORA-01000: maximum open cursors exceeded问题的解决方法

项目在运行过程中,后台报错:                      Java代码   ORA-01000: maximum open cursors exceeded   ...
  • iadink
  • iadink
  • 2015-06-29 11:01:29
  • 5970

"Current Open Cursors Count" 位于 1333警告

"Current Open Cursors Count" 位于 1333
  • sxj1069425501
  • sxj1069425501
  • 2014-09-26 10:43:35
  • 1468

ORA-01000: maximum open cursors exceeded, 引发的JDBC, DBPool的思考

1.首先我们来看oracle为什么会产生这个错误,默认的数据库最大的cursors是多少,当前使用又是多少. 1.1 Oracle不同数据库版本能打开的最大的的游标数和缓存的游标数略有不同,下面是w...
  • lengfei9928
  • lengfei9928
  • 2012-12-04 23:38:16
  • 3411


  • cn_chenfeng
  • cn_chenfeng
  • 2007-09-17 14:48:00
  • 8019

关于ORA-01000: maximum open cursors exceeded 在Websphere里

网上有很多,这边备忘一下。ORA-01000 这个参数决定一个SESSION的最大打开CURSOR的个数.可能是异常中断而没有CLOSE,或程序写嘚有问题,或者确实有这么多的CUSOR同时在应用. ...
  • Petergepeter
  • Petergepeter
  • 2008-04-10 15:06:00
  • 1417

java.sql.SQLException: ORA-01000: maximum open cursors exceeded

 我使用Oracle数据库的时候,碰到有ORA-01000: maximum open cursors exceeded.的错误。   [INFO ] [2009-03-04 05:25:06] -=...
  • clz1314521
  • clz1314521
  • 2009-03-04 10:21:00
  • 4239

循环执行sql语句时报 ORA-01000 maximum open cursors exceeded 超出打开游标的最大数的原因和解决方案

以下摘自百度: 1.检查数据库中的 OPEN_CURSORS 参数值。       Oracle 使用 init.ora 中的初始化参数 OPEN_CURSORS 指定一个会话一次最多可以拥有的游标数...
  • qq_38122518
  • qq_38122518
  • 2017-09-13 11:10:52
  • 646
您举报文章:Monitoring Open and Cached Cursors