This was first published on https://blog.dbi-services.com/phantom-session-environment-in-multitenant (2015-12-27)
Republishing here for new followers. The content is related to the the versions available at the publication date

Phantom session environment in multitenant?

In multitenant a session can switch from one container to another. There are a few restrictions such as a transaction cannot span multiple containers. But how do sessions parameters behave? It seems that there is a small inconsistency. I was looking at some adaptive plan and SPM behavior (see this tweeter conversation) and played with the optimizer environment to reproduce the plan I wanted, and then came to a strange behavior. I can understand that a session keep its parameter settings when switching to another container. But not when closing and re-opening the pluggable database. The default values should come then.

Here is an example.

Change in memory value of optimizer parameter

This is in 12.1.0.2 latest PSU. I connect to PDB

19:13:10 SQL> alter session set container=PDB;
Session altered.
and check parameter optimizer_index_cost_adj from memory:
19:13:10 SQL> show parameter optimizer_index_cost_adj;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_index_cost_adj             integer     100
It’s the default.

then I set it to one in memory only:

19:37:17 SQL> alter system set optimizer_index_cost_adj=1 scope=memory;
System altered.
And I run a query and check that the optimizer used that value
19:37:18 SQL> select * from dual;

D
-
X

19:37:19 SQL> select * from table(dbms_xplan.display_cursor(format=>'+outline'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
SQL_ID  a5ks9fhw2v9s1, child number 0
-------------------------------------
select * from dual

Plan hash value: 272002086

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       |     2 (100)|          |
|   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
      DB_VERSION('12.1.0.2')
      OPT_PARAM('optimizer_index_cost_adj' 1)
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "DUAL"@"SEL$1")
      END_OUTLINE_DATA
  */

Si this is expected, my custom value has been used to optimize the cursor.

close and re-open the PDB

I close and restart my PDB:

19:37:19 SQL> shutdown immediate
Pluggable Database closed.
19:37:21 SQL> startup
Pluggable Database opened.
As the value was set in memory, it’s now back to default:
19:36:48 SQL> show parameter optimizer_index_cost_adj;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_index_cost_adj             integer     100

and of course, my cursor is not there anymore:
19:36:48 SQL> select sql_id,child_number,first_load_time,con_id from v$sql where sql_id='a5ks9fhw2v9s1';

no rows selected

So now I run again my query and expect the default optimizer environement:

19:36:48 SQL> select dummy from dual;

D
-
X

19:36:48 SQL> select * from table(dbms_xplan.display_cursor(format=>'+outline'));

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------
SQL_ID  4au7rzs3y6kzn, child number 0
-------------------------------------
select dummy from dual

Plan hash value: 272002086

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       |     2 (100)|          |
|   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
      DB_VERSION('12.1.0.2')
      OPT_PARAM('optimizer_index_cost_adj' 1)
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "DUAL"@"SEL$1")
      END_OUTLINE_DATA
  */
And my new cursor has used the optimizer_index_cost_adj=1 which is not what I expected at all. Does that mean that session parameters remain across PDB close/start? No according to ‘show parameter':
19:37:07 SQL> show parameter optimizer_index_cost_adj;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_index_cost_adj             integer     100

but yes according to V$SES_OPTIMIZER_ENV:
19:37:07 SQL> select sid,name,value from v$ses_optimizer_env where name='optimizer_index_cost_adj' and sid=sys_context('userenv','sid');

       SID NAME                                     VALUE
---------- ---------------------------------------- -------------------------
        35 optimizer_index_cost_adj                 1

Conclusion

I’ve reproduced the same when re-connecting (instead of changing session container) and even when connecting to another PDB. In my opinion, this is a bug. The session parameters should be reinitialized when re-connecting. So be careful.

Update 12-JUL-2016

See Maciej Tokar post about this issue (my case being only one effect)

 

2 Comments