Quantcast
Channel: Timur Akhmadeev's blog » shared cursors
Viewing all articles
Browse latest Browse all 4

Obsolete cursors

$
0
0

In the previous post I wrote about strangely behaving V$SQL. For some reason there were duplicate rows leading to wrong results issue when running DBMS_XPLAN.DISPLAY_CURSOR for a particular child cursor. I tried to reproduce the issue using simple test case – and it was reproduced.

Here it is. I’m starting to execute a simple query against DUAL while constantly changing optimizer environment, forcing Oracle to build a new child cursor for each execution:

alter session set workarea_size_policy=manual;
col curr_date new_value curr_date
select to_char(sysdate, 'HH24MISS') curr_date from dual;
set define on verify off

begin
    for i in 1..100 loop
        execute immediate 'alter session set sort_area_size=' || to_char(100000 + i*1024);
        execute immediate 'select /* &&curr_date */ count(*) from dual';
    end loop;
end;
/

col sql_id new_value sql_id
select sql_id, address from v$sqlarea where sql_text = 'select /* &&curr_date */ count(*) from dual';
clear columns
select count(*) from v$sql_shared_cursor where sql_id = '&&sql_id';
@unshared &&sql_id

As expected, I’ve got 100 child cursors and 99 of them were created due to OPTIMIZER_MISMATCH:

SQL> select sql_id, address from v$sqlarea where sql_text = 'select /* &&curr_date */ count(*) from dual';

SQL_ID        ADDRESS
------------- ----------------
8ugq0vhq0z7pb 000007FF5D45C0B0

SQL> clear columns
columns cleared
SQL> select count(*) from v$sql_shared_cursor where sql_id = '&&sql_id';

            COUNT(*)
--------------------
                 100

SQL> @unshared &&sql_id

SQL_ID        NONSHARED_REASON                          COUNT(*)
------------- ----------------------------- --------------------
8ugq0vhq0z7pb OPTIMIZER_MISMATCH                              99

Now let’s continue and see what will happen:

begin
    for i in 101..250 loop
        execute immediate 'alter session set sort_area_size=' || to_char(100000 + i*1024);
        execute immediate 'select /* &&curr_date */ count(*) from dual';
    end loop;
end;
/

select count(*) from v$sql_shared_cursor where sql_id = '&&sql_id';

select sum(cnt), avg(cnt), min(child_number), max(child_number)
  from (select child_number, count(*) cnt
          from v$sql
         where sql_id = '&&sql_id'
         group by child_number);

select address, count(*) from v$sql where sql_id='&&sql_id' group by address;
select sql_id, address from v$sqlarea where sql_text = 'select /* &&curr_date */ count(*) from dual';
@unshared &&sql_id
select * from table(dbms_xplan.display_cursor('&&sql_id', 1));
SQL> select count(*) from v$sql_shared_cursor where sql_id = '&&sql_id';

            COUNT(*)
--------------------
                 250

SQL>
SQL> select sum(cnt), avg(cnt), min(child_number), max(child_number)
  2    from (select child_number, count(*) cnt
  3            from v$sql
  4           where sql_id = '&&sql_id'
  5           group by child_number);

            SUM(CNT)             AVG(CNT)    MIN(CHILD_NUMBER)    MAX(CHILD_NUMBER)
-------------------- -------------------- -------------------- --------------------
                 250                  2.5                    0                   99

SQL>
SQL> select address, count(*) from v$sql where sql_id='&&sql_id' group by address;

ADDRESS                      COUNT(*)
---------------- --------------------
000007FF5D1E18A8                   50
000007FF5D45C0B0                  100
000007FF5D5BA268                  100

SQL> select sql_id, address from v$sqlarea where sql_text = 'select /* &&curr_date */ count(*) from dual';

SQL_ID        ADDRESS
------------- ----------------
8ugq0vhq0z7pb 000007FF5D1E18A8

SQL> @unshared &&sql_id

SQL_ID        NONSHARED_REASON                          COUNT(*)
------------- ----------------------------- --------------------
8ugq0vhq0z7pb OPTIMIZER_MISMATCH                             249

SQL> select * from table(dbms_xplan.display_cursor('&&sql_id', 1));

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------
SQL_ID  8ugq0vhq0z7pb, child number 1
-------------------------------------
An uncaught error happened in prepare_sql_statement : ORA-01422: exact fetch returns more than requested number of rows

Plan hash value: 3910148636

-----------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------

SQL_ID  8ugq0vhq0z7pb, child number 1
-------------------------------------
An uncaught error happened in prepare_sql_statement : ORA-01422: exact fetch returns more than requested number of rows

Plan hash value: 3910148636

-----------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------

SQL_ID  8ugq0vhq0z7pb, child number 1
-------------------------------------
An uncaught error happened in prepare_sql_statement : ORA-01422: exact fetch returns more than requested number of rows

Plan hash value: 3910148636

-----------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   0 | SELECT STATEMENT |      |       |     2 (100)|          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------


114 rows selected.

Bingo. After the point of 100 child cursors per parent, Oracle builds a new parent (V$SQL.ADDRESS holds its address) cursor, marking old parent and child cursors as obsolete. V$SQLAREA handles the situation well, but V$SQL doesn’t and that’s clearly a bug. The threshold point of when to build a new parent cursor is 100 by default and is controlled with a new hidden parameter _cursor_obsolete_threshold. I’ve tested setting this parameter to 150 and it worked as expected. Note that this bug-fix-improvement-again-bugs 10187168 claimed to be included into Patch Set Update 11.2.0.2.2 (and higher). I’ve tested 11.2.0.2.3 & 11.2.0.2.5 and it seems the improvement is not enabled by default and they act the old, pre-11.2.0.3 way; most likely the bug-fix have to be enabled explicitly with event 106001 in the 11.2.0.2 PSUs. I haven’t tested it though.
PS. If you have time and desire, please file a bug to Oracle.


Filed under: Oracle Tagged: 11.2.0.3, bug, dynamic views, shared cursors

Viewing all articles
Browse latest Browse all 4

Latest Images

Trending Articles



Latest Images