Parameterverwaltung in CDBs und PDBs

6. April 2021 0 Von Markus Flechtner

Auch knapp acht Jahre nachdem Oracle mit der Version 12c die Container-Datenbank-Architektur veröffentlicht hat, ist diese Architektur immer noch nicht bei allen Kunden “angekommen” und sorgt immer wieder für Fragen. Zum Beispiel auch zu dem Thema, wie Parameter in Container-Datenbanken definiert werden und wo die definierten Werte gespeichert werden.

Es gilt – wie bei der klassischen Datenbank („Non-CDB“):

  1. Es gibt eine Instanz mit einer Menge von Prozessen (PMON, SMON, DWB0, LGWR etc.) und einer SGA (Shared Pool, Buffer Cache, Log Buffer etc.)
  2. Es gibt ein spfile in dem die Instanz-Parameter gespeichert sind.

Die Parameter, die im spfile abgelegt sind, werden beim Start der Instanz ausgelesen und sind die Einstellungen für den Root-Container (CDB$ROOT). Änderungen der Parameter erfolgen, auch das ist nichts Neues, mit dem altbekannten „ALTER SYSTEM“-Befehl und werden auch in das spfile geschrieben

CDB$ROOT > alter system set optimizer_index_cost_adj=105 scope=spfile;
System altered.

CDB$ROOT > !strings /u00/app/oracle/dbs/spfileTVDCDB1.ora |grep -i optimizer_index_cost_adj
*.optimizer_index_cost_adj=105


Kurz gesagt: für den Root-Container CDB$ROOT ändert sich nichts. Wie sieht das nun bei den PDBs aus?

Hier gilt, dass – wenn nichts anderes auf PDB-Ebene definiert ist – die Parametereinstellungen aus dem Root-Container übernommen werden. Ein Teil der Parameter kann aber auf PDB-Ebene geändert werden. Diese Parameter enthalten in der Spalte ISPDB_MODIFIABLE in V$SYSTEM_PARAMETER den Wert ‘TRUE’.

CDB$ROOT > select distinct name from v$system_parameter
       2   where ispdb_modifiable='TRUE' order by name;

NAME
------------------------------------------------------------
adg_account_info_tracking
allow_rowid_column_type
approx_for_aggregation
approx_for_count_distinct
approx_for_percentile

[…]

undo_retention
undo_tablespace
unified_audit_systemlog
workarea_size_policy
xml_db_events

196 rows selected.

Um einen derartigen Parameter in einer PDB zu ändern, muss man zuerst in die PDB wechseln:

CDB$ROOT> alter session set container=pdb01;
Session altered.

Die Änderung eines Parameters erfolgt dann wieder mit dem bekannten Befehl “ALTER SYSTEM”:

CDB$ROOT@TVDCDB1> alter system set optimizer_index_cost_adj=110 scope=both;
System altered.

Allerdings wird der geänderte Parameter dann nicht im spfile gespeichert, wie folgender Befehl zeigt:

PDB01> !strings /u00/app/oracle/dbs/spfileTVDCDB1.ora |grep -i optimizer_index_cost_adj
*.optimizer_index_cost_adj=105

 

Wo ist der geänderte Wert dann zu finden?

Um diese Frage zu beantworten, müssen wir wieder zurück in den Root-Container gehen.

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

 

Dort gibt es die Tabelle PDB_SPFILE$, in der Oracle die auf PDB-Ebene geänderten Parameter ablegt:

CDB$ROOT@TVDCDB1> desc pdb_spfile$

 Name                            Null?    Type
 ------------------------------- -------- ----------------------------
 DB_UNIQ_NAME                    NOT NULL VARCHAR2(30)
 PDB_UID                         NOT NULL NUMBER
 SID                             NOT NULL VARCHAR2(80)
 NAME                            NOT NULL VARCHAR2(80)
 VALUE$                                   VARCHAR2(4000)
 COMMENT$                                 VARCHAR2(255)
 SPARE1                                   NUMBER
 SPARE2                                   NUMBER
 SPARE3                                   VARCHAR2(128)

COLUMN pdb_name FORMAT a10
COLUMN name FORMAT a30
COLUMN value$ FORMAT a25




SELECT
    a.pdb_name,
    b.name,
    b.value$
FROM
    cdb_pdbs     a,
    pdb_spfile$  b
WHERE
        a.con_uid = b.pdb_uid
    AND b.spare2 <> 1
    AND a.pdb_name = 'PDB01'
ORDER BY
    a.pdb_name,
    b.name;

PDB_NAME   NAME                        VALUE$
---------- --------------------------- -------------------------
PDB01      optimizer_index_cost_adj    110

1 row selected.

Bei der PDB_SPFILE$ gibt es allerdings einige Dinge zu beachten:

  1. Wenn man PDB_SPFILE$ in einer PDB abfragt, dann ist sie leer.
  2. Wenn man einen Parameter auf PDB Ebene löscht (“ALTER SYSTEM RESET ..”), dann wird die zugehörige Zeile in PDB_SPFILE$ nicht gelöscht. Stattdessen wird die Spalte SPARE2 mit dem Wert 1 gefüllt:
CDB$ROOT > select b.name,b.value$,b.spare2
  2  from cdb_pdbs a,pdb_spfile$ b
  3  where a.con_uid=b.pdb_uid and a.pdb_name='PDB01'
  4  and b.name='optimizer_index_cost_adj';

NAME                     VALUE$                      SPARE2
------------------------------ ------------------------- ----------
optimizer_index_cost_adj       110                      0

1 row selected.


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

PDB01> alter system reset optimizer_index_cost_adj scope=both;
System altered.

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

CDB$ROOT> select b.name,b.value$,b.spare2
  2  from cdb_pdbs a,pdb_spfile$ b
  3  where a.con_uid=b.pdb_uid and a.pdb_name='PDB01'
  4  and b.name='optimizer_index_cost_adj';

NAME                     VALUE$                      SPARE2
------------------------------ ------------------------- ----------
optimizer_index_cost_adj       110                      1

1 row selected.


Für die Abfrage der gültigen Einträge in PDB_SPFILE$ sollte man daher immer die WHERE-Bedingung “where spare2<>1” ergänzen.

 

Wie zeigen sich die Parameter nun in den diversen V$-Views?

Starten wir mit dem Root-Container:

CDB$ROOT > show con_name

CON_NAME
------------------------------
CDB$ROOT

Im spfile steht der Wert, den wir oben geändert haben:

CDB$ROOT1> select con_id,name,value from v$spparameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       1 optimizer_index_cost_adj     105

Da der Wert nur im spfile eingetragen ist (“SCOPE=SPFILE”) und nicht für die laufende Instanz geändert wurde, gilt für die laufende Session (V$PARAMETER) und die laufende Instanz (V$SYSTEM_PARAMETER) noch der Ursprungswert:

CDB$ROOT> select con_id,name,value from v$parameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       1 optimizer_index_cost_adj     100

1 row selected.

CDB$ROOT> select con_id,name,value from v$system_parameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       0 optimizer_index_cost_adj     100

1 row selected.


 

Wie sieht es nun in der PDB aus?

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

 

Auch hier gilt für die Session der originale Wert:

PDB01> select con_id,name,value from v$parameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       1 optimizer_index_cost_adj     100

Die Abfrage auf v$spparameter zeigt ein interessantes Ergebnis:

PDB01> select con_id,name,value from v$spparameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       7 optimizer_index_cost_adj

1 row selected.

Der Eintrag ist leer, da es nur einen inaktiven Eintrag in PDB_SPFILE$ gibt (“spare2=1”), denn die Parameteränderung, die wir oben gemacht hatten, hatten wir ja mit “ALTER SYSTEM RESET” wieder rückgängig gemacht.

 

Jetzt ändern wir den Wert nochmal in der PDB, diesmal für das “spfile” und die laufende Instanz:

PDB01> alter system set optimizer_index_cost_adj=101 scope=both;
System altered.

Und natürlich sind diese Änderungen in den V$-Views sichtbar:

PDB01> select con_id,name,value from v$system_parameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       7 optimizer_index_cost_adj     101

1 row selected.

PDB01> select con_id,name,value from v$parameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       7 optimizer_index_cost_adj     101

1 row selected.

PDB01> select con_id,name,value from v$spparameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       7 optimizer_index_cost_adj     101

1 row selected.


 

Eine interessante Änderung ergibt sich jetzt im Root-Container, wenn wir v$system_parameter abfragen:

 

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

CDB$ROOT> select con_id,name,value from v$system_parameter where name='optimizer_index_cost_adj';

    CON_ID NAME                 VALUE
---------- ------------------------------ ----------
       0 optimizer_index_cost_adj     100
       7 optimizer_index_cost_adj     101

2 rows selected.

Über die v$system_parameter können wir also unterschiedliche Parameter in CDB$ROOT bzw. den PDBs einfach ermitteln.

 

Abschließend noch ein paar Worte zum Real Application Cluster (RAC):

Auch hier ändert sich nichts (unabhängig davon, ob man sich in CDB$ROOT oder in einer PDB befindet):

  • “ALTER SYSTEM .. SCOPE=SPFILE” ändert einen Wert für alle Instanzen.
  • “ALTER SYSTEM .. SCOPE=SPFILE SID=’..'” ändert einen Wert für eine Instanz

Da ich aber schon einmal einen Kunden hatte, der im RAC für die SID den Namen der PDB angegeben hatte – und der sich dann gewundert hat, dass die Änderung nicht erfolgreich war – sei dieser kurze Hinweis gestattet: Wenn man instanzspezifische Parameter für eine PDB setzen will, dann muss man – wie üblich bei “SID” die Instanz angeben und nicht den PDB-Namen.

 

Data Dictionary Tabellen

  • PDB_SPFILE$

V$-Views:

  • v$spparameter (Einträge im spfile)
  • v$parameter (aktuell gültige Einstellungen in einer Session)
  • v$system_parameter (aktuell gültige Einstellungen für die Instanz)

MOS-Notes

  • Initialization parameters in a Multitenant database – Facts and additional information (Doc ID 2101596.1)
  • Initialization parameters in a Multitenant database – FAQ and Examples (Doc ID 2101638.1)
  • Alter Session And System Parameter In Both CDB and PDB (Doc ID 2673509.1)
  • Bug 24423308 – SV12.2DBSA: ALTER SYSTEM RESET DOESN’T UPDATE PARAM VALUE IN PDB_SPFILE$@ROOT

 

 

Amazon Partner Link: