February 3, 2010
Assume that one of the users receives an error message like this one from an application (caution: some errors may be bigger than they appear).
Just what does this error message mean? It could mean that Oracle’s OPEN_CURSORS initialization parameter, which specifies the maximum number of cursors that may be open simultaneously by a single session, is set too low. The error could also mean that a limit of the program, the database connection method, or the application development environment was hit. Or, the error could potentially be a false alarm – maybe there was a completely different error (maybe out of memory) and this message just happened to be selected for presentation to the user.
First, let’s try a quick experiment:
(Session 1, Just After Connecting to the Database):
SELECT SID FROM V$MYSTAT WHERE ROWNUM<=1; SID ----- 168
(Session 2):
SELECT SQL_ID, SUBSTR(SQL_TEXT,1,50) SQL_TEXT, COUNT(*) CNT FROM V$OPEN_CURSOR WHERE SID=168 GROUP BY SQL_ID, SUBSTR(SQL_TEXT,1,50) ORDER BY SQL_ID; SQL_ID SQL_TEXT CNT ------------- -------------------------------------------------- ---- 1uzhrfn574t12 SELECT ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DA 1 2q93zsrvbdw48 select grantee#,privilege#,nvl(col#,0),max(mod(nvl 2 425wwycyjax6t DECLARE SHOULD_EXECUTE INTEGER; BEGIN SELECT D 1 53saa2zkr6wc3 select intcol#,nvl(pos#,0),col#,nvl(spare1,0) from 1 6769wyy3yf66f select pos#,intcol#,col#,spare1,bo#,spare2 from ic 1 6aq34nj2zb2n7 select col#, grantee#, privilege#,max(mod(nvl(opti 2 7ng34ruy5awxq select i.obj#,i.ts#,i.file#,i.block#,i.intcols,i.t 2 83taa7kaw59c1 select name,intcol#,segcol#,type#,length,nvl(preci 2 96g93hntrzjtr select /*+ rule */ bucket_cnt, row_cnt, cache_cnt, 1 a73wbv1yu8x5c select con#,type#,condlength,intcols,robj#,rcon#,m 2 bsa0wjtftg3uw select file# from file$ where ts#=:1 1 c4pc3jhzjcmc7 SELECT CHAR_VALUE FROM SYSTEM.PRODUCT_PRIVS WHERE 1 d6vwqbw6r2ffk SELECT USER FROM DUAL 1 dyk4dprp70d74 SELECT DECODE('A','A','1','2') FROM DUAL 1 f8pavn1bvsj7t select con#,obj#,rcon#,enabled,nvl(defer,0) from c 2 g4y6nw3tts7cc BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); E 1 16 rows selected.
(Session 1):
SELECT COUNT(*) FROM ALL_OBJECTS;
(Session 2 – Re-execute the same SQL statement):
... 16 rows selected.
No change in the number of open cursors.
(Session 1):
SELECT COUNT(*) FROM ALL_OBJECTS; SELECT COUNT(*) FROM ALL_OBJECTS;
(Session 2 – Re-execute the same SQL statement):
SQL_ID SQL_TEXT CNT ------------- -------------------------------------------------- ---- 1uzhrfn574t12 SELECT ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DA 1 2q93zsrvbdw48 select grantee#,privilege#,nvl(col#,0),max(mod(nvl 2 425wwycyjax6t DECLARE SHOULD_EXECUTE INTEGER; BEGIN SELECT D 1 53saa2zkr6wc3 select intcol#,nvl(pos#,0),col#,nvl(spare1,0) from 1 6769wyy3yf66f select pos#,intcol#,col#,spare1,bo#,spare2 from ic 1 6aq34nj2zb2n7 select col#, grantee#, privilege#,max(mod(nvl(opti 2 7ng34ruy5awxq select i.obj#,i.ts#,i.file#,i.block#,i.intcols,i.t 2 83taa7kaw59c1 select name,intcol#,segcol#,type#,length,nvl(preci 2 96g93hntrzjtr select /*+ rule */ bucket_cnt, row_cnt, cache_cnt, 1 a73wbv1yu8x5c select con#,type#,condlength,intcols,robj#,rcon#,m 2 bsa0wjtftg3uw select file# from file$ where ts#=:1 1 c4pc3jhzjcmc7 SELECT CHAR_VALUE FROM SYSTEM.PRODUCT_PRIVS WHERE 1 d6vwqbw6r2ffk SELECT USER FROM DUAL 1 dr2v8xdg4w2ag SELECT COUNT(*) FROM ALL_OBJECTS 1 dyk4dprp70d74 SELECT DECODE('A','A','1','2') FROM DUAL 1 f8pavn1bvsj7t select con#,obj#,rcon#,enabled,nvl(defer,0) from c 2 g4y6nw3tts7cc BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); E 1 17 rows selected.
In the above, notice that the open cursor count increased and that the “SELECT COUNT(*) FROM ALL_OBJECTS” SQL statement with SQL_ID dr2v8xdg4w2ag is now listed in the V$OPEN_CURSOR output, indicating that it is now held open in the session cursor cache. So, the SQL statements in the session cursor cache could be affecting the actual number of cursors that may remain open, as specified by the OPEN_CURSORS initialization parameter, so this could be a problem (I have not investigated to see what happens when the OPEN_CURSORS value is reached – whether or not Oracle will throw an error, or simply close one of the cached cursors).
Back to the error message, let’s spend a couple of minutes investigating this particular problem. We execute a SQL statement that outputs the following (note that the HASH_VALUE is output, not the SQL_ID):
SID USER_NAME PROGRAM HASH_VALUE SQL_TEXT CNT --- ---------- ---------- ---------- ------------------------------------------------------------ ------- 208 USER1 CUSINQ.EXE 1511368051 SELECT BITS FROM CUST_LINE_BINARY where TYPE = :1 and 74 235 USER2 PLNWIN.EXE 881677082 select TRANSACTION_ID, IT.TYPE, IT.CLASS, WORKORDER_TYPE, 15 237 USER3 PURENT.EXE 233497298 select ID from VENDOR where ACTIVE_FLAG = 'N' 11 115 USER4 APIENT.EXE 233497298 select ID from VENDOR where ACTIVE_FLAG = 'N' 228
Does the above show a problem? Maybe, maybe not – it depends on what the SQL statement’s output is actually showing to us. The above output is from a query of V$SESSION and V$OPEN_CURSOR. SID 115 (USER4) had 228 open cursors for the SQL statement “select ID from VENDOR where ACTIVE_FLAG = ‘N’“, and SID 237 (USER3) had 11 cursors open for the same SQL statement – is this a problem? Maybe, maybe not. At the point that this output was captured, the APIENT.EXE program was active for only a short period of time, but just a couple of minutes after the above was captured, the application crashed with the error message shown in the picture at the top of this article. Was it a problem with too small of a value for the OPEN_CURSORS parameter?
SQL> SHOW PARAMETER OPEN_CURSORS NAME TYPE VALUE --------------- ----------- ----- open_cursors integer 1000
From the above, probably not. Some development environments limit the number of simulatneously open cursors in an application (or worse yet limit the sum of all cursors opened in all applications developed with that development environment that are concurrently running on a computer) to a number that is substantially lower than the 1,000 cursors permitted by the OPEN_CURSORS parameter. This particular program was apparently developed using a version of the Centura/Gupta/Unify SQLWindows development environment that limits each application to no more than 300 open cursors. In reality, 300 is a high limit – so hitting that limit should be uncommon, yet the application has 228 cursors open for this one SQL statement. It appears that this application has a cursor leak, where a cursor is opened, but never closed (until the application is closed or the program crashes). So, a quick examination of a 10046 trace for the session which was enabled in a logon trigger finds this:
PARSING IN CURSOR #4 len=69 dep=2 uid=0 oct=42 lid=0 tim=1182428884 hv=1576194328 ad='77846918' ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 12' ... PARSING IN CURSOR #4 len=45 dep=0 uid=50 oct=3 lid=50 tim=3416927811 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #8 len=45 dep=0 uid=50 oct=3 lid=50 tim=3620531267 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #9 len=45 dep=0 uid=50 oct=3 lid=50 tim=3724573181 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #26 len=45 dep=0 uid=50 oct=3 lid=50 tim=3827005408 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #30 len=45 dep=0 uid=50 oct=3 lid=50 tim=3848476712 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #19 len=45 dep=0 uid=50 oct=3 lid=50 tim=3995284712 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #20 len=45 dep=0 uid=50 oct=3 lid=50 tim=4088861749 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... ... PARSING IN CURSOR #254 len=45 dep=0 uid=50 oct=3 lid=50 tim=3223320608 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #78 len=45 dep=0 uid=50 oct=3 lid=50 tim=3336508540 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #260 len=45 dep=0 uid=50 oct=3 lid=50 tim=3336615021 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... PARSING IN CURSOR #251 len=45 dep=0 uid=50 oct=3 lid=50 tim=3356820371 hv=233497298 ad='88d08b70' select ID from VENDOR where ACTIVE_FLAG = 'N' ... WAIT #259: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3357352080 WAIT #259: nam='SQL*Net message from client' ela= 279 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3357352383 WAIT #0: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3357352417 *** 2008-08-12 15:52:59.826 WAIT #0: nam='SQL*Net message from client' ela= 157430298 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514782745 XCTEND rlbk=1, rd_only=0 WAIT #0: nam='db file sequential read' ela= 10308 file#=4 block#=221289 blocks=1 obj#=12464 tim=3514793577 WAIT #0: nam='log file sync' ela= 105 buffer#=16352 p2=0 p3=0 obj#=12464 tim=3514794105 WAIT #0: nam='SQL*Net message to client' ela= 3 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514794195 WAIT #0: nam='SQL*Net message from client' ela= 3539 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514797765 STAT #7 id=1 cnt=1 pid=0 pos=1 obj=11900 op='TABLE ACCESS FULL ACCOUNT_PERIOD (cr=8 pr=0 pw=0 time=83 us)' XCTEND rlbk=1, rd_only=1 ... XCTEND rlbk=1, rd_only=1 WAIT #0: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514806922 WAIT #0: nam='SQL*Net message from client' ela= 263 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514807200 STAT #4 id=1 cnt=0 pid=0 pos=1 obj=12943 op='TABLE ACCESS FULL VENDOR (cr=122 pr=0 pw=0 time=2238 us)' XCTEND rlbk=1, rd_only=1 ... XCTEND rlbk=1, rd_only=1 WAIT #0: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514807792 WAIT #0: nam='SQL*Net message from client' ela= 265 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514808072 STAT #9 id=1 cnt=0 pid=0 pos=1 obj=12943 op='TABLE ACCESS FULL VENDOR (cr=122 pr=0 pw=0 time=2235 us)' XCTEND rlbk=1, rd_only=1 WAIT #0: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514808212 WAIT #0: nam='SQL*Net message from client' ela= 249 driver id=1413697536 #bytes=1 p3=0 obj#=12464 tim=3514808477 STAT #8 id=1 cnt=1 pid=0 pos=1 obj=0 op='UPDATE SEMAPHORE (cr=1 pr=0 pw=0 time=99 us)' STAT #8 id=2 cnt=1 pid=1 pos=1 obj=12738 op='INDEX UNIQUE SCAN X_SEMAPHORE_0 (cr=1 pr=0 pw=0 time=14 us)' XCTEND rlbk=1, rd_only=1 ...
Once a cursor is closed, Oracle will re-use the CURSOR # associated with that cursor when the next SQL statement is executed (assuming that the SQL statement is not already held open in the session cursor cache). If the PARSING IN CURSOR # value keeps increasing, that is a sign that cursors are not being closed either due to the design of application code (it might be intentional to reduce the number of soft parses) or the session cursor cache. From the above, it looks like the application crashed at 2008-08-12 15:52:59.826 and a rollback (XCTEND rlbk=1, rd_only=0) was performed that affected previously changed, but not committed data. Once the program crashed, Oracle wrote the STAT lines for all cursors that were still open. In the above, we see the STAT lines that for cursor #4 and #9 were written after the crash, and those cursors were opened fairly early in the trace activity (note that the 32 bit value used for the tim= entry wrapped around 0 while tracing was enabled). The STAT line output for cursor #8 after the crash shows a different execution plan than that for cursor #9, indicating that at some point the “select ID from VENDOR where ACTIVE_FLAG = ‘N’” SQL statement that was opened early in the trace file for cursor #8 successfully closed at some point before the crash. In this case, the 10046 trace file provided significant evidence that a programming fix was required. The developers to the rescue… 🙂
Let’s try executing the following SQL statement in a time period unrelated to the above exploration (with SQL statements executed by some users explicitly omitted and some SQL statements explicitly omitted – warning, you probably should not repeatedly execute this SQL statement due to the potential for latching problems):
SELECT OC.SID, OC.USER_NAME, S.PROGRAM, COUNT(*) COUNTER, OC.SQL_ID, OC.SQL_TEXT FROM V$OPEN_CURSOR OC, V$SESSION S WHERE OC.SQL_TEXT NOT LIKE '%obj#,%' AND OC.SQL_TEXT NOT LIKE '%grantee#,%' AND OC.SQL_TEXT NOT LIKE '%privilege#%' AND OC.SQL_TEXT NOT LIKE 'DECLARE%' AND OC.SQL_TEXT NOT LIKE '%/*+ rule */%' AND OC.SQL_TEXT NOT LIKE '%col#%' AND OC.SQL_TEXT NOT LIKE '%sys.mon_mods$%' AND OC.SQL_TEXT NOT LIKE '%obj#=%' AND OC.SQL_TEXT NOT LIKE '%update$,%' AND OC.SID=S.SID AND OC.USER_NAME NOT IN ('SYS','DBSNMP','SYSTEM','SYSMAN','RMAN') GROUP BY OC.SID, OC.USER_NAME, S.PROGRAM, OC.SQL_ID, OC.SQL_TEXT HAVING COUNT(*)>=10 ORDER BY OC.USER_NAME, OC.SID, OC.SQL_TEXT; SID USER_NAME PROGRAM COUNTER SQL_ID SQL_TEXT ----- --------- -------------------------- ------- ------------- ------------------------------------------------------------ 208 USER1 PLNWIN.EXE 20 5ngzsfstg8tmy select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname, 173 USER2 NCMR.exe 10 5ngzsfstg8tmy select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname, 173 USER2 NCMR.exe 10 cqgv56fmuj63x select owner#,name,namespace,remoteowner,linkname,p_timestam 302 USER3 CapturePhoneData.exe 11 36405ka00hcv5 INSERT INTO PHONE_LOG ( ACCESS_DATE, EXTENSION 230 USER4 bclabr.exe 10 6qrbg23ub5syp SELECT calc_end_qty, completed_qty FROM OPERATION WHERE WO 235 USER5 bclabr.exe 10 6qrbg23ub5syp SELECT calc_end_qty, completed_qty FROM OPERATION WHERE WO 246 USER6 PURENT.EXE 14 5ngzsfstg8tmy select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname, 171 USER7 CorrectiveActionReport.exe 15 5ngzsfstg8tmy select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname, 167 USER8 NetworkTest.exe 53 3ubfyvhz2zdfk SELECT HOST_NAME , LAST_DEAD_PING , WARNING_MINUTES , IP_ADD 167 USER8 NetworkTest.exe 55 55gk2gdxb9mvc SELECT IP , COMPUTER_NAME FROM CUSTAPP.WEB_LOCAL_IP_LOOKUP 167 USER8 NetworkTest.exe 88 4xu4rvudbc83p UPDATE DOC_OBJECT_DESCRIPTION SET LAST_GOOD_PI 296 USER9 ReceivePO.exe 10 fr464ph8jb4zm SELECT COUNT(*) LINES FROM CUSTAPP.PURC_ORDER_OPEN WHE 296 USER9 ReceivePO.exe 12 5ft6wg3qhvw58 SELECT RCE.PURC_ORDER_ID, RCE.PURC_ORDER_LINE_NO, P.PR ...
USER1 has about 20 cursors open for SQL_ID 5ngzsfstg8tmy, which appears to be an internal SQL statement that is executed on behalf of the session. The same SQL_ID appears for a couple of other sessions. Let’s take a look at that SQL statement a little more closely.
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('5ngzsfstg8tmy',NULL,'TYPICAL')); SQL_ID 5ngzsfstg8tmy, child number 0 ------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 1 ------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 2 ------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 3 ------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 4 ------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 5 ------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 7 ------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 9 ------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 10 -------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 11 -------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) - SQL_ID 5ngzsfstg8tmy, child number 12 -------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o. dataobj#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 ---------------------------------------------- | Id | Operation | Name | ---------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | ---------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1) Note ----- - rule based optimizer used (consider using cbo) - SQL_ID 5ngzsfstg8tmy, child number 14 -------------------------------------- select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,o.dataob j#,o.flags from obj$ o where o.obj#=:1 Plan hash value: 3317232865 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| OBJ$ | 1 | 74 | 2 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | I_OBJ1 | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("O"."OBJ#"=:1)
There are 12 child cursors for this SQL statement still in the library cache, or at least the execution plans are still available. If we check V$SQL_SHARED_CURSOR we might be able to tell why at least 15 child cursors were created for this one SQL statement:
SQL_ID ADDRESS CHILD_ADDRESS CN USOOSLSEBPISTABDLTRIIRLIOSMUTNFAITDLDBPCSRPTMBMROPMFL ------------- ---------------- ---------------- -- ----------------------------------------------------- 5ngzsfstg8tmy 000000018D960FF0 000000018D9600C0 0 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 000000018D642EA8 1 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN 000000018D960FF0 000000018A2D1B98 2 NNYNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 0000000180B86C60 3 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 000000016AC7CD28 4 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 0000000161B54780 5 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 0000000175FE5788 6 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 0000000178648270 7 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 0000000173425140 9 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 000000017322B9C0 10 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 00000001834D71D8 11 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 00000001767FE0C8 12 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN 000000018D960FF0 000000017D28DFA0 14 NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNNN
In the above, the first O is OPTIMIZER_MISMATCH, the second S is STATS_ROW_MISMATCH, the last R is ROLL_INVALID_MISMATCH, and the last O is OPTIMIZER_MODE_MISMATCH. A lot of the child cursors were created due to statistics collection – I wonder if some of these older child cursors are still open by sessions. Oracle Database 10.2.0.x does not offer the IS_SHAREABLE column in V$SQL, but the IS_OBSOLETE column shows that none of the 13 child cursors still in the library cache has been marked as obsolete:
SELECT CHILD_NUMBER CN, PARSING_SCHEMA_NAME, OPTIMIZER_ENV_HASH_VALUE OPTIMIZER_ENV, INVALIDATIONS, PARSE_CALLS, IS_OBSOLETE, FIRST_LOAD_TIME, TO_CHAR(LAST_ACTIVE_TIME,'YYYY-MM-DD/HH24:MI:SS') LAST_ACTIVE_TIME FROM V$SQL WHERE SQL_ID='5ngzsfstg8tmy'; CN PARSING_SC OPTIMIZER_ENV INVALIDATIONS PARSE_CALLS I FIRST_LOAD_TIME LAST_ACTIVE_TIME -- ---------- ------------- ------------- ----------- - ------------------- ------------------- 0 SYS 1515106640 1 3107 N 2009-11-27/16:40:02 2010-01-25/14:53:12 1 SYS 1515106640 0 240 N 2009-11-27/16:40:02 2010-01-25/22:03:15 2 SYS 2540482053 0 1073 N 2009-11-27/16:40:02 2010-02-01/08:01:01 3 SYS 1515106640 0 2810 N 2009-11-27/16:40:02 2010-02-01/03:40:02 4 SYS 1515106640 0 583 N 2009-11-27/16:40:02 2010-01-25/18:09:13 5 SYS 1515106640 0 239 N 2009-11-27/16:40:02 2010-02-01/10:19:44 6 SYS 2540482053 0 69 N 2009-11-27/16:40:02 2010-02-01/10:14:58 7 SYS 1515106640 0 763 N 2009-11-27/16:40:02 2010-01-25/10:49:16 9 SYS 1515106640 0 510 N 2009-11-27/16:40:02 2010-02-01/08:16:10 10 SYS 2540482053 0 163 N 2009-11-27/16:40:02 2010-02-01/06:54:04 11 SYS 1515106640 0 260 N 2009-11-27/16:40:02 2010-01-31/23:07:26 12 SYS 2230081206 0 8 N 2009-11-27/16:40:02 2010-02-01/03:48:43 14 SYS 1515106640 0 654 N 2009-11-27/16:40:02 2010-02-01/06:10:55
The OPTIMIZER_ENV_HASH_VALUE is different for some of the child cursors, although all of the SQL statements were parsed by the SYS user. Let’s take a look at what is different about the optimizer environment for some of the SQL statements:
SELECT CHILD_NUMBER CN, NAME, VALUE, ISDEFAULT DEF FROM V$SQL_OPTIMIZER_ENV WHERE SQL_ID='5ngzsfstg8tmy' AND CHILD_NUMBER in (0,2,12) ORDER BY NAME, CHILD_NUMBER;
If we just list the differences in the output for the three child cursors, we see the following:
CN NAME VALUE DEF --- --------------------------- --------------- --- 2 _optim_peek_user_binds false NO 0 optimizer_mode choose NO 2 optimizer_mode choose NO 12 optimizer_mode rule NO
Interesting, two of the child cursors are using an OPTIMIZER_MODE of CHOOSE, and one is using an OPTIMIZER_MODE of RULE, neither of which are valid (supported) OPTIMIZER_MODE values for this release of Oracle Database. Of course, it is possible to supply a hint to force the use of the RULE optimizer (might be used by Oracle’s internal SQL statements), but CHOOSE? Just to verify:
SQL> SHOW PARAMETER OPTIMIZER_MODE NAME TYPE VALUE ---------------- ----------- -------- optimizer_mode string ALL_ROWS
The _OPTIM_PEEK_USER_BINDS is disabled for one of the three unique OPTIMIZER_ENV_HASH_VALUE values, which was implemented in a logon trigger to “fix” problems with certain applications that either fail to initialize bind variable values on the initial hard parse, or select unpopular values during the initial hard parse. But, there is no logon trigger that sets the OPTIMIZER_MODE to CHOOSE for a session.
OK, the topic is drifting a bit. USER1 (SID 208) has 20 cursors open with this internal SQL statement. I wonder if the number of child cursors in the library cache could be a possible cause, combined with the value of 200 for SESSION_CACHED_CURSORS (if a SQL statement is executed at least 3 times, it will be added to the cached cursors for the session and held open, even when the client explicitly closes the cursor)?
I suppose at this point, I should probably try to determine why the NetworkTest.exe program has 88 open cursors for an update statement, 55 open cursors for one select statement, and 53 open cursors for a second select statement… To crash, or not to crash, is not the question – it is only a matter of time.
Recent Comments