Перейти к содержанию

Session cursor cache count statistics incorrect with parallel queries

I have recently investigated an issue with high session cursor cache count statistics in one of 11.2.0.4 databases. I found that some of sessions have extremely high values of these statistics.

Investigation

SQL> select s.sid, ss.value, s.logon_time, s.service_name, s.program
  2    from v$session s,
  3         v$statname sn,
  4         v$sesstat ss
  5   where sn.name='session cursor cache count'
  6     and ss.statistic#=sn.statistic#
  7     and ss.value > 100
  8     and s.sid=ss.sid;

       SID      VALUE LOGON_TIME          SERVICE_NAME PROGRAM
---------- ---------- ------------------- ------------ ----------------
       485        255 19.05.2015 02:47:52 dp_task      JDBC Thin Client
       705      12774 19.05.2015 02:47:51 dp_task      JDBC Thin Client
       800        267 19.05.2015 02:47:51 dp_task      JDBC Thin Client

the session_cached_cursors parameter has a default value of 50. My first thought was that the sessions changed the session_cached_cursors parameter. To confirm this hypothesis, I executed the following oradebug command:

oradebug dump modified_parameters 1

Looking into the trace file:

Received ORADEBUG command (#1) 'dump modified_parameters 1' from process 'Unix process pid: 13761, image: <none>'
DYNAMICALLY MODIFIED PARAMETERS:
  nls_language             = AMERICAN
  nls_territory            = AMERICA
  log_archive_dest_state_3 = ENABLE
  service_names            = drep_dp_stat, drep_dp_task, drep_ora_at, drep_dp_core

*** 2015-05-14 10:44:20.744
Finished processing ORADEBUG command (#1) 'dump modified_parameters 1'

So session_cached_cursors parameter wasn't changed by the session. At the next step I decided to dump all cursors cached by the session:

oradebug dump cursordump 1

Here is the relevant portion of trace file:

----- Session Cached Cursor Dump -----
----- Generic Session Cached Cursor Dump -----
-----------------------------------------------------------
-------------- Generic Session Cached Cursors Dump --------
-----------------------------------------------------------
hash table=ffffffff79d34228 cnt=50 LRU=ffffffff79d245f0 cnt=49 hit=64510 max=50 NumberOfTypes=6

From the above, there was no doubt that the session cursor cache count statistic is lying. I opened an SR with Oracle and the support engineer pointed to a Bug 5713223 : 'SESSION CURSOR CACHE COUNT' OF V$SYSSTAT IS NOT CURRENT VALUE. This bug was opened in 2006 for 10.2 version and is still not resolved yet.

I have a couple of SRs with Oracle in which I wait for the resolution of such long lived bugs. So, I decided to further diagnose this issue and provide additional information to the Oracle Support.

All of the sessions are using the dp_task database service. I created this service for a reporting application that executes a bunch of heavy SQL.

I wrote a simple job that takes a snapshot of v$session, v$sesstat on periodic interval. On the next day I checked the generated data and found a couple of suspicious SQL statements for further investigation.

Most of the SQLs used some combination of: PARALLEL/MATERIALIZE hints, and pipelined table functions. Deeping into this further, I found that the incorrect statistics are due to the PARALLEL hint.

Reproduction

I created a simple test case that can be used to reproduce the issue.

Show
create table t as select * from dba_objects;

sho parameter session_cached_cursors

select s.value
  from v$statname n,
       v$mystat s
 where n.name = 'session cursor cache count'
   and s.statistic#=n.statistic#;

select /*+ parallel(4)*/count(distinct owner) from t;

select s.value
  from v$statname n,
       v$mystat s
 where n.name = 'session cursor cache count'
   and s.statistic#=n.statistic#;

select /*+ parallel(4)*/count(distinct owner) from t;

Here is a SQL*Plus output of the script execution:

SQL> sho parameter session_cached_cursors

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
session_cached_cursors               integer                           50
SQL>
SQL> select s.value
  2    from v$statname n,
  3         v$mystat s
  4   where n.name = 'session cursor cache count'
  5     and s.statistic#=n.statistic#;

     VALUE
----------
        49

SQL>
SQL> select /*+ parallel(4)*/count(distinct owner) from t;

COUNT(DISTINCTOWNER)
--------------------
                  59

SQL>
SQL> select s.value
  2    from v$statname n,
  3         v$mystat s
  4   where n.name = 'session cursor cache count'
  5     and s.statistic#=n.statistic#;

     VALUE
----------
        58

Notice that the session cursor cache count statistic is 49 before the parallel query is run and 58 after. After I executed the parallel query multiple times checking statistics at each step, I found that each query execution leads to an increase of the session cursor cache count statistics by 2*parallel_degree.

SQL> select /*+ parallel(4)*/count(distinct owner) from t;

COUNT(DISTINCTOWNER)
--------------------
                  59
SQL>
SQL> select s.value
  2    from v$statname n,
  3         v$mystat s
  4   where n.name = 'session cursor cache count'
  5     and s.statistic#=n.statistic#;

     VALUE
----------
        98
SQL>
SQL> select /*+ parallel(8)*/count(distinct owner) from t;

COUNT(DISTINCTOWNER)
--------------------
                  59

SQL>
SQL> select s.value
  2    from v$statname n,
  3         v$mystat s
  4   where n.name = 'session cursor cache count'
  5     and s.statistic#=n.statistic#;

     VALUE
----------
       114
SQL>

The good news is that the issue is not reproduced in 12.1.0.2. I hope that Oracle support resolve this issue in 11.2.0.4 too.

Update 17.06.2015

Oracle released a new patch 21135007: SESSION CURSOR CACHE COUNT STATISTICS IS INCORRECT. I applied it to the 11.2.0.4 environment and can confirm that it works as expected. Now the session cursor cache count statistics are correct in the problem scenario.