Skip to Main Content
  • Questions
  • Exactly what triggers 'maximum open cursors exceeded' error ?

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Simon.

Asked: March 06, 2002 - 11:15 am UTC

Last updated: July 27, 2007 - 3:05 pm UTC

Version: 7.3.4

Viewed 10K+ times! This question is

You Asked

Tom

My client has been getting the 'maximum open cursors exceeded' error message upto three times a day on their production system. The front end is a Progress GUI linked to a 7.3 database. Upon further investigation I noticed that

1) OPEN_CURSORS was set to 512

2) The v$sqlarea view was reporting many thousands of literals within SQL commands. All of these literals originated from our PL/SQL packages.

3) The Progress GUI was behaving in that it generated SQL on the server that used bind variables in all cases.

To solve the problem I did the following :-

1) Increased OPEN_CURORS to 1024

2) Replaced all literal SQL statements with statements using bind variables.

This has solved the problem, we no longer have to reboot the server.

However I am unsure which of the above actions solved the problem, is the problem still lurking because the number of OPEN_CURSORS has doubled, or has removing all literal SQL statements solved the problem?

I guess I'm basically trying to understand what the "point of no return" is for the "maximum open cursors exceeded" error message is - what limit is reached to trigger it off.

Regards
Simon.



and Tom said...

Well, getting rid of the literals is definitely a very good, positive thing indeed. Its the best thing you can do for your database!

In PLSQL, it will attempt to cache cursors in the hopes that you will reuse again and again. In 7.3 and before the way this was done is different from later releases and at times could lead to a max open cursors even when you've been careful. The init.ora parameter (since obsoleted)

close_cached_open_cursors

would help mitigate this.

My guess is -- setting open_cursors to 1024 fixed it. Since you must have been using DBMS_SQL to generate the sql with literals and we won't cache those (maybe you inadvertantly fixed a cursor leak as well? by adding a dbms_sql.close_cursor somewhere?) fixing the bind problem would not have decreased the cursor usage.

You can query v$open_cursor by SID to see what queries are remaining opened (ignore any static SQL from PLSQL routines -- its cached on purpose).

Rating

  (7 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

what kind of cursors shown in v_$Open-Cursor view.?

CSR, April 03, 2003 - 4:48 am UTC

Tom,
"(ignore any static SQL from PLSQL routines -- its cached on purpose)."
What is meant by static SQL statements in your followup above.

My client is complaining that, they are getting "maximum cursors exceeded" error.

At what scenarios, all the opened cursors gets closed.Will this closing of opened cursors depends on time too.

My Database is Oracle: 8.1.7
Apllication Server: Tomcat.

Am sure at all places in java, they are closing resultsetsa and connections properly.
At SP level we are not closing refcursors.Data extraction and closing of ResultsSet is doing at Java level.

When I tried with the following example, I did not get the complete picture about the 'Opened Cursors" issue.

Please look at the examples.

conn SWIPTEST2/SWIPTEST2

create or replace procedure sptest3 is
n1 NUMBER;
BEGIN
select count(*) into n1 from tab;
insert into test_tab values(32);
commit;
end ;
/

SQL>exec sptest3;

SQL> conn sys/sysdba

SQL>select sql_text from v_$open_cursor where user_name = 'SWIPTEST2' ;

SQL_TEXT
------------------------------------------------------------
 select /*+ CHOOSE */ a1.constraint_name,   c1.column_name,
INSERT INTO TEST_TAB VALUES ( 32  )
Select /*+ CHOOSE */ cols.column_name as Name, nullable,  da
Select /*+ CHOOSE */ object_name, object_type, status from
SELECT COUNT(*)   FROM TAB
BEGIN sptest3; END;
SELECT rowid, "SWPTEST2"."T_WIPS_INVOICE_CHARGE_CODE".* FRO

SQL>7 rows selected.

when I query the v_$open_cursor, it is giving the above results.

v_$open_cursor view will give all kind of cursor list(implcit, explicit, refcursors).?

"INSERT INTO TEST_TAB VALUES ( 32  )" is this a static sql.?
In the v_$Opnen_Cursor count the above statement also counted.?
We set our open_cursors to 200. Is above statement also consuming a cursor from the above 200 value.

Please give me your suggestion to get rid of this problem.

thanks in advance.

 

Tom Kyte
April 03, 2003 - 8:02 am UTC

begin
select count(*) into l_cnt from dual; <<<== static sql
execute immediate
'select count(*) from dual' into l_cnt; <<<=== dynamic sql
end;
/


If, I had but $1 for everytime I've heard:

...
Am sure at all places in java, they are closing resultsetsa and connections
properly.....


ref cursors are closed by the client that fetched from them, so it is good that plsql doesn't close them if java is doing the fetching...



suggestion: you don't say what open-cursors is set to. perhaps you do close everything but -- it is actually set to small for the number of cursors you use concurrently.

suggestion: search for

v$open_cursor java

on this site. add some code to the application to monitor its actual cursor usage -- find out where you are leaking cursors in the application (if you are).






What is the ideal value for the Open_Cursor parameter.

CSR, April 03, 2003 - 10:56 am UTC

Tom,
Thank you very much for your reply.

please let me know, what will be the recomended value for the open_cursor parameter to avoid this kind of errors for the following environment.

Environment details:
Database:Oracle 8.1.7 on Solaris, Sun sparc.
App Server: Tomcat.
Drivers: Oracle 8i Thin.
In the production, 75 users will be accessing the application concurrently via browser.

Currently client's production server is set with open_cursor = 200.
And he recomended us the cursor limit should not exceed 120 at any given point in time. Since kernel process will be using some cursors. So he recomended the above figure.

In considering the above scenarios, what could be the suggested /ideal value for the open_cursor.

Will it degrades performance or leads to any db server crashes, If I run under high open_cursor value. ?

Thanks in advance.







Tom Kyte
April 03, 2003 - 11:37 am UTC

somewhere between 0 and 10,000


open cursor will allocate an array in the session space (smallish).

then, as cursors are needed, we'll grab 64 at a time (so the first cursor really sets up for 64 of them, the 65th sets up for 128 and so on).

200 would be fine for most, i regularly run with 500/1000



Getting open cursors exceed with statements being closed?

Doug, July 09, 2003 - 10:36 am UTC

Tom - during a small stress test where connection pooling makes use of about 10 connections to the database, the running scripts got a maximum open cursors exceeded error. I bumped it to 1000 and watched it. There appeared to be a small "leak" where the cursors just went up and up and up. When I did a select sql_text, count(1) from v$open_cursor where sid = 11 group by sql_text (the maxed sid).. I saw that one statement dwarfed the others by about 600:1. I had the developers look to see if they are closing that prepared statement and they said that yes.. they were. Then they hand the connection back to the pool. Any idea what else could be going on? Would the lack of an explicit commit keep the cursors from being handed back? Thanks.

Tom Kyte
July 09, 2003 - 11:38 am UTC

they have a cursor leak, they are NOT closing the cursor. perhaps they have an try catch block that flies over the close.

open cursors

Reader, October 13, 2003 - 8:59 pm UTC

Tom, If I issue a select * from emp from my session, I use a cursor slot in the pga that will cache my statement, hash value for the statement and also a pointer to shared pool to point to the execution plan for that statement. Is it correct? Then, If I issue the same statement in my session, will it use the same cursor slot in the pga or a different slot? Thanks.

Tom Kyte
October 14, 2003 - 6:27 am UTC

fundementally correct -- when you open a cursor, we'll allocate a slot for it and it'll be in your CGA which may or may not be in the PGA (dedicated vs shared server configuration).

If you close that cursor -- and the slot is free, it may use the same slot again but that would be by accident


there is also session cached cursors -- that simply changes the semantics of "close" to "close but remember" -- leading to a softer soft parse next time around (makes that reuse you talk of more real)

Question on Open Cursors

Karthik, July 25, 2007 - 10:57 am UTC

Hello Tom,
Of late we are getting ORA-01000: maximum open cursors exceeded. This error is encountered in the remote database only. The OPEN_CURSORS value is set to as high as 1300 in the remote database and to 1500 in the local database.

Partly we suspect (but not sure) it's because front-end application (3rd party tool) is not closing the database link after the transaction completes or may be because we are dynamically generating queries in the back-end procedures in both local and remote dbs.

The V$OPEN_CURSOR view shows sql queries which are not part of any explicit cursor (like Declare CURSOR or FOR C1 as SELECT ...).

And we are sure we are closing all the cursor which are opened in the procedures.

Can a dynamically generated query be a problem here? I was going through your earlier response to one of the question.

Thanks

Tom Kyte
July 26, 2007 - 5:29 pm UTC

it won't matter if they do not close the database link, they need to close their cursors - they are leaking cursors, they have a bug. Increasing the value will only push the wall back - you'll hit it eventually.

what does v$open-cursor show here, are they queries generated by this 3rd party tool

Thanks

Karthik, July 27, 2007 - 5:37 am UTC

Hello Tom,
Some of the queries shown in V$OPEN_CURSOR view are generated by 3rd party tool and rest of them are generated by back-end procedures. Those which are part of back-end procedures are simple queries (like SELECT or INSERT or UPDATE statement and none of the queries are part of any explict cursor)

Why are these queries are still in V$OPEN_CURSOR whose corresponding session are in INACTIVE status? Infact these queries should not be present as the transaction is already completed.

Why do I see some many session in INACTIVE when these session have completed the transaction?

Once in a forthnight we are hitting the ORA-01000: maximum open cursors exceeded error.



Thanks
Tom Kyte
July 27, 2007 - 3:05 pm UTC

plsql caches cursors - but they are closable (transparently, automatically, they do not count "against" you).


inactive just means not currently active. You can be in a transaction, and you can be inactive. just go into sqlplus, update a row, and walk away, you are in a transaction, you are inactive.


once a fortnight I would say that you have an application that is needing more cursors opened simultaneously than you have allowed for. Either that application is leaking cursors and has a bug (don't count the plsql managed SQL, that is all very closable and will be closed). OR, your application really needs that many.

Forgot to mention ...

Karthik, July 27, 2007 - 6:27 am UTC

Hello Tom,
One more thing which I forgot to mention was, there are dynamically created sql queries as well. All these are created in back-end procedures.

Thanks
Tom Kyte
July 27, 2007 - 3:05 pm UTC

no idea what a "back end procedure" is.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library