Before describing the issue that lead to this post, let’s shortly review how the handling of initialization parameters works in a multitenant environment.
The issue that I recently experienced while working in a multitenant environment for one of my customers can be summarized by the inconsistency related to the output of the following queries (not that both are executed at the PDB level):
SQL> SELECT value FROM v$system_parameter WHERE name = 'optimizer_dynamic_sampling';
VALUE
------------------------------
0
SQL lang="dummy"> SELECT value FROM v$sys_optimizer_env WHERE name = 'optimizer_dynamic_sampling';
VALUE
------------------------------
11
Note that both queries should return the same value. But, since it isn’t the case, two are the key questions that require an answer…
First question, in which situation the output of the two queries is inconsistent?
I’m able to observe such an inconsistency when three conditions are met. First, the initialization parameter has been set at the PDB level. Second, the value of the initialization parameter at the PDB level is different than the one at the CDB level. Third, the initialization parameter was set before the last instance bounce (unplug/plug and close/open don’t show this behavior). Note that I didn’t test whether it happens for all initialization parameters. In any case, I can confirm that it’s the case for the ones with the “optimizer” prefix. The following example illustrates:
SQL> STARTUP
SQL> ALTER PLUGGABLE DATABASE pdb121 OPEN;
SQL> ALTER SESSION SET CONTAINER = cdb$root;
SQL> ALTER SYSTEM SET optimizer_dynamic_sampling = 2;
SQL> ALTER SESSION SET CONTAINER = pdb121;
SQL> ALTER SYSTEM SET optimizer_dynamic_sampling = 0;
SQL> ALTER SESSION SET CONTAINER = cdb$root;
SQL> SHUTDOWN IMMEDIATE
SQL> STARTUP
SQL> ALTER PLUGGABLE DATABASE pdb121 OPEN;
SQL> ALTER SESSION SET CONTAINER = pdb121;
SQL> SELECT value FROM v$system_parameter WHERE name = 'optimizer_dynamic_sampling';
VALUE
-------------------------
0
SQL> SELECT value FROM v$sys_optimizer_env WHERE name = 'optimizer_dynamic_sampling';
VALUE
-------------------------
2
Second question: which one of the two values is used?
According to my tests, in version 12.1 (more about 12.2 later on) the query optimizer uses the one returned by V$SYS_OPTIMIZER_ENV. The following example, which is a continuation of the previous one, illustrates:
SQL> ALTER SESSION SET events 'trace[sql_optimizer.*]';
SQL> EXPLAIN PLAN FOR SELECT * FROM dual;
SQL> ALTER SESSION SET events 'trace[sql_optimizer.*]off';
SQL> SELECT value FROM v$diag_info WHERE name = 'Default Trace File';
VALUE
--------------------------------------------------------------------------------
/u00/oracle/app/oracle/diag/rdbms/dbm121/DBM121/trace/DBM121_ora_25742.trc
SQL> host grep "^optimizer_dynamic_sampling" /u00/oracle/app/oracle/diag/rdbms/dbm121/DBM121/trace/DBM121_ora_25742.trc
optimizer_dynamic_sampling = 2
optimizer_dynamic_sampling = 2
The examples shown before where generated with version 12.1.0.2.160719. The same test in version 12.2.0.1.0 leads, in my opinion, to an even worse result. In fact, even though the value shown by the two dynamic performance views is consistent (i.e. both shows the value 0), the value that is actually used by the query optimizer is the wrong one! The following example illustrates:
SQL> ALTER SESSION SET CONTAINER = pdb1;
SQL> SELECT value FROM v$system_parameter WHERE name = 'optimizer_dynamic_sampling';
VALUE
-------------------------
0
SQL> SELECT value FROM v$sys_optimizer_env WHERE name = 'optimizer_dynamic_sampling';
VALUE
-------------------------
0
SQL> ALTER SESSION SET events 'trace[sql_optimizer.*]';
SQL> EXPLAIN PLAN FOR SELECT * FROM dual;
SQL> ALTER SESSION SET events 'trace[sql_optimizer.*]off';
SQL> SELECT value FROM v$diag_info WHERE name = 'Default Trace File';
VALUE
--------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/orcl/ORCL/trace/ORCL_ora_5518.trc
SQL> host grep "^optimizer_dynamic_sampling" /u01/app/oracle/diag/rdbms/orcl/ORCL/trace/ORCL_ora_5518.trc
optimizer_dynamic_sampling = 2
optimizer_dynamic_sampling = 2
I checked MOS and I found a number of bugs (all related to version 12.1) in this area:
I’m not sure whether what I see is caused by one of these bugs. In any case, Oracle has to fix all of them straightaway! I’m actually surprised that version 12.2 shows the behavior I just described. It’s such a basic functionality that must work as expected!
In summary, if you work in a multitenant environment, after restarting an instance, you have to make sure that all your PDB are using the right settings. To do so, you either have to set the initialization parameters at the CDB level only or you have to execute a number of ALTER SYSTEM statements at the PDB level. It goes without saying that the former is only an acceptable workaround if you have a single PDB.
Recent comments
3 years 5 weeks ago
3 years 17 weeks ago
3 years 22 weeks ago
3 years 22 weeks ago
3 years 27 weeks ago
3 years 48 weeks ago
4 years 16 weeks ago
4 years 46 weeks ago
5 years 30 weeks ago
5 years 31 weeks ago