The fix 30577591 which is included in the DBRU 19.9 changed how the undo_retention parameter value is set in a CDB. Prior to this the value was set at CDB root level and all PDBs inherited this value. But with this change this is not the case. The value set at CDB root is only assigned to CDB root. For PDB this must be explicityly set either by login into the PDB or using "container=all" clause if setting at CDB root level and want the value to be inherited by all PDBs. This change has been mentioned here.
It seems Oracle has not foreseen the unintended consequence of this change. Mainly, how this would affect the standby databases. The database used in this case is using local undo.
Now open the CDB in read only mode.
Only workaround found so far is to set the value on the PDB to memory.
SR has been raised.
It seems Oracle has not foreseen the unintended consequence of this change. Mainly, how this would affect the standby databases. The database used in this case is using local undo.
SQL> select property_value from database_properties where property_name='LOCAL_UNDO_ENABLED';To demonstrate the issue at hand, assume the standby databases is in mount mode.
PROPERTY_VALUE
--------------------------------------------------------------------------------
TRUE
SQL> select ispdb_modifiable from v$parameter where name='undo_retention';
ISPDB
-----
TRUE
SQL> select open_mode from v$database;Current value for undo_retention is same for both cdb root and pdb and is the default 900.
OPEN_MODE
---------
MOUNTED
SQL> show con_nameSet the undo_retention parameter at CDB root level.
CON_NAME
------------------------------
CDB$ROOT
SQL> show parameter undo_retention
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 900
-- value at PDB
SQL> alter session set container=dgpdb;
Session altered.
SQL> show con_name
CON_NAME
------------------------------
DGPDB
SQL> show parameter undo_retention
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 900
SQL> show con_nameThis change appears to be applied on both CDB root and PDB level.
CON_NAME
------------------------------
CDB$ROOT
SQL> alter system set undo_retention=901 scope=both;
System altered.
SQL> show parameter undo_retentionValue appears to be set at PDB because at mounted state the PDB seem to inherit it from the CDB.
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 901
SQL> alter session set container=dgpdb;
Session altered.
SQL> show con_name
CON_NAME
------------------------------
DGPDB
SQL> show parameter undo_retention
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 901
Now open the CDB in read only mode.
SQL> select open_mode from v$database;The change reamins on the CDB root but is lost on the PDB.
OPEN_MODE
--------------------
READ ONLY WITH APPLY
show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 DGPDB READ ONLY NO
SQL> show con_nameTrying to set the value with container=all fails with the following.
CON_NAME
------------------------------
CDB$ROOT
SQL> show parameter undo_retention
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 901
SQL> alter session set container=dgpdb;
Session altered.
SQL> show con_name
CON_NAME
------------------------------
DGPDB
-- change not inherited by pdb
SQL> show parameter undo_retention
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 900
SQL> alter system set undo_retention=901 container=all scope=both;Trying to set it by login into PDB also fails.
alter system set undo_retention=901 container=all scope=both
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-16000: database or pluggable database open for read-only access
SQL> alter session set container=dgpdb;Reason for this is as undo_retention value is not inherited, it is kept as a local parameter of the PDB. To change this the new value must be written to the data dictionary (PDB_SPFILE$ table) this means writing it to the system tablespace where the pdb_spfile$ table resides. But for standby databases this cannot be done as writes are not allowed on standby.
Session altered.
SQL> show con_name
CON_NAME
------------------------------
DGPDB
SQL> alter system set undo_retention=901;
alter system set undo_retention=901
*
ERROR at line 1:
ORA-32000: write to SPFILE requested but SPFILE is not modifiable
Only workaround found so far is to set the value on the PDB to memory.
SQL> alter system set undo_retention=901 scope=memory;However, this means everytime there's a restart of the standby the change is lost and must be set again.
System altered.
SR has been raised.