The query always return 1 open cursor
A reader, June 25, 2002 - 2:58 pm UTC
Hi Tom,
Two questions:
1. I run you query listed here
select a.value, b.name
from v$mystat a, v$statname b
where a.statistic# = b.statistic#
and a.statistic#= 3;
The result is the same in any databases I have (9 in total) at any time.
VALUE NAME
--------- ------------------------
1 opened cursors current
I think this is not the case.
2. When I run
select count(*) from v$open_cursor;
I get 1996 as the result. However, my parameter file setting is:
Open cursors = 1000.
How can that be? You have explained above that v$open_cursor is not the currently open cursors. Should the number returned from v$open_cursor smaller than the setting in parameter file, 1000 in my case, even though the number is not the actually openning cursors? The database has no problem.
Thank you very much.
June 25, 2002 - 4:33 pm UTC
1) and ... why do you believe that? care to explain why you think it is wrong (i don't think it is wrong)
SQL*Plus: Release 8.1.7.0.0 - Production on Tue Jun 25 15:35:20 2002
(c) Copyright 2000 Oracle Corporation. All rights reserved.
Connected to:
Oracle8i Enterprise Edition Release 8.1.7.3.0 - Production
With the Partitioning option
JServer Release 8.1.7.3.0 - Production
ops$tkyte@ORA817DEV.US.ORACLE.COM> select a.value, b.name
2 from v$mystat a, v$statname b
3 where a.statistic# = b.statistic#
4 and a.statistic#= 3;
VALUE NAME
---------- ------------------------------
1 opened cursors current
2) select sid, count(*) from v$open_cursor group by sid
open_cursor is by session. You are looking across sessions.
Clearing up confusion regarding Open Cursors
Mary Ruiz, December 10, 2002 - 10:48 am UTC
I looked all over for this information. I am trying to set up alerting before the ORA-1000 error is posted in the alert log. I am now changing my code to count the maximum number of open cursors for a session, and check it against a threshold value, instead of counting all open cursors for a session
Just to clarify
Robert, March 12, 2003 - 4:58 am UTC
Tom
After testing would I be right in saying then that the query:
SELECT a.VALUE, b.NAME
FROM v$mystat a, v$statname b
WHERE a.statistic# = b.statistic#
AND a.statistic#= 3
Returns only those open cursors for your current session? If this is so, how do you get all the open cursors for the database? Would you use v$open_cursors then?
Thanks
R.
March 12, 2003 - 7:59 am UTC
you would use v$sesstat.
I did a bad thing here too -- i should have coded using the NAME not the number:
ops$tkyte@ORA9I> select a.value, b.name
2 from v$mystat a, v$statname b
3 where a.statistic# = b.statistic#
4 and b.name = 'opened cursors current'
5 /
VALUE NAME
---------- ------------------------------
1 opened cursors current
ops$tkyte@ORA9I> select sum(a.value), b.name
2 from v$sesstat a, v$statname b
3 where a.statistic# = b.statistic#
4 and b.name = 'opened cursors current'
5 group by b.name
6 /
SUM(A.VALUE) NAME
------------ ------------------------------
94 opened cursors current
Oops i did it again...
Robert, March 12, 2003 - 5:29 am UTC
Sorry about that Tom,
a little more investigation leads me to believe that if you have a 1000 set as max number of open cursors you are allowed a 1000 per session, for all sessions. Is this correct.
Also I replaced v$mystat with v$sesstat to get all the session open cursors. Is this the correct view? If so is it misleading that it gives me the same number of open cursors as v$open_cursors does?
Cheers
R.
March 12, 2003 - 8:02 am UTC
You are allowed 1000 PER SESSION. so there could be 10,000 of them if you have 10 sessions.
if you are in a single user database -- v$sesstat and v$mystat will return basically the same thing for opened cursors current unless smon or some other background process is awake and doing something.
v$open_cusor has a higher value than your last query?
Doug, April 08, 2003 - 7:05 pm UTC
Hi Tom -
I tried this -
SQL> select sum(a.value), b.name
from v$sesstat a, v$statname b
where a.statistic# = b.statistic#
and b.name = 'opened cursors current'
group by b.name
2 3 4 5 6 /
SUM(A.VALUE) NAME
------------ ------------------------------------------------------------
515 opened cursors current
SQL> select count(1) from v$open_Cursor;
COUNT(1)
----------
377
SQL>
How can v$open_cursor contain less than your query?
April 08, 2003 - 7:29 pm UTC
v$open_cursor = your session.
v$sesstat (summed over) = sum of all sessions.
? v$open_cursor has a sid column
Doug, April 08, 2003 - 11:48 pm UTC
How can v$open_cursor be only my own cursors? It has a sid column.
April 09, 2003 - 8:11 am UTC
never mind, restart....(geez, i even said myself:
...
2) select sid, count(*) from v$open_cursor group by sid
open_cursor is by session. You are looking across sessions.
......
above) thats what I get for firing off an answer too fast. thanks for checking back.
but anyway, on a busy system -- one would expect there to be differences -- cursors come and cursors go. All you need is one session to exit between calls and bamm -- there go hundreds of cursors potentially.
Now, since V$ views are *not* read consistent -- they are 100% point in time pictures -- at the point in time you look at them -- you'll see this.
http://docs.oracle.com/docs/cd/B10501_01/server.920/a96536/ch3.htm#1086021
Even if you try a single query like so:
ops$tkyte@ORA9I> select sum(a.value), b.name
2 from v$sesstat a, v$statname b
3 where a.statistic# = b.statistic# and b.name = 'opened cursors current'
4 group by b.name
5 union all
6 select count(*), 'v$open_cursor' from v$open_cursor
7 /
SUM(A.VALUE) NAME
------------ ------------------------------
100 opened cursors current
129 v$open_cursor
ops$tkyte@ORA9I> /
SUM(A.VALUE) NAME
------------ ------------------------------
85 opened cursors current
129 v$open_cursor
ops$tkyte@ORA9I> /
SUM(A.VALUE) NAME
------------ ------------------------------
110 opened cursors current
175 v$open_cursor
ops$tkyte@ORA9I> /
SUM(A.VALUE) NAME
------------ ------------------------------
91 opened cursors current
97 v$open_cursor
ops$tkyte@ORA9I> /
SUM(A.VALUE) NAME
------------ ------------------------------
144 opened cursors current
137 v$open_cursor
ops$tkyte@ORA9I> /
SUM(A.VALUE) NAME
------------ ------------------------------
146 opened cursors current
95 v$open_cursor
v$sesstat is queried at a different point in time then v$open_cursor. Both answers are *right* at their respective points in time. If you do this on a "single user" system -- you'll see much more predicable responses.
Great Tom,Explained in an easily perceptible manner, > 5*
Saminathan Seerangan, April 25, 2003 - 1:19 am UTC
Monitoring
Harri, October 22, 2003 - 5:22 pm UTC
Is there a way to monitor open_cursors usage? I want to get noted if open_cursors parameter is too small.
My monitoring "sofware" uses this query:
select value-(select max(value) from v$sesstat where STATISTIC#='3') from v$parameter where name='open_cursors';
...but sometimes, some databases it gives negative value, so my logic must be wrong or there is a bug or something.
October 22, 2003 - 6:29 pm UTC
well, statistic# is a number (why are you comparing to a string????)
are you sure that 3 is open cursors in your database (i should not have used 3 myself)
...
Harri, October 23, 2003 - 6:44 am UTC
SQL> select STATISTIC#, name from v$sysstat where NAME='opened cursors current';
STATISTIC# NAME
---------- ----------------------------------------------------------------
3 opened cursors current
SQL>
SQL> select value-(select max(value) from v$sesstat where STATISTIC#='3') from
v$parameter where name='open_cursors';
VALUE-(SELECTMAX(VALUE)FROMV$SESSTATWHERESTATISTIC#='3')
--------------------------------------------------------
2677
SQL> show parameter open_cursors
NAME TYPE VALUE
------------------------------------ ------- ------------------------------
open_cursors integer 3000
SQL> select value-(select max(value) from v$sesstat where STATISTIC#=3) from v$parameter where name='open_cursors';
VALUE-(SELECTMAX(VALUE)FROMV$SESSTATWHERESTATISTIC#=3)
------------------------------------------------------
2677
...but sometimes it gives negative values!?
October 23, 2003 - 12:48 pm UTC
so, select the max value as well -- see what it "is".
Open Cursors
Dan Clamage, October 23, 2003 - 1:41 pm UTC
Great! Now will this show me ref cursors as well as "regular" cursors? I don't think it does (after running a quick test). So I can find out whether my web app has a ref cursor leak (ref cursors being opened but never closed). We use connection pooling so a session may stay active for quite some time.
October 23, 2003 - 1:47 pm UTC
ref cursors ARE regular cursors.
yes, it'll show you.
ops$tkyte@ORA920LAP> select name, value
2 from v$mystat a, v$statname b
3 where a.statistic# = b.statistic#
4 and b.name = 'opened cursors current'
5 /
NAME VALUE
------------------------------ ----------
opened cursors current 1
ops$tkyte@ORA920LAP>
ops$tkyte@ORA920LAP> variable x refcursor
ops$tkyte@ORA920LAP> variable y refcursor
ops$tkyte@ORA920LAP> variable z refcursor
ops$tkyte@ORA920LAP>
ops$tkyte@ORA920LAP> exec open :x for select * from dual;
PL/SQL procedure successfully completed.
ops$tkyte@ORA920LAP> /
NAME VALUE
------------------------------ ----------
opened cursors current 2
ops$tkyte@ORA920LAP> exec open :y for select * from dual;
PL/SQL procedure successfully completed.
ops$tkyte@ORA920LAP> /
NAME VALUE
------------------------------ ----------
opened cursors current 3
ops$tkyte@ORA920LAP> exec open :z for select * from dual;
PL/SQL procedure successfully completed.
ops$tkyte@ORA920LAP> /
NAME VALUE
------------------------------ ----------
opened cursors current 4
ref cursors strike again
Dan Clamage, October 23, 2003 - 2:43 pm UTC
I think I see what's going on here.
<pre>
declare
type typ_ref is ref cursor;
v_ref typ_ref;
v_sum number;
v_name varchar2(100);
begin
select name, value
into v_name, v_sum
from v$mystat a, v$statname b
where a.statistic# = b.statistic#
and b.name = 'opened cursors current';
dbms_output.put_line(v_name || ': ' || v_sum);
open v_ref for select 1 from dual;
open v_ref for select 'test' from dual;
open v_ref for select user from dual;
open v_ref for select sysdate from dual;
open v_ref for select * from dual;
select name, value
into v_name, v_sum
from v$mystat a, v$statname b
where a.statistic# = b.statistic#
and b.name = 'opened cursors current';
dbms_output.put_line(v_name || ': ' || v_sum);
end;
/
opened cursors current: 7
opened cursors current: 9
</pre>
My cursor space is being reused. I was expecting Oracle to store all the different queries in memory.
Thanks!
...
Harri, October 24, 2003 - 3:51 am UTC
SQL> select STATISTIC#, name from v$sysstat where NAME='opened cursors current';
STATISTIC# NAME
---------- ----------------------------------------------------------------
3 opened cursors current
SQL> select max(VALUE) from v$sesstat where STATISTIC#=3;
MAX(VALUE)
----------
381
SQL> show parameter open_cursors
NAME TYPE VALUE
------------------------------------ ------- ------------------------------
open_cursors integer 150
SQL> select value-(select max(value) from v$sesstat where STATISTIC#='3')
2 from v$parameter where name='open_cursors';
VALUE-(SELECTMAX(VALUE)FROMV$SESSTATWHERESTATISTIC#='3')
--------------------------------------------------------
-231
October 24, 2003 - 9:37 am UTC
any chance someone did an alter system?
ops$tkyte@ORA920> select STATISTIC#, name from v$sysstat where NAME='opened cursors current';
STATISTIC# NAME
---------- ------------------------------
3 opened cursors current
ops$tkyte@ORA920>
ops$tkyte@ORA920> select max(VALUE) from v$sesstat where STATISTIC#=3;
MAX(VALUE)
----------
10
ops$tkyte@ORA920>
ops$tkyte@ORA920> show parameter open_cursors
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 500
ops$tkyte@ORA920>
ops$tkyte@ORA920> select value-(select max(value) from v$sesstat where STATISTIC#='3')
2 from v$parameter where name='open_cursors';
VALUE-(SELECTMAX(VALUE)FROMV$SESSTATWHERESTATISTIC#='3')
--------------------------------------------------------
490
ops$tkyte@ORA920>
ops$tkyte@ORA920> alter system set open_cursors = 5;
System altered.
ops$tkyte@ORA920>
ops$tkyte@ORA920> show parameter open_cursors
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors integer 5
ops$tkyte@ORA920>
ops$tkyte@ORA920> select value-(select max(value) from v$sesstat where STATISTIC#='3')
2 from v$parameter where name='open_cursors';
VALUE-(SELECTMAX(VALUE)FROMV$SESSTATWHERESTATISTIC#='3')
--------------------------------------------------------
-5
ops$tkyte@ORA920>
open_cursors
Sikandar Hayat, April 01, 2004 - 12:27 am UTC
I have Oracle 9i R2 application and 9i R2 database server. The open_curosrs were default on db server. The application server stopped responding so it was suggested by the application developer that open_cursors should be increased. Now let me know,
1- Is there any calculations method for open_cursors?
2- If application is not using bind variables so is this the reason that we have to increase open_cursors?
3- If the open_cursors are increased then what will be the performance impact on the db server and the memory usage?
Thanks for your time.
April 01, 2004 - 10:01 am UTC
why would you increase open_cursors?
why wouldn't you figure out "what happened"?
Unless you are getting ora-1000 max open cursors exceeded, upping it won't fix anything.
1) you need to set it high enough to not get ora-1000, it is dependent on the applications needs
2) no, you have a bug in the code that the java developers MUST fix though.
3) if you are not hitting ora-1000, it will change nothing (since you are not using the cursors you currently have)
why an app server "not responding" would give a gut reaction of "up open cursors" is beyond me though..
Nice info.
Sikandar Hayat, April 01, 2004 - 10:37 am UTC
Ya you are right that it should be only increased when the error hits. I would like to know that what kind of bug do you think may be in the application,
2) no, you have a bug in the code that the java developers MUST fix though.
No use of baind variables may be one of the reasons?
April 01, 2004 - 10:53 am UTC
there are an infinite number of possible bugs.
not using bind variables in a transactional application is definitely a bug.
prat, July 21, 2004 - 6:54 pm UTC
Hi Tom,
I have the following PL/SQL block:
SQL> declare
2 procedure x is
3 cursor c is select ename from emp;
4 v_ename emp.ename%TYPE;
5 begin
6 open c;
7 fetch c into v_ename;
8 dbms_output.put_Line(v_ename);
9 -- Let's not bother to close c
10 end;
11 begin
12 for i in 1..5 loop
13 x;
14 end loop;
15* end;
SQL> /
SMITH
SMITH
SMITH
SMITH
SMITH
I would like to know, if it would hog the memory (especially if I increase the counter) ? It does not show these as open cursors though !
Can you please throw some light on this ..
Thanks
July 21, 2004 - 7:11 pm UTC
that is an infinite loop that fails only because dbms_output fails it.
the cursor is closed for you as it goes out of scope. only if its scope what "global" (defined in a package spec or body outside of a function) would it remain "in scope" and be a potential problem.
Open Cursors ?
prat, July 21, 2004 - 8:54 pm UTC
SQL> set serveroutput on size 1000000
SQL> variable myref refcursor
SQL> DECLARE
2 TYPE emp_cur_t is REF CURSOR return SCOTT.EMP%ROWTYPE;
3 v_cur emp_cur_t;
4 emp_rec scott.emp%rowtype;
5 procedure x is
6 begin
7 open v_cur for select * from scott.emp where rownum <= 10;
8 fetch v_cur into emp_rec;
9 DBMS_OUTPUT.PUT_LINE(emp_rec.ename);
10 :myref := v_cur;
11 end;
12 begin
13 for i in 1..5 loop
14 x;
15 end loop;
16 end;
17 /
SMITH
SMITH
SMITH
SMITH
SMITH
PL/SQL procedure successfully completed.
SQL> print myref
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO
----------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300
30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500
30
7566 JONES MANAGER 7839 02-APR-81 2975
20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400
30
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7788 SCOTT ANALYST 7566 19-APR-87 3000
20
7839 KING PRESIDENT 17-NOV-81 5000
10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0
30
9 rows selected.
SQL>
What does this prove to you ? Was the cursor closed after the RETURN happened ? :)) Even if the cursor variable was available at the SQL*Plus prompt, the cursor should have been closed (as per your theory). So, when you print the value of cursor variable, you should'nt get anything (infact you should get an error, because the handle of cursor that was set in the cursor variable, has been closed. Refer the code below, where we would get the error, if we close the cursor explicitly)
Now, let us close the cursor explicitly :
SQL> set serveroutput on size 1000000
SQL> variable myref refcursor
SQL> DECLARE
2 TYPE emp_cur_t is REF CURSOR return SCOTT.EMP%ROWTYPE;
3 v_cur emp_cur_t;
4 emp_rec scott.emp%rowtype;
5 procedure x is
6 begin
7 open v_cur for select * from scott.emp where rownum <= 10;
8 fetch v_cur into emp_rec;
9 DBMS_OUTPUT.PUT_LINE(emp_rec.ename);
10 :myref := v_cur;
11 close v_cur; -- CLOSED EXPLICITLY
12 end;
13 begin
14 for i in 1..5 loop
15 x;
16 end loop;
17 end;
18 /
SMITH
SMITH
SMITH
SMITH
SMITH
PL/SQL procedure successfully completed.
SQL> print myref
ERROR:
ORA-24338: statement handle not executed
SP2-0625: Error printing variable "myref"
SQL>
July 21, 2004 - 9:11 pm UTC
no theory -- the ref cursor is "global in nature" (it was not declared in the local scope of the plsql block) and sqlplus closed it after it exhausted it.
I don't know what you are trying to prove/show?
you compared a locally scoped cursor (example above with "cursor c") to a ref cursor that had a scope controlled by sqlplus itself?????
what you showed is totally expected and doesn't contradict anything I said?
cursor not closed
prat, July 22, 2004 - 4:50 am UTC
Hi Tom,
Sorry for not being explicit.
I was trying to mention that if we do a close within the procedure (where we open the cursor), the cursor actually is closed. But, If we don't put a close in the procedure, the cursor is not closed (even though the procedure has finished).
Cursor is actually defined and opened in the procedure, so when the procedure returns the control to the PL/SQL block, and then to SQL*Plus, you would expect the cursor to be closed. But that does'nt happen.
Also, if you could please let me know why do I get the other 9 records from the table, when I just do one fetch (5 times) ?
July 22, 2004 - 7:22 am UTC
that is a REF CURSOR only.
in your first example "C", a local cursor to that anonymous block is *closed*
in your second example, :myref, a cursor handle owned by sqlplus, is closed only when
a) you close it in plsql before giving it back to sqlplus
b) sqlplus hits "end of fetch" and closes it.
cursor is NOT defined in plsql in your second example:
SQL> variable myref refcursor
it was clearly defined in SQLPlus -- sqlplus owned that cursor. You would not expect the cursor to be closed -- else there would be NO WAY to return a result set from a stored procedure.
I don't know what you mean by that last paragraph at all??? You fetched a row in plsql -- sqlplus fetched the rest?
open cursors ... contd. ...
prat, July 22, 2004 - 4:56 am UTC
And ... in the second PL/SQL, you can see that if I do the print (cursor variable), I cannot print it. Which proves that the cursor is not opened. Whereas in case of first PL/SQL, it prints the other records from the cursor, even after the PL/SQL block has executed. I would assume, that since the PLSQL has finished, the cursor should not be open/available for print. I can be sure that it is showing records from the cursor, because it shows only the 10 records that I selected while defining the cursor.
I am just trying to understand what is happening here. Please excuse my inexperience :)
July 22, 2004 - 7:27 am UTC
it is not opened because YOU CLOSED IT!!!!
I'm really not understanding where you are going with this.
you assigned the cursor (a single thing) to a global variable :myref. If you left the cursor open, sqlplus gets it and prints it. If you close the cursor, sqlplus doesn't get it, cannot print it.
If you've ever programmed in C, this is alot like:
void x( FILE * * foo )
{
FILE * input;
input = fopen( ..... );
*foo = input;
both input and foo "point" to the same "result set" -- file. close foo -- input is closed. close input, foo is closed.
foo is a ref cursor, a pointer to a result set. if we leave procedure X, the caller can use foo to read/write the "result set". If we closed input before leaving x -- foo would not be usable.
Don't understand
reader, July 22, 2004 - 5:06 am UTC
I am a bit confused here. What has happend when we assign a local declared ref cursor to a global cursor i,e
:myref := v_cur;
If they both represent different cursor then surely closing the local cursor v_cur should not have any impact on the global one. Hence we should be able to print the values from the global cursor at the SQL prompt.
Have I got something wrong here ?
July 22, 2004 - 7:28 am UTC
a ref cursor is a pointer to a cursor. they point to the same thing. it did not "copy" the result set.
V$open_cursor and V$sesstat and v$statname give different results
Paru, July 27, 2004 - 12:58 pm UTC
Hi Tom,
Here is the query that I ran on my database as the developer complained about getting ORA-1000, but he is fixing his code and closing the cursors.
But, the results of the queries are so different, can you explain why...
select sum(a.value), b.name
from v$sesstat a, v$statname b
where a.statistic# = b.statistic# and b.name = 'opened cursors current'
group by b.name
union all
select count(*), 'v$open_cursor' from v$open_cursor
;
SUM(A.VALUE) NAME
------------ ----------------------------------------------- 5081 opened cursors current
53 v$open_cursor
OPEN_CURSOR is set at 700.
July 27, 2004 - 1:06 pm UTC
hit / a couple of times, does it stay the same?
look by session -- join sesstat to open_cursor to v$session and see which processes have the "big diffs", that might be telling.
A reader, August 17, 2004 - 9:33 pm UTC
Tom,
How can i know how much memory is used by each cursor.
Thanks.
August 18, 2004 - 7:44 am UTC
v$sql can show you the shared resource -- the "parsed query itself".
v$sql_cursor has the memory associated with an instance of a cursor (session viewable only)
Is this really true for Open Cursors
Bablu, June 24, 2005 - 10:22 am UTC
We have a typical situation here, wherein the application is throwing TOO MANY CURSORS. We know that we have to fix the application, but in the interim we would like to increase the cursors open to 2000. But, this is the feedback we got :
"Each open cursor consume 2 to 5 MB of memory, depend upon execution work. Setting 2000 cursor means we are reserving memory of 4000MB. You system may crash at some point. We can set the limit to 2000, provided the server can handle this much of memory."
I know this is not true, but how to really determine how much each cursors is taking space in memory.
June 24, 2005 - 6:27 pm UTC
each open cursor does not take that amount.
but i would not fix a leaking cursor problem with this -- you have a serious bug in your code, this just moves the wall back a couple of inches You haven't fixed anything.
(this is not a typial situation, this is a bug in the developed code)
ORA-01000 : maximum open cursors exceeded
swain, September 06, 2005 - 12:40 am UTC
Hi Tom,
Could you please explain why I see cursors in the V$OPEN_CURSOR view and in v$sesstat even though they have been explicitly closed in the code.
With each call to this function the number of open cursors increased and leads to ORA-01000 error.
Here is the part of the code used for cursor handling.
EXEC SQL PREPARE S FROM :gSQLStatement;
EXEC SQL DECLARE C CURSOR FOR S;
EXEC SQL OPEN C;
.
.
.
EXEC SQL DESCRIBE SELECT LIST FOR S INTO selda;
.
.
.
EXEC SQL FOR :array_size FETCH C USING DESCRIPTOR selda;
.
.
.
sqlclu(selda);
EXEC SQL CLOSE C;
Thanks,
Swain
September 06, 2005 - 8:11 am UTC
can you please put things in one place?
see the other place you put this for comments.
Back to the Original Question by Connie Halpin
Roger, September 23, 2005 - 3:29 pm UTC
Hi, Tom,
I found that your query:
select a.value, b.name
from v$mystat a, v$statname b
where a.statistic# = b.statistic#
and b.name = 'opened cursors current'
still returns a result that includes 'cached cursors' that has been closed.
Here are my test procs and results - should be general enough for any other oracle dbs:
SQL> CREATE OR REPLACE PROCEDURE OPENCursorTest1
2 IS
3
4 CURSOR Test_cur
5 IS
6 SELECT * FROM global_name
7 ;
8
9 V_NUM_OPENCURSOR NUMBER;
10
11 BEGIN
12
13 OPEN Test_cur;
14 CLOSE Test_cur;
15
16 IF Test_cur%ISOPEN THEN
17
18 select a.value INTO V_NUM_OPENCURSOR
19 from v$mystat a, v$statname b
20 where a.statistic# = b.statistic#
21 and b.name = 'opened cursors current';
22
23 DBMS_OUTPUT.PUT_LINE('Test_cur IS OPEN AND NUM OPEN CURSORS ='||TO_CHAR(V_NUM_OPENCURSO
R));
24 CLOSE Test_cur;
25 ELSE
26
27 select a.value INTO V_NUM_OPENCURSOR
28 from v$mystat a, v$statname b
29 where a.statistic# = b.statistic#
30 and b.name = 'opened cursors current';
31 DBMS_OUTPUT.PUT_LINE('Test_cur IS CLOSED AND NUM OPEN CURSORS
32 ='||TO_CHAR(V_NUM_OPENCURSOR));
33
34 END IF;
35
36
37 END OPENCursorTest1;
38 /
Procedure created.
SQL>
SQL> show error;
No errors.
SQL>
SQL> exec OPENCursorTest1
Test_cur IS CLOSED AND NUM OPEN CURSORS
=3
PL/SQL procedure successfully completed.
SQL>
SQL> CREATE OR REPLACE PROCEDURE OPENCursorTest2
2 IS
3
4 CURSOR Test_cur
5 IS
6 SELECT * FROM global_name
7 ;
8
9 V_NUM_OPENCURSOR NUMBER;
10
11 BEGIN
12
13 OPEN Test_cur;
14 --CLOSE Test_cur;
15
16 IF Test_cur%ISOPEN THEN
17
18 select a.value INTO V_NUM_OPENCURSOR
19 from v$mystat a, v$statname b
20 where a.statistic# = b.statistic#
21 and b.name = 'opened cursors current';
22
23 DBMS_OUTPUT.PUT_LINE('Test_cur IS OPEN AND NUM OPEN CURSORS ='||TO_CHAR(V_NUM_OPENCURSO
R));
24 CLOSE Test_cur;
25 ELSE
26
27 select a.value INTO V_NUM_OPENCURSOR
28 from v$mystat a, v$statname b
29 where a.statistic# = b.statistic#
30 and b.name = 'opened cursors current';
31 DBMS_OUTPUT.PUT_LINE('Test_cur IS CLOSED AND NUM OPEN CURSORS
32 ='||TO_CHAR(V_NUM_OPENCURSOR));
33
34 END IF;
35
36
37 END OPENCursorTest2;
38 /
Procedure created.
SQL>
SQL> show error;
No errors.
SQL>
SQL> exec OPENCursorTest2
Test_cur IS OPEN AND NUM OPEN CURSORS =3
PL/SQL procedure successfully completed.
SQL>
The SQL_TEXTs for the two of the three open cursors are the same for the two cases:
SID SQL_TEXT
51 SELECT A.VALUE FROM V$MYSTAT A, V$STATNAME B WHERE A.STATIST
51 SELECT * FROM GLOBAL_NAME
The question is now back to Connie's:
How do we know the "real" open cursors that developers forget to explicitly close in the app codes?
Thanks Tom!
Roger
Open Cursors discussion is very helpful
jim basler, September 27, 2005 - 9:22 am UTC
Thanks for having this out here
Maximum No Of Cursor
Mita, March 17, 2006 - 2:51 pm UTC
my process does not have any Open Cursor or Open REF Cursor. there is a call to DBMS_XML.get_xml and it returns out put of it in CLOB to Java program. when I am load testing the app for 300 simultaneous users, I get ora-01000 error. Database version is 10gR1 and parameter is set to 300.
since we are not opening any cursors explictly, why would we get this error ??
March 17, 2006 - 5:57 pm UTC
post the smallest test case humanly possible against the scott.emp table.
(what is dbms_xml? for example...)
Also, the java code is managing THEIR cursors (the only way to talk to oracle) correctly right??
Obtaining the text of open cursors
Steve Baldwin, March 22, 2006 - 6:58 pm UTC
I have a situation where I believe my app is leaking cursors, but it would help me a lot to see the SQL text of only the open (as reported by the session_open_cursors function) cursors.
Is this possible?
Thanks.
March 22, 2006 - 7:17 pm UTC
what function is that?
Oops
Steve Baldwin, March 22, 2006 - 9:06 pm UTC
Sorry, I just realised that is a function we wrote. It just returns the value for the statistic 'opened cursors current'.
March 23, 2006 - 10:11 am UTC
v$open_cursor has the leading bit of sql text and it can be joined to v$sql.
What about the text for *open* cursors
Steve Baldwin, March 23, 2006 - 2:26 pm UTC
As you say above ...
"V$OPEN_CURSOR represents a set of cached cursors the server
has for you. The query [snip] gives you the actual number of truely open cursors."
What I am trying to get is the text for truly open cursors.
March 23, 2006 - 2:34 pm UTC
doesn't exist as far as I know.
SQL query for Open Cursors
Archana, March 23, 2006 - 11:08 pm UTC
I am facing a problem in our production. There are some cursors which are not getting closed.
Using following query I am able to get the count of open cursors:
SELECT a.SID, a.VALUE, b.NAME
FROM v$sesstat a, v$statname b, v$session s
WHERE a.statistic# = b.statistic#
AND a.statistic# = 3
AND a.SID = s.SID
AND a.VALUE <> 0;
But I am not able to get the sql queries of those open cursors anyhow.
Can you please help me?
Thanks in Advance.
March 24, 2006 - 8:29 am UTC
v$open_cursor
Session_cached_cursor
Anil, March 24, 2006 - 3:28 am UTC
Hi Tom
How does open_cursor and session_cached_cursor relted to. What is the difference between these two.
In the top of this article you had mentioned
<<V$OPEN_CURSOR represents a set of cached cursors the server
has for you. >>
so what is session_cached_cursor will do. a bit confused..
Thanks & Rgds
Anil
March 24, 2006 - 9:49 am UTC
Query
Shwetha, April 25, 2006 - 2:35 am UTC
Could you please let me know how to forcibly close the open cursors that are listed in the table V$OPEN_CURSOR
April 25, 2006 - 5:37 am UTC
You cannot, the application that owns them is the only thing that can.
And the only things that "cares" really - each session has it's own set of cursors and it's own limit on cursors - It is not like one application can be hogging all of the cursors for the system.
Differences on V$SQL_PLAN
JAIME, July 01, 2009 - 7:22 pm UTC
Hi tom,
Could you please explain the reuslts.
First example Database 9.2.0.8 ( session_cached_cursors=0)
Second example 10.2.0.3 session_cached_cursors=20
Third example 10.2.0.3 session_cached_cursors=0
All examples i just connected to the database:
1)
JServer Release 9.2.0.8.0 - Production
select * from V$MYSTAT where rownum < 2;
SID STATISTIC# VALUE
---------- ---------- ----------
2617 0 1
Transcurrido: 00:00:00.00
variable x refcursor
exec open :x for select * from dual;
Procedimiento PL/SQL terminado correctamente.
Transcurrido: 00:00:00.00
select name, value
from v$mystat a, v$statname b 2
where a.statistic# = b.statistic#
and b.name = 3 4 'opened cursors current';
NAME VALUE
---------------------------------------------------------------- ----------
opened cursors current 4
Transcurrido: 00:00:00.01
select sql_text from V$OPEN_CURSOR where sid=2617;
SQL_TEXT
------------------------------------------------------------
select sql_text from V$OPEN_CURSOR where sid=2617
SELECT * FROM DUAL
Transcurrido: 00:00:00.05
select name, value
from v$mystat a, v$statname b 2
where a.statistic# = b.statistic#
and b.name = 3 4 'opened cursors current';
NAME VALUE
---------------------------------------------------------------- ----------
opened cursors current 4
Transcurrido: 00:00:00.00
EXAMPLE 2)
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
select * from V$MYSTAT where rownum < 2;
SID STATISTIC# VALUE
---------- ---------- ----------
1019 0 1
variable x refcursor
exec open :x for select * from dual;
Procedimiento PL/SQL terminado correctamente.
select name, value
from v$mystat a, v$statname b 2
where a.statistic# = b.statistic#
and b.name = 3 4 'opened cursors current';
NAME VALUE
---------------------------------------------------------------- ----------
opened cursors current 2
select sql_text from V$OPEN_CURSOR where sid=1019;
SQL_TEXT
------------------------------------------------------------
select f.file#, f.block#, f.ts#, f.length from fet$ f, ts$ t
SELECT DECODE('A','A','1','2') FROM DUAL
SELECT USER FROM DUAL
BEGIN open :x for select * from dual; END;
SELECT * FROM DUAL
select * from V$MYSTAT where rownum < 2
select name, value from v$mystat a, v$statname b where a.sta
BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); END;
SELECT CHAR_VALUE FROM SYSTEM.PRODUCT_PRIVS WHERE (UPPER('
DECLARE v_ID NUMBER; v_user VARCHAR2(15); v_program
SELECT ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DATE_VALUE F
select sql_text from V$OPEN_CURSOR where sid=1019
12 filas seleccionadas.
select name, value
from v$mystat a, v$statname b 2
where a.statistic# = b.statistic#
and b.name = 3 4 'opened cursors current';
NAME VALUE
---------------------------------------------------------------- ----------
opened cursors current 2
Third example:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
alter session set session_cached_cursors=0;
Sesión modificada.
select * from V$MYSTAT where rownum < 2;
SID STATISTIC# VALUE
---------- ---------- ----------
975 0 1
variable x refcursor
exec open :x for select * from dual;
Procedimiento PL/SQL terminado correctamente.
select name, value
from v$mystat a, v$statname b 2
where a.statistic# = b.statistic#
and b.name = 3 4 'opened cursors current';
NAME VALUE
---------------------------------------------------------------- ----------
opened cursors current 2
select sql_text from V$OPEN_CURSOR where sid=975;
SQL_TEXT
------------------------------------------------------------
update sys.col_usage$ set equality_preds = equality_pre
SELECT * FROM DUAL
select sql_text from V$OPEN_CURSOR where sid=975
select name, value
from v$mystat a, v$statname b 2
where a.statistic# = b.statistic#
and b.name = 3 4 'opened cursors current';
NAME VALUE
---------------------------------------------------------------- ----------
opened cursors current 2
My questions are :
1) Does oracle treat in a different way opened cursors on different versions ¿?
2) Why does oracle detect 4 opened cursors on oracle 9 ¿?
It makes more sense to me the behaviour of oracle 10.
A reader, May 06, 2010 - 2:55 pm UTC
Sir,
I am trying to understand about the 'open_cursors' and 'session_cached_cursors' and to understand them clearly - I want to understand the cursors how they are managed by the client,pl/sql in the above example ..
I have a 3GL application which calls a pl/sql procedure
Any 3GL application
============================
declare a cursor C- CLIENT CURSOR
main()
C=call_plsql_procedure();
end;
==========================
see below the pl/sql procedure
create or replace call_plsql_procedure
as
declare a ref_cursor R - EXPLICIT cursor - 1
curor d is select emp_no from emp; -EXPLICIT CURSOR -2 (Pl/sql)
begin
open d;
fetch d into x
close c ;
update emp set emp_no=emp_no+20 -- IMPLICIT 1
select x from y into z --IMPLICIT 2
end;
Here
Client Cursor - 1
Pl/sql Explicit cursors -2
Pl/sql Implicit cursors - 3
Could you please explain the sequence of the cursors caching/closing above by pl/sql and the client ?
Thanks for your time
May 06, 2010 - 8:54 pm UTC
implicit and explicit cursors are both cached by plsql the same - so, we don't need to consider them "differently" - they are to plsql "the same thing"
(ref cursors - they are different however, they are not cacheable)
Here the client has 1 cursor and plsql opens two more.
Plsql will cache OPEN (ignore your close) as many cursors as it can, up to session_cached_cursors (which is less than or equal to open-cursors). So, in this case, probably (assuming session cached cursors > 2), plsql would have 2 cursors open at the end.
The client - the client decides whether to cache or not. The programmer might cache the cursor, the API the programmer uses might. This caching is typically NOT affected at all by session-cached-cursors (it could be, typically is not, you'd have to read the documentation for your client api to see what it does).
The plsql cursor cache is nice because if you have say
open_cursors = 100
session_cached_cursors = 50
and your client has 50 open cursors - and plsql has 50 CACHED OPENED cursors and your client wants to open the 51st cursor - instead of getting an error, plsql will gracefully close a cursor - taking its cache down to 49, giving you the extra cursor handle to open in the client.
A reader, May 09, 2010 - 6:50 am UTC
Hard Parse :
cursor creation,allocate some memory in uga/pga to store the information about SQL,variables etc ,syntax,semantic check,bindng,create a LINK to SGA ,Optimizer will develop the best execution plan and store in SGA .
Soft Parse:
again we do -cursor creation,allocate some memory in uga/pga to store the information about SQL,variables etc ,syntax,semantic check,bindng,HERE WE FIND SAME SQL in SGA and so NO NEED to create an execution plan - again we have to create a link to that SQL ... so everything is same as hard parse excpet that 'execution plan' is not again built in this case.
Softer Soft parse :(curose caching by pl/sql or any 3gl)
nothing we do here ...becuase memory already exists,link to SGA exists , exection plan is there ... just 'execute' it
Is my understaning correct Tom ? Thank you
May 10, 2010 - 6:35 pm UTC
softer soft parse is achieved using session_cached_cursors - there the application actually does close the cursor and we have to reopen it - but - if they close it say three times, we finally catch on and say "oh, you didn't really mean to close that" and when we close it - we keep a pointer to it in the shared pool so that when you say open the next time, we check the shared pool (skipping many of the steps like syntax parse, semantic check) to see if it is still there and if so, just execute it.
then there is NO PARSE - that is what plsql code - that is plsql cursor caching.
So, there is:
a) hard parse (very very very bad)
b) soft parse (very very bad)
c) softer soft parse (very bad)
d) NO PARSE (very very very good!)
A reader, May 11, 2010 - 5:39 am UTC
Sir,
Let us say - it is 'dedicated connection'
When the client(3gl) submits a SQL statement for first time - It first creates a pointer an handle -(cursor) on its side ,associates the SQL with it - allocates 'sql area' to hold the information about that sql in pga/uga and make a parse call to server - the client is done now ...
Server parses it , get the execution plan and store them in SGA , now there is a pointer to the SQL in the SGA . so there are 'two' pointers now - one is from client to PGA/uga and second is from PGA/UGA to SGA
Lets say the statement is executed 3 times (open, close, open-close,open -close) - then Server may decide to 'cache' it - in this case -
1.Server 'caches' the cursor - means what happens internally? I mean - here the cursor is closed but the pointer from pga/uga still points to the SQL in SGA though the cursor is closed ....Correct ? but the SQL can be aged out from shared pool as per LRU logic.
2.Will the Client (3gl) also 'cache' cursor as Server does above - (or) does it depend on client side programming ? How it actually 'caches' internally ?
3.Lets say in the above case - the SQL statement is from pl/sql block -
Pl/SQl 'caches' the cursor though the cursor is closed - means what happens ? Here the cursor is still 'open' so everything remains same as if it is open - correct ?
Here the SQL can NOT be aged out from shared pool as the cursor is still open.
A reader, May 24, 2010 - 1:49 pm UTC
Sir,
Let us say - it is 'dedicated connection'
When the client(3gl) submits a SQL statement for first time - It first creates a pointer an
handle -(cursor) on its side ,associates the SQL with it - allocates 'sql area' to hold the
information about that sql in pga/uga and make a parse call to server - the client is done now ...
Server parses it , get the execution plan and store them in SGA , now there is a pointer to the SQL
in the SGA . so there are 'two' pointers now - one is from client to PGA/uga and second is from
PGA/UGA to SGA
Lets say the statement is executed 3 times (open, close, open-close,open -close) - then Server may
decide to 'cache' it - in this case -
1.Server 'caches' the cursor - means what happens internally? I mean - here the cursor is closed
but the pointer from pga/uga still points to the SQL in SGA though the cursor is closed
....Correct ? but the SQL can be aged out from shared pool as per LRU logic.
2.Will the Client (3gl) also 'cache' cursor as Server does above - (or) does it depend on client
side programming ? How it actually 'caches' internally ?
3.Lets say in the above case - the SQL statement is from pl/sql block -
Pl/SQl 'caches' the cursor though the cursor is closed - means what happens ? Here the cursor is
still 'open' so everything remains same as if it is open - correct ?
Here the SQL can NOT be aged out from shared pool as the cursor is still open.
May 24, 2010 - 2:32 pm UTC
are you talking about session cached cursors? I think so, because of the magic "3" reference.
conceptually:
The client would call "close", the server process working on behalf of the client would say "oh, you closed it N times already - you are going to open it again, I'll save you some work" and it keeps a pointer to the SGA where this statement is in the shared pool. If you say "open" again - it will peek at that point, look in the shared pool and see if that statement is still there - if so, it can just re-establish everything it needs and execute that cursor.
I (tom) call this a softer soft parse.
Normally:
soft parse:
o parse sql text for syntax, build parse tree
o do a semantic lookup to resolve all items in sql statement - so we know what "T" is in "select * from t" for example
o hash original sql statement to a sql_id
o look up in shared pool for matches
o search the matches for one that matches everything exactly (same tables being queried, same optimizer environment, etc)
o then execute
hard parse:
o everything a soft parse does - except it doesn't find a match so it
o optimizes (generate lots of plans, sort by cost, take the cheapest one)
o row source generates (turns plan into something that we can execute, generate byte code)
o puts it (new shared sql and row source) into the shared pool
o then execute
softer soft parse:
o peek at pointer, if sql still there in shared pool, reattach it then execute
o if sql not still there, goto hard/soft parse
excellent explanation
A reader, May 24, 2010 - 3:48 pm UTC
Many thanks Tom for your excellent explanation -
Sorry but one more doubt
there is a slight difference between any 3GL cached cursors and PL/SQL cached cursors ?
I was under impression if PL/SQL caches a curosr - the SQL can not be aged out(removed) from shared pool but for 3GL(client) cursors -Oracle will age out the SQL though the cursor is cached ?
Is it wrong assumption ?
May 24, 2010 - 7:44 pm UTC
... there is a slight difference between any 3GL cached cursors and PL/SQL cached
cursors ? ...
what is a 3gl cached cursor and how is pl/sql not a 3gl?
but most importantly, what do you mean by "3gl cached cursor", I'm not familiar with that term or concept.
A reader, May 25, 2010 - 4:43 am UTC
Sorry , I was wrong in saying '3gl cached cursors' - I meant to say any 'API' client which interacts with Database .
I want to know if there is difference between the caching mechanism between an API client caching and Pl/SQL caching .
PL/SQL will automatically 'caches' if the cursor is opened few times (say 3 times) but the API client - it depends on the API and user programming (the API code)- the client will decide whether to cache or not ,…
Is it correct ?
May 25, 2010 - 7:40 am UTC
define API client cache now. What is that? How is it implemented? What is it's logic?
See where I am going here - I don't know what API cache you are talking about, how it is implemented, what it does, how it was designed, how efficient it is. Every API would necessarily do it "their way"
PLSQL *does not* automatically cache the cursor if it is opened a few times - that is what SESSION_CACHED_CURSORS does for any client (any - repeat - any client).
PLSQL does it one better. When you open a cursor in PLSQL, and later close it (explicitly or implicitly), PLSQL keeps it OPEN - does not close it - right away, from the first time.
PLSQL will cache N open cursors like that (where N = setting for session_cached_cursors - but this is NOT using the session_cached_cursors logic at all, plsql just borrows that number to set N, that is all). If PLSQL has N cursors cached open - and the client has (OPEN_CURSORS-SESSION_CACHED_CURSORS - eg: N) cursors open (so that all possible cursors are opened - and the client attempts to open one more cursor - PLSQL will silently, transparently - close one of it's cursors (so now it has N-1 open) so the client can have OPEN_CURSORS-SESSION_CACHED_CURSORS+1 cursors open. PLSQL will keep doing that for as long as the client needs more cursor handles.
A reader, May 25, 2010 - 8:27 am UTC
Many Many thanks Tom for the excellent explanation ..
I am learning a lot of things *clearly* from you .
Sir , I have one question for you
Why do you revise and update your book 'Effective Oracle by design' ?
I have your book first edition (Expert Oracle architecture 9i and 10g) and got the alpha version of your second edition (Expert Oracle architecture 9i,10g and 11g ) and compared both of them - I may be wrong - what I have understood is you added just few 11g features of those concepts to the same old book .
But the one who ** understands clearly your first edition** can easily understands 11g features just by going through the concepts guide or any other book
Because that first book has basic, solid and great explanations for every concept- I don’t see very much benefit for going for second edition of the book while I have the first edition .
What thought came to mind is - if you rewrite the "Effective Oracle by design for 11g" - that would *rock and roll*..
Can we expect this in future ?
Sir, Please don’t mind - this is purely my personal opinion and this is what I felt in my mind.
May 25, 2010 - 12:37 pm UTC
the 2nd edition of Expert Oracle Database Architecture is an update - a 2nd edition. Corrections, updates to how things work now, some new features are included. But yes, by and large, it is still Expert Oracle Database Architecture - just the 2nd edition.
I just wrote on another thread a few minutes ago - that I would not actually change very much in Effective Oracle by Design - it wasn't really version specific in most of the pages - not at all. In fact, it would have made sense in version 7.3 for the most part...
How to close cursors...
Abhisek, September 07, 2010 - 10:25 am UTC
Hi Tom,
In case I declare a cursor in my package and I dont close it, what happens? Is it closed after some time automatically?
If not, I would like to know the way we can close the cursors that are open which I see through your query:
select sum(a.value), b.name
from v$sesstat a, v$statname b
where a.statistic# = b.statistic#
and b.name = 'opened cursors current'
group by b.name
Does the same logic applies for the CFL (Cursor For-Loop) also? as we dont fetch there, I hope.
Please suggest.
September 09, 2010 - 8:19 pm UTC
it depends, there are implicit cursors (always closed as they go out of scope - and they always go out of scope). there are explicit cursors - they do not always go out of scope, you would have to make sure that the ones that do not go out of scope are closed by you!
ops$tkyte%ORA11GR2> create or replace package my_pkg
2 as
3 procedure p;
4 end;
5 /
Package created.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> create or replace package body my_pkg
2 as
3
4 cursor always_closed_for_me is select * from all_users;
5
6 cursor I_must_close_this is select * from all_users;
7
8 procedure p
9 is
10 cursor this_will_be_closed_for_me is select * from all_users;
11 l_rec all_users%rowtype;
12 begin
13 for x in (select * from all_users THIS_IS_ALWAYS_CLOSED_FOR_ME)
14 loop
15 null;
16 end loop;
17
18 for y in ALWAYS_CLOSED_FOR_ME
19 loop
20 null;
21 end loop;
22
23 open I_must_close_this;
24 loop
25 fetch I_must_close_this into l_rec;
26 exit when I_must_close_this%notfound;
27 end loop;
28 close I_must_close_this;
29
30 open this_will_be_closed_for_me;
31 loop
32 fetch this_will_be_closed_for_me into l_rec;
33 exit when this_will_be_closed_for_me%notfound;
34 end loop;
35 /* sloppy but I don't have to close it */
36 end;
37
38 end;
39 /
Package body created.
A reader, September 10, 2010 - 9:33 am UTC
Dear Sir,
Nice example!!!
for x in (select * from all_users THIS_IS_ALWAYS_CLOSED_FOR_ME) ------- implicit cursor
14 loop
15 null;
16 end loop;
17
18 for y in ALWAYS_CLOSED_FOR_ME ----- declare in package body
19 loop
20 null;
21 end loop;
(1) so does it mean that explicit or imlicit cursor when loop through FOR LOOP will close implicitly i.e. automatically?
(2) Also when cursor is close implicitly OR explicitly does oracle still keep it open under the hood in PL/SQL cache ?
Thanks
September 13, 2010 - 7:46 am UTC
(1) yes.
(2) yes. up to session_cached_cursors in 9i and above (open_cursors in 8i and before)
Wierd open cursors current value
Dayne Olivier, October 28, 2010 - 4:51 am UTC
Hi Tom, (Oracle 10.1.0.5, open_cursors=300, session_cached_cursors=0, cursor_sharing=EXACT)
I stumbled upon something really strange today. It relates to open cursors. I was trying to determine how many open cursors were being used by each user (across multiple sessions), so I used the following SQL:
select sum(a.value) total_cur, avg(a.value) avg_cur, max(a.value) max_cur, count(*) sessions#,
s.username, s.machine, s.program
from v$sesstat a, v$statname b, v$session s
where a.statistic# = b.statistic# and s.sid=a.sid
and b.name = 'opened cursors current'
group by s.username, s.machine, s.program
order by 1 desc;
This seemed to work quite well. I tested it by logging in and opening some cursors and closing some cursors etc. This seemed to work as expected.
However, while running this in my production environment, there was suddenly a single session that jumped to the top of the list with a number for total_cur that was so big, it just showed ############ as a value. So I quickly changed the query to try and get the total open cursors for the single user:
select a.value total_cur,
s.username, s.machine, s.program
from v$sesstat a, v$statname b, v$session s
where a.statistic# = b.statistic# and s.sid=a.sid
and b.name = 'opened cursors current'
AND S.USERNAME = 'HDM4'
Using toad to view the output, I got a result of 1.84467440737096E19
And now, I am totally confused. I don't get it... How is this possible? There was only 1 session for the given schema (schema named 'HDM4'). A bit more info:
a) I also noticed that this was a dbms_job process.
b) The session seemed to be connected for perhaps 5-10 minutes.
Sanity check: is my SQL wrong?
How is it possible that the session opens more than open_cursors? And, is this query really indicating "currently open cursors"?
Thanks Tom
October 28, 2010 - 12:11 pm UTC
that looks like an overflow of some sort - please utilize support.
you could just:
select *
from v$sesstat
where sid in (select sid from v$session where username = 'HDM4')
and statistic# = (select statistic# from v$statname where name = 'opened cursors current' )
if you don't trust your join.
new book - suggestion only
Ajeet ojha, October 29, 2010 - 3:52 am UTC
Hi Tom,
have been asking questions here since last 8 yrs, some one above made a comment that you should write a new version of effective design for 11g. My opinion is you should write a book which tells more details..which help the mid-level experienced folks in oracle ( have 4-8 yrs of experience) mostly in consultiing work on oracle. reasons are :
1)There are so many un-answered queries in our mind - they never get answered - partly we don;t have source of information as we are not oracle employees - one such exmaple is - how to read AWR reports and make sense out of it. there are few things we know, we learn from asktom or we learn from some other books .
2) how to really approach a complex performance issue...
sometime i do feel that you just oversimplify the answers you gave here...I do unserstand that you speak from your experience and we will probably never reach to that level but there is fair amount of queroisity to know the things - how things actually work in oracle..to become more comptent than what we are.
recently i read a book "troubleshooting oracle performance" - something like that may be...if comes from you as well -would be a great assist .
Regards
Ajeet
November 01, 2010 - 5:06 am UTC
... sometime i do feel that you just oversimplify the answers you gave here... ...
No, I try to make the seemingly complex - simple. Which most of the times, it is. We tend to get buried in the details, not realizing that many things are actually "simple".
Fetched rows
Victor Hugo Marques COsta, June 21, 2013 - 8:36 pm UTC
Hi Tom!
Are there any way to know if a cursor still have any row to be fetched? I need to kill some inactive sessions with opened cursors, but I don´t know if one of these cursors will be fetched by the user later.
Thanks!
Victor
July 01, 2013 - 5:28 pm UTC
no, there isn't, not really. you could use the real time sql monitor to attach to the queries in 11g - but it would be rather clumsy to do this.