Multitenant: Einhängen einer Non-CDB mit einem höheren Patchstand

8. Juli 2024 Aus Von Markus Flechtner

Neben dem Remote-Cloning einer Non-CDB in eine CDB mit einer anderen Einstellung bei MAX_STRING_SIZE ist das Einhängen oder Remote-Clonen einer Non-CDB in eine CDB mit höherem Patchstand eine Aufgabe, die man Alltag schon mal öfter hat, wenn seine Systeme nicht auf einem einheitlichen Patchstand halten konnte. Schauen wir uns doch mal an, wie dieser Sonderfall funktioniert.

Ausgangssituation

Quelle: Non-CDB NCDB1907:

Versionsstand:

oracle@kiwi:~/ [NCDB1907] $ORACLE_HOME/OPatch/opatch lspatches
30805684;OJVM RELEASE UPDATE: 19.7.0.0.200414 (30805684)
30869156;Database Release Update : 19.7.0.0.200414 (30869156)
29585399;OCW RELEASE UPDATE 19.3.0.0.0 (29585399)

OPatch succeeded.

Parameter MAX_STRING_SIZE

SQL> show parameter max_string_size

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------
max_string_size 		     string	 EXTENDED

(Der Parameter ist für den Test nicht relevant, aber dieser Post ist im Kontext von dem Blog-Post „MAX_STRING_SIZE und Remote Cloning einer Non-CDB“ entstanden.

Ziel: Container-Datenbank CDB1921:

Versionsstand:

oracle@kiwi:~/ [CDB1921] $ORACLE_HOME/OPatch/opatch lspatches
35787077;DATAPUMP BUNDLE PATCH 19.21.0.0.0
35648110;OJVM RELEASE UPDATE: 19.21.0.0.231017 (35648110)
35643107;Database Release Update : 19.21.0.0.231017 (35643107)
29585399;OCW RELEASE UPDATE 19.3.0.0.0 (29585399)

OPatch succeeded.
SQL> show parameter max_string_size

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------
max_string_size 		     string	 STANDARD

Schritt 1: „CREATE PLUGGABLE DATABASE“-Recht in der Non-CDB vergeben

Der Benutzer, mit dem sich der Datenbank-Link an der Non-CDB anmeldet, muss dort das „CREATE PLUGGABLE DATABASE“-Recht bekommen:

SQL> grant create pluggable database to system;
Grant succeeded.

Schritt 2: Datenbank-Link von der CDB in die Non-CDB anlegen (und testen)

SQL> create database link NCDB1907
  2  connect to system identified by manager
  3  using 'localhost:1521/NCD1907';
Database link created.

SQL> select * from dual@NCDB1907;

D
-
X

Schritt 3: Datenbank-Dateien kopieren

create pluggable database PDB1907 from NON$CDB@NCDB1907
  2  file_name_convert=
  3  ('/u01/oradata/NCDB1907','/u01/oradata/CDB1921/PDB1907')
  4  ;
Pluggable database created.

Ergebnis:

SQL> show pdbs
    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ WRITE NO
	 4 PDB1907			  MOUNTED

Schritt 4: Dictionary-Konvertierung

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

SQL> spool 1907to1921.log

SQL> @?/rdbms/admin/noncdb_to_pdb.sql
Session altered.

SQL>
SQL> -- leave the PDB in the same state it was when we started
SQL> BEGIN
  2    execute immediate '&open_sql &restricted_state';
  3  EXCEPTION
  4    WHEN OTHERS THEN
  5    BEGIN
  6      IF (sqlcode <> -900) THEN
  7        RAISE;
  8      END IF;
  9    END;
 10  END;
 11  /

PL/SQL procedure successfully completed.

SQL>
SQL> WHENEVER SQLERROR CONTINUE;
SQL> spool off

Schritt 5: PDB öffnen

Wenn man jetzt die PDB öffnen will, dann meldet die Datenbank einen Fehler:

SQL> alter pluggable database pdb1907 open;
Warning: PDB altered with errors.
SQL> show pdbs
    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ WRITE NO
	 4 PDB1907			  READ WRITE YES

Die PDB ist zwar geöffnet, aber nur im Restricted-Mode. Woran das liegt, zeigt der Blick auf die View PDB_PLUG_IN_VIOLATIONS:

SQL> select message,action from pdb_plug_in_violations where status <> 'RESOLVED';

MESSAGE
--------------------------------------------------------------------------
ACTION
--------------------------------------------------------------------------
Interim patch 35648110/25365038 (OJVM RELEASE UPDATE: 19.21.0.0.231017 (35648110
)): Installed in the CDB but not in the PDB
Call datapatch to install in the PDB or the CDB

Interim patch 35787077/25410019 (DATAPUMP BUNDLE PATCH 19.21.0.0.0): Installed i
n the CDB but not in the PDB
Call datapatch to install in the PDB or the CDB

Interim patch 30805684/23401476 (OJVM RELEASE UPDATE: 19.7.0.0.200414 (30805684)
): Not installed in the CDB but installed in the PDB
Call datapatch to install in the PDB or the CDB

'19.21.0.0.0 Release_Update 2309301519' is installed in the CDB but '19.7.0.0.0
Release_Update 2004040350' is installed in the PDB
Call datapatch to install in the PDB or the CDB

4 rows selected.

Wie erwartet, hat Oracle bemerkt, dass die neue PDB noch den Versionsstand 19.07 hat und dass die Patches des Release-Updates 19.21 noch in der PDB eingespielt werden müssen.

Schritt 6: datapatch ausführen

Mit dem Parameter „-pdbs“ kann datapatch für einzelne PDBs ausgeführt werden.

oracle@kiwi:~/ [CDB1921] /u00/app/oracle/product/19.21-ee/OPatch/datapatch -verbose -pdbs PDB1907
SQL Patching tool version 19.21.0.0.0 Production on Mon Jul  8 18:25:17 2024
Copyright (c) 2012, 2023, Oracle.  All rights reserved.

Log file for this invocation: /u00/app/oracle/cfgtoollogs/sqlpatch/sqlpatch_49934_2024_07_08_18_25_17/sqlpatch_invocation.log

Connecting to database...OK
[...]
Validating logfiles...done
Patch 30805684 rollback (pdb PDB1907): SUCCESS
  logfile: /u00/app/oracle/cfgtoollogs/sqlpatch/30805684/23401476/30805684_rollback_CDB1921_PDB1907_2024Jul08_18_25_45.log (no errors)
Patch 35643107 apply (pdb PDB1907): SUCCESS
  logfile: /u00/app/oracle/cfgtoollogs/sqlpatch/35643107/25405995/35643107_apply_CDB1921_PDB1907_2024Jul08_18_25_56.log (no errors)
Patch 35648110 apply (pdb PDB1907): SUCCESS
  logfile: /u00/app/oracle/cfgtoollogs/sqlpatch/35648110/25365038/35648110_apply_CDB1921_PDB1907_2024Jul08_18_25_56.log (no errors)
Patch 35787077 apply (pdb PDB1907): SUCCESS
  logfile: /u00/app/oracle/cfgtoollogs/sqlpatch/35787077/25410019/35787077_apply_CDB1921_PDB1907_2024Jul08_18_29_32.log (no errors)

Die Datenbank ist allerdings immer noch „nur“ im Restricted-Modus geöffnet, d.h. wir schließen und öffnen sie einmal:

SQL> show pdbs
    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ WRITE NO
	 4 PDB1907			  READ WRITE YES

SQL> alter pluggable database pdb1907 close;
Pluggable database altered.

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

SQL> show pdbs
    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ WRITE NO
	 4 PDB1907			  READ WRITE NO

Schritt 7: Kontrolle

SQL> set pagesize 100
SQL> column comp_name format a40
SQL> column version_full format a20
SQL> column con$name format a10

SQL> select comp_name,version_full,status from cdb_registry where con$name='PDB1907';

COMP_NAME				 VERSION_FULL	      STATUS
---------------------------------------- -------------------- -----------
Oracle Database Catalog Views		 19.21.0.0.0	      VALID
Oracle Database Packages and Types	 19.21.0.0.0	      INVALID
Oracle Real Application Clusters	 19.21.0.0.0	      OPTION OFF
JServer JAVA Virtual Machine		 19.21.0.0.0	      VALID
Oracle XDK				 19.21.0.0.0	      VALID
Oracle Database Java Packages		 19.21.0.0.0	      VALID
OLAP Analytic Workspace 		 19.21.0.0.0	      VALID
Oracle XML Database			 19.21.0.0.0	      VALID
Oracle Workspace Manager		 19.21.0.0.0	      VALID
Oracle Text				 19.21.0.0.0	      VALID
Oracle Multimedia			 19.21.0.0.0	      VALID
Spatial 				 19.21.0.0.0	      INVALID
Oracle OLAP API 			 19.21.0.0.0	      VALID
Oracle Label Security			 19.21.0.0.0	      VALID
Oracle Database Vault			 19.21.0.0.0	      VALID

15 rows selected.

Zwei Komponenten sind „INVALID“. Dieses Problem können wir aber mittels „utlrp.sql“ lösen:

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

SQL> @?/rdbms/admin/utlrp.sql
[...]
Function created.

PL/SQL procedure successfully completed.

Function dropped.

PL/SQL procedure successfully completed.

Ergebnis:

SQL> select comp_name,version_full,status from cdb_registry where con$name='PDB1907';

COMP_NAME				 VERSION_FULL	      STATUS
---------------------------------------- -------------------- ------------
Oracle Database Catalog Views		 19.21.0.0.0	      VALID
Oracle Database Packages and Types	 19.21.0.0.0	      VALID
Oracle Real Application Clusters	 19.21.0.0.0	      OPTION OFF
JServer JAVA Virtual Machine		 19.21.0.0.0	      VALID
Oracle XDK				 19.21.0.0.0	      VALID
Oracle Database Java Packages		 19.21.0.0.0	      VALID
OLAP Analytic Workspace 		 19.21.0.0.0	      VALID
Oracle XML Database			 19.21.0.0.0	      VALID
Oracle Workspace Manager		 19.21.0.0.0	      VALID
Oracle Text				 19.21.0.0.0	      VALID
Oracle Multimedia			 19.21.0.0.0	      VALID
Spatial 				 19.21.0.0.0	      VALID
Oracle OLAP API 			 19.21.0.0.0	      VALID
Oracle Label Security			 19.21.0.0.0	      VALID
Oracle Database Vault			 19.21.0.0.0	      VALID

15 rows selected.

Und „MAX_STRING_SIZE“ wurde übrigens auch korrekt übernommen:

SQL> column value format a30
SQL> select con_id,value from v$system_parameter where name='max_string_size';

    CON_ID VALUE
---------- ------------------------------
	 0 STANDARD
	 4 EXTENDED

Zusammengefasst:

Einhängen oder „Remote Cloning“ einer Non-CDB$ in eine CDB mit einem höheren Patch-Stand ist möglich. Ähnlich wie bei einer Patch-Einspielung muss auch hier der Patch in der neuen PDB mittels „datapatch“ installiert werden. Die nach der Patch-Einspielung ungültigen Komponenten können einfach mittels „utlrp.sql“ validiert werden; dieser Schritt ist ansonsten nicht erforderlich, aber ich gehöre zu den DBAs, die diesen Schritt ohnehin nach jeder Patch-Einspielung machen. Daher empfehle ich es meinen Kunden auch immer „utlrp.sql“ und die anschließende Kontrolle via CDB_REGISTRY in ihre Patch-Prozeduren mit aufzunehmen.