Risiken beim Umbenennen von Pluggable Databases (PDB)

By | 4. Januar 2021

Die mit Oracle 12.1 eingeführte Multitenant Architektur birgt die großartige Möglichkeit, den Namen einer erstellten Pluggable Database (PDB) nachträglich zu ändern. Gegenüber der Umbenennung einer Nicht-Multitenant- bzw. Container-Datenbank (CDB) ist dies eine relativ einfache Sache, die jedoch mit einigen Risiken verbunden ist und daher mit Vorsicht durchgeführt werden sollte. Gründe für eine Umbenennung kann es viele geben. Möglicherweise stellt sich ein bei der Erstellung der PDB gewählter Name im Nachhinein als unpassend heraus oder man möchte den Service-Namen der PDB, welcher sich vom Namen der PDB ableitet und über den sich die Clients mit der Datenbank verbinden, ändern.

In diesem Artikel werde ich nicht nur das übliche Verfahren für das Umbenennen einer PDB beschreiben, sondern insbesondere auch die mir bekannten Gefahren und Probleme aufzeigen, die damit einhergehen könnten.

Umbenennen einer PDB

Das Umbenennen einer Pluggable Database wird durch das Ändern des globalen Namens der PDB herbeigeführt. Der globale Name bezieht sich auf den vollständigen Namen einer Datenbank (einschließlich ihrer Domäne), der sie von jeder anderen Datenbank eindeutig unterscheiden soll. Ein Beispiel für einen globalen Namen ist pdbtom.example.de. Insbesondere bei kleineren Organisationen ist es allergings nicht unüblich, dass man auf den Domänen-Teil verzichtet. Erwähnenswert ist, dass man in einer CDB keine zweite PDB mit gleichem Namen haben kann, selbst wenn man eine andere Domäne für die zweite PDB wählt. Im nachfolgenden Beispiel verzichte ich zur Vereinfachung auf die Verwendung der Domäne als Bestandteil des globalen Namens.

An die CDB mit einen priviligierten Account, z.B. SYS anmelden

sqlplus / as sysdba

PDB in den Restricted Mode setzen

SQL> alter pluggable database PDBTOM close immediate;
SQL> alter pluggable database PDBTOM open restricted;

In die PDB wechseln

SQL> alter session set container = PDBTOM;

PDB umbenennen (Hier von PDBTOM in PDBJOE)

SQL> alter database rename global_name to PDBJOE;

Die PDB wieder öffnen

SQL> alter pluggable database PDBJOEclose;
SQL> alter pluggable database PDBJOE open;
SQL> alter pluggable database PDBJOE open save state;

 

Mögliche Probleme durch das Umbenennen

1.) Doppelte Service-Registrierung bei gemeinsam genutzten Listenern

Vor dem Ändern des Namens der PDB sollte man sich sicher sein, dass der neue Name nicht mit dem Namen einer anderen Datenbank identisch ist, die denselben Listener nutzt. Ein gemeinsam genutzter Listener kann dabei ein „Local Listener“ oder ein „Remote Listener“, wie er z.B. in einem Oracle Cluster (SCAN-Listener) oder bei einem Oracle Connection Manager (CMAN) verwendet wird, sein.

Der Service-Namen einer PDB registriert sich automatisch an den für die PDB konfigurierten Local-Listener und ggf. einem weiteren Remote-Listener – selbst wenn sich die PDB nur im Status Mount befindet! Dies hat zur Folge, dass ein und derselbe Service-Name zweimal beim Listener registriert ist. Dies wiederum birgt die Gefahr, dass sich eine Anwendung, die sich unter Verwendung des Service-Namen und des Listeners mit der Datenbank verbindet, sich mal mit der einen und mal mit der anderen Datenbank verbindet. Dies ist in der Regel unerwünscht, da dies zu inkonsistenten Daten führen kann! Die gleiche Gefahr besteht natürlich auch, wenn man weitere, benutzerdefinierte Services in einer Datenbank nutzt oder PDBs klont.

Vorbeugung: Vor dem Umbenennen einer Datenbank sollte man sicherstellen, dass der PDB-Name nicht von einer anderen Datenbank, die einen gemeinsamen Listener nutzt, verwendet wird (lsnrctl status). Grundsätzlich empfehle ich, dass ein verwendeter Datenbank- und Service-Name immer eindeutig sein sollte, sprich einmalig in der gesamten Organisation ist. Dies beugt Verwechselungen und damit einhergehende Fehler vor.

 

lsnrctl status
....
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=ora1srv)(PORT=1521)))
Services Summary...

Service "pdbjoe" has 2 instance(s).
Instance "cdb1", status READY, has 2 handler(s) for this service...
Instance "cdb2", status READY, has 2 handler(s) for this service...
The command completed successfully

2.)  Zeichensatz-Problem bei Nicht-Unicode-PDBs in Unicode-CDBs

Auf das nachfolgende Problem, für welches derzeit noch keine MOS-Note in der Oracle Knowledge Base existiert, bin ich im Rahmen einer kürzlich durchgeführten Migration gestoßen. Ab Version 12.2 ist es bekanntermaßen möglich, dass man in einer CDB, die mit dem Unicode-Zeichensatz AL32UTF8 erstellt wurde, auch PDBs mit anderen (Nicht-Unicode)-Zeichensätzen, z.B. WE8ISO88P15 betreiben kann. Damit soll dem Konsolidierungsgedanken besser Rechnung getragen werden. In einer Unicode-CDB kann man zwar keine PDB mit einem abweichenden Zeichensatz erstellen, man kann aber eine PDB mit einem abweichenden Zeichensatz z.B. via PDB Cloning dort „hinein-pluggen“ und dann betreiben. Oracle empfiehlt zwar grundsätzlich eine Migration der PDB zu Unicode, dies ist aber nicht immer in der Praxis aufgrund von fehlendem Support der Anwendungshersteller möglich.

Problem: Wenn man nun eine PDB, die einen von der Unicode-CDB abweichenden Zeichensatz hat, umbenennt, dann funktioniert die normalerweise stattfindende Zeichensatzkonvertierung zwischen Client und PDB nicht mehr! Als Folge werden z.B. falsche Werte für die Anzahl der verwendeten Bytes oder die Anzahl der verwendeten Zeichen von Zeichenketten zum Client zurückgegeben. Ein fehlerfreier Betrieb der Anwendung ist so nicht mehr gewährleistet.
Ich vermute hier einen Oracle Bug und habe das Problem dem Oracle Support gemeldet. Ich konnte das Verhalten bei mehreren Oracle Versionen einschließlich dem aktuellsten 19.9 Release reproduzieren. Betroffen sind vermutlich alle Versionen.

Das nachfolgende Beispiel zeigt die fehlende Zeichsatzkonvertierung zwischen einem Client und einer PDB nach Umbenennung einer PDB mit dem Zeichensatz WE8ISO88P15. Die CDB läuft auf Linux und hat den Unicode Zeichensatz  AL32UTF8. Der Client ist ein Oracle SQL Developer, der unter Windows läuft und naturgemäß den JDBC-Thin Treiber verwendet.

Beispiel-Abfrage Umlaut-Zeichen (Ä) im Oracle SQL Developer

select 'Ä' Character, rawtohex('Ä') HEXCODE, lengthb('Ä') Byte_Length, lengthc('Ä') Character_Length from dual;

Korrekte Interpretation vor Umbenennung der PDB

CHARACTER HEXCODE  BYTE_LENGTH CHARACTER_LENGTH 
--------- -------- ----------- ---------------- 
        Ä       C4           1                1

Fehlerhafte Interpretation nach Umbenennung der PDB

CHARACTER HEXCODE BYTE_LENGTH CHARACTER_LENGTH 
--------- -------- ----------- ---------------- 
       Ã?     C384           2                2

Der Zeichensatz der PDB hat sich übrigens mit der Umbenennung der PDB nicht verändert. Woher die Falschinterpretation kommt, ist unklar.

select parameter database_parameter, value from nls_database_parameters where parameter in ('NLS_CHARACTERSET');
DATABASE_PARAMETER  VALUE 
------------------- ------------------ 
NLS_CHARACTERSET    WE8ISO8859P15

Vorbeugung: Unicode-Migration oder Unbenennung in der Unicode-CDB vermeiden

Eine PDB, die einen von der CDB abweichenden Zeichensatz hat, sollte man entweder nach dem Plugin nicht mehr umbenennen oder die PDB zu Unicode migrieren. Denkbar ist auch, dass man die PDB bereits in der Quell-CDB umbenennt.

 

3.)  Vom PDB-Namen abweichende Pfadnamen

Wenn kein Oracle Managed Files (OMF) bei der Erstellung einer PDB verwendet wird (Parameter db_create_file_dest nicht gesetzt), dann enthalten die Pfadnamen der zur PDB zugehörigen Datenbankfiles nach der Umbenennung weiterhin in Gestalt eines Unterverzeichnisses den alten Namen der PDB. Das Unterverzeichnis wird also nicht umbenannt. Dies ist nicht nur unschön und verwirrend, sondern birgt auch die Gefahr, dass das Unterverzeichnis wiederverwendet wird, wenn man eine PDB mit dem alten Namen erstellt.

Beispiel Pfadnamen nach Umbenennung der PDB von PDBJOE nach PDBTOM, wenn kein OMF verwendet wird

In die PDB wechseln

SQL> alter session set container = PDBJOE;

Anzeige Pfadnamen der Datenbankdateien

SQL> select name from v$datafile union select name from v$tempfile;

Die Pfade beinhalten weiterhin den alten PDB-Namen PDBTOM

NAME
--------------------------------------------------------------------------------
/u01/oradata/cdb1/pdbtom/sysaux01.dbf
/u01/oradata/cdb1/pdbtom/system01.dbf
/u01/oradata/cdb1/pdbtom/temp01.dbf
/u01/oradata/cdb1/pdbtom/undotbs01.dbf
/u01/oradata/cdb1/pdbtom/users01.dbf

Lösung: Datafiles und Tempfiles auf Betriebssystemebene verschieben

Mit der Verschiebung und Umbenennung der Datenbankdateien korrigiert man den Umstand, dass die Datenbankdateien der umbenannten PDB im „falschen“ Verzeichnis liegen. Im folgenden Teil habe ich exemplarisch beschrieben, wie man dies mit dem „Alter-Database-Rename-File“-Verfahren erreichen kann. Im Gegensatz zum „Alter-Database-Move-Datafile“-Verfahren, welches auch im geöffneten Zustand der PDB funktioniert und der Schritt des Verschiebens wegfällt, funktioniert dieses auch in der Oracle Standard Edition!

PDB schließen

SQL> alter pluggable database PDBJOE close immediate;
SQL> exit

Neues PDB-Verzeichnis anlegen

mkdir /u02/oradata/cdb419/pdbjoe

Datenbankdateien auf Betriebssystemebene in das neue Verzeichnis verschieben

mv /u01/oradata/cdb1/pdbtom/sysaux01.dbf /u01/oradata/cdb1/pdbjoe
mv /u01/oradata/cdb1/pdbtom/system01.dbf /u01/oradata/cdb1/pdbjoe
mv /u01/oradata/cdb1/pdbtom/undotbs01.dbf /u01/oradata/cdb1/pdbjoe
mv /u01/oradata/cdb1/pdbtom/users01.dbf /u01/oradata/cdb1/pdbjoe
mv /u01/oradata/cdb1/pdbtom/temp01.dbf /u01/oradata/cdb1/pdbjoe

Alte PDB-Verzeichnis löschen

rmdir /u01/oradata/cdb1/pdbtom

Datenbankdateien in der CDB umbenennen

SQL> alter database rename file '/u01/oradata/cdb1/pdbtom/sysaux01.dbf' to '/u01/oradata/cdb1/pdbjoe/sysaux01.dbf';
SQL> alter database rename file '/u01/oradata/cdb1/pdbtom/system01.dbf' to '/u01/oradata/cdb1/pdbjoe/system01.dbf';
SQL> alter database rename file '/u01/oradata/cdb1/pdbtom/undotbs01.dbf' to '/u01/oradata/cdb1/pdbjoe/undotbs01.dbf';
SQL> alter database rename file '/u01/oradata/cdb1/pdbtom/users01.dbf' to '/u01/oradata/cdb1/pdbjoe/users01.dbf';
SQL> alter database rename file '/u01/oradata/cdb1/pdbtom/temp01.dbf' to '/u01/oradata/cdb1/pdbjoe/temp01.dbf';

PDB wieder öffnen

SQL> alter pluggable database PDBJOE open;

Pfad-Kontrolle

SQL> alter session set container = PDBJOE;
SQL> select name from v$datafile union select name from v$tempfile;
NAME
--------------------------------------------------------------------------------
/u01/oradata/cdb1/pdbjoe/sysaux01.dbf
/u01/oradata/cdb1/pdbjoe/system01.dbf
/u01/oradata/cdb1/pdbjoe/temp01.dbf
/u01/oradata/cdb1/pdbjoe/undotbs01.dbf
/u01/oradata/cdb1/pdbjoe/users01.dbf

Empfehlung: OMF verwenden

Ich bin ein großer Freund von der Verwendung von Oracle Managed Files (OMF) und empfehle grundsätzlich das Feature zu nutzen, da es die Arbeit des DBA ungemein vereinfacht und sich solche Probleme vermeiden lassen. Wenn OMF genutzt wird, enthalten die Pfade nicht den Namen der PDB sondern stattdessen den Globally Unique Identifier (GUID). Die GUID ist eine 32-stellige hexadezimale Kennung, die für jede PDB eindeutig ist und sich auch nach Umbenennung der PDB nicht verändert.

Beispiel PDB-Pfade bei Verwendung OMF

SQL> alter session set container = PDBJOE;
 SQL> select name from v$datafile union select name from v$tempfile;
NAME
--------------------------------------------------------------------------------------------
/u01/oradata/CDB1/B6E77261ACDE337FE0530738A8C0C80B/datafile/o1_mf_sysaux_hxys6fm9_.dbf
/u01/oradata/CDB1/B6E77261ACDE337FE0530738A8C0C80B/datafile/o1_mf_system_hxys6fm9_.dbf
/u01/oradata/CDB1/B6E77261ACDE337FE0530738A8C0C80B/datafile/o1_mf_temp_hxys6fmb_.dbf
/u01/oradata/CDB1/B6E77261ACDE337FE0530738A8C0C80B/datafile/o1_mf_undotbs1_hxys6fm9_.dbf
/u02/oradata/CDB1/B6E77261ACDE337FE0530738A8C0C80B/datafile/o1_mf_users_hxys765n_.dbf

4.) Parallel Query Funktioniert im RAC nicht mehr

Parallele Abfragen (PQO) in einer RAC-Datenbank funktionieren nach Umbenennung der PDB nicht mehr. Betroffen sind die Oracle Versionen 18.1 – 19.6.
Lösung: Uprade auf mindesten 19.6

 

Relevante MOS Notes