Strange behaviours on setting PDB parameters 3


[Tests performed on Oracle 19.8]

All started when I wanted to create a query to check which parameters are set on a PDB and the difference from the CDB$ROOT container.

set pages 110
col pdb_name for a10 
col name for a30 
col value for a20
col pdb_value for a20
col root_value for a20
col source for a10
select a.pdb_name, a.name, a.value PDB_VALUE, b.value ROOT_VALUE,source from
  (select pdb_name,name,value,a.con_id, decode(ismodified,'MODIFIED','PDB SPFILE','PDB$SEED') SOURCE 
   from v$system_parameter a left join dba_pdbs b on (a.CON_ID=b.pdb_id)
   where a.con_id>2 and (ismodified='MODIFIED' or isdefault='FALSE')) a,
  (select 'CDB$ROOT' pdb_name,name,value,con_id,null
   from v$system_parameter where con_id=0) b
where a.name=b.name and a.con_id>2
order by 1,2;

But I know there is also one view called pdb_spfile$ that would show the parameters on the PDB pseudo-spfiles:

col pdb_name for a10 
col name for a20
col value$ for a20
select pdb_name,name,value$ 
from pdb_spfile$ left join dba_pdbs on (CON_UID=pdb_uid) 
where con_id>2 
and bitand(nvl(spare2,0),1)=0
order by name;

The V$SYSTEM_PARAMETER is well documented, while the PDB_SPFILE$ is not.

A slight more complete query to check parameters which are not set the same between cdb$root and the PDB is this one:

with pdb_params as (select pdb_name,name,trim(both '''' from value$) value$ 
                                   from pdb_spfile$ left join dba_pdbs on (CON_UID=pdb_uid)
                                   where con_id>1 and bitand(nvl(spare2,0),1)=0 ),
        cdb_params as (select name, value,inst_id,con_id from gv$parameter ),
        spfile_params as (select name,value, sid from v$spparameter where isspecified='TRUE')
  select pdb_name, pdb_params.name, value$ pdb_value, cdb_params.value root_value, spfile_params.value spfile_value
    from pdb_params, cdb_params, spfile_params
    where pdb_params.name(+)=cdb_params.name and cdb_params.name(+)=spfile_params.name
        and (value$!=cdb_params.value or value$!=spfile_params.value)
union all 
  select case when sys_context('USERENV','CON_NAME') !='CDB$ROOT' then 'CALL THIS SCRIPT FROM CDB$ROOT' end pdb_name,
        null,null,null,null from dual
order by 1,2;

Now, the set or unset parameters do not work the same way, as I expected, it trigger some strange behaviours.

Strange behaviours

ALTER SYSTEM … default SCOPE on PDB

Oracle Documentation 19c only mentions the default SCOPE on CDB root:

"If a server parameter file was used to start up the database, then BOTH is the default. If a parameter file was used to start up the database, then MEMORY is the default, as well as the only scope you can specify."

On a PDB, the default SCOPE depends(!) on the action:

Setting a parameter, then default is SCOPE=BOTH :

TVDCDB1.PDB01 SQL> show parameter cursor_sharing
NAME             TYPE        VALUE
---------------- ----------- ----------------
cursor_sharing   string      EXACT

TVDCDB1.PDB01 SQL> show spparameter cursor_sharing
SID      NAME             TYPE        VALUE
-------- ---------------- ----------- ----------------
*        cursor_sharing   string

TVDCDB1.PDB01 SQL> alter system set cursor_sharing=FORCE;
System altered.

TVDCDB1.PDB01 SQL> show parameter cursor_sharing
NAME             TYPE        VALUE
---------------- ----------- ----------------
cursor_sharing   string      FORCE

TVDCDB1.PDB01 SQL> show spparameter cursor_sharing
SID      NAME             TYPE        VALUE
-------- ---------------- ----------- ----------------
*        cursor_sharing   string      FORCE

Resetting a parameter, then default is SCOPE=SPFILE :

TVDCDB1.PDB01 SQL> alter system reset cursor_sharing;
System altered.

TVDCDB1.PDB01 SQL> show parameter cursor_sharing
NAME             TYPE        VALUE
---------------- ----------- ----------------
cursor_sharing   string      FORCE

TVDCDB1.PDB01 SQL> show spparameter cursor_sharing
SID      NAME             TYPE        VALUE
-------- ---------------- ----------- ----------------
*        cursor_sharing   string

TVDCDB1.PDB01 SQL> alter system reset cursor_sharing scope=both;
System altered.

TVDCDB1.PDB01 SQL> show parameter cursor_sharing
NAME             TYPE        VALUE
---------------- ----------- ----------------
cursor_sharing   string      EXACT

PDB_SPFILE$ marks row as “deleted” on parameter reset

[EDIT: 03.01.2022, next paragraphs corrected followed helpful comments from Martin Albert Berger]

When going back to the CDB root, I would expect to not see anymore the parameter on PDB_SPFILE$ view. Well, it is still there:

SQL> connect / as sysdba
Connected.

SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT

SQL> select pdb_name,name,value$ from pdb_spfile$ left join dba_pdbs on (CON_UID=pdb_uid) where name='cursor_sharing' order by name;

PDB_NAME   NAME                      VALUE$
---------- ------------------------- --------------------
PDB01      cursor_sharing            'FORCE'
1 row selected.

SQL> -- Need to use "and bitand(nvl(spare2,0),1)=0", as row is just marked "deleted"

SQL> select pdb_name,name,value$ from pdb_spfile$ left join dba_pdbs on (CON_UID=pdb_uid) where name='cursor_sharing' and bitand(nvl(spare2,0),1)=0 order by name;

no rows selected

Use ISMODIFIED column on V$SYSTEM_PARAMETER

On V$SYSTEM_PARAMETER the “ISDEFAULT=’FALSE'” will show the SEED non-default parameters for all PDBs, even if these are not specified on the PDB pseudo-spfile:

SQL> create pluggable database pdb02 admin user pdb_admin identified by pdb_admin file_name_convert=('pdbseed','pdb02');
Pluggable database created.

SQL> alter pluggable database pdb02 open;
Pluggable database altered.

select a.pdb_name, a.name, a.value PDB_VALUE, b.value ROOT_VALUE from
  (select pdb_name,name,value 
   from v$system_parameter a left join dba_pdbs b on (a.CON_ID=b.pdb_id)
   where a.con_id>2 and isdefault='FALSE') a,
  (select 'CDB$ROOT' pdb_name,name,value 
   from v$system_parameter where con_id=0) b
where a.name=b.name and a.pdb_name='PDB02'
order by 1,2;


PDB_NAME   NAME                 PDB_VALUE            ROOT_VALUE
---------- -------------------- -------------------- --------------------
PDB02      db_securefile        PREFERRED            PREFERRED
PDB02      sga_target           0                    2634022912
PDB02      shared_pool_size     0                    637534208
PDB02      undo_tablespace      UNDOTBS1             UNDOTBS1

4 rows selected.

SQL> select 'PDB$SEED' pdb_name, name,value from v$system_parameter where con_id=2 and isdefault='FALSE';

PDB_NAME   NAME                 VALUE
---------- -------------------- --------------------
PDB$SEED   shared_pool_size     0
PDB$SEED   sga_target           0
PDB$SEED   undo_tablespace
PDB$SEED   db_securefile        PREFERRED

4 rows selected.

One needs to use the ISMODIFIED=’MODIFIED’ to get the modified values on a specific PDB:

SQL> select a.pdb_name, a.name, a.value PDB_VALUE, b.value ROOT_VALUE from
  (select pdb_name,name,value 
   from v$system_parameter a left join dba_pdbs b on (a.CON_ID=b.pdb_id)
   where a.con_id>2 and isdefault='FALSE') a,
  (select 'CDB$ROOT' pdb_name,name,value 
   from v$system_parameter where con_id=0) b
where a.name=b.name and a.pdb_name='PDB02'
order by 1,2;

no rows selected

SQL> alter session set container=PDB01;
Session altered.

TVDCDB1.PDB01 SQL> alter system set cursor_sharing=FORCE;
System altered.

TVDCDB1.PDB01 SQL> alter session set container=CDB$ROOT;
Session altered.

SQL> select a.pdb_name, a.name, a.value PDB_VALUE, b.value ROOT_VALUE from
  (select pdb_name,name,value 
   from v$system_parameter a left join dba_pdbs b on (a.CON_ID=b.pdb_id)
   where a.con_id>2 and ismodified='MODIFIED') a,
  (select 'CDB$ROOT' pdb_name,name,value 
   from v$system_parameter where con_id=0) b
where a.name=b.name and a.pdb_name='PDB02'
order by 1,2;

PDB_NAME   NAME                 PDB_VALUE            ROOT_VALUE
---------- -------------------- -------------------- --------------------
PDB01      cursor_sharing       FORCE                EXACT

Summary: Make sure you use the correct filter on V$SYSTEM_PARAMETER or PDB_SPFILE$ to have the parameters of a PDB.


Leave a comment

Your email address will not be published. Required fields are marked *

3 thoughts on “Strange behaviours on setting PDB parameters

  • Martin Berger

    I did a quick&dirty test:
    when I set cursor_sharing in my PDB, the column pdb_spfile$.SPARE2 is 0,
    when I RESET cursor_sharing, pdb_spfile$.SPARE2 changes to 1.
    hth

    • Miguel Anjo Post author

      Hi Martin,

      Thanks for the comment. So I would believe the right way to use pdb_spfile$ would be:

      select pdb_name,name,value$
      from pdb_spfile$ left join dba_pdbs on (CON_UID=pdb_uid)
      where name=’cursor_sharing’
      and spare2=0
      order by name;

      Do you agree?

      • Martin Berger

        Hi Miguel,
        Yes, kind of 😉
        I’d use the filter
        bitand(nvl(spare2,0),1)=0
        as Oracle is also using it internally.

        I’d prefer using something like CONTAINERS(v$spparameterfile) but I failed in my sandbox for unknown reasons.