Data Guard per PDB bei Oracle 23ai
Überblick
In der traditionellen Oracle Data Guard Architektur hat eine Datenbank zu einem Zeitpunkt nur eine Rolle, z.B. Primary oder Physical Standby. Diese Architektur ist seit über 20 Jahren bewährte Oracle-Technologie und kann sowohl für NON-CDB wie auch für CDB Datenbanken eingesetzt werden. In Oracle Version 21.7 wurde die neue Data Guard per PDB Architektur für Containerdatenbanken eingeführt. Dabei kann eine CDB unterschiedliche Datenbankrollen besitzen, weil die Verwaltung der Datenbankrollen auf PDB Ebene erfolgt.
In diesem Blog werden die aktuellen Möglichkeiten und Grenzen dieser neuen Architektur an einem Beispiel unter Oracle 23ai gezeigt.
Voraussetzungen
Den Ausgangspunkt bilden zwei Containerdatenbanken mit den Namen “BOSTON” und “LONDON”.
Die CDB BOSTON enthält die User-PDB BOS_PDB1, die CDB LONDON enthält die User-PDB LON_PDB1.
Beide sind im Archivelog Mode und haben die Datenbankrolle “Primary”.
SYS@BOSTON:CDB$ROOT:> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
5 BOS_PDB1 READ WRITE NO
SYS@LONDON:CDB$ROOT:> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
5 LON_PDB1 READ WRITE NO
SYS@BOSTON:CDB$ROOT:> select log_mode, database_role from v$database;
LOG_MODE DATABASE_ROLE
------------ ----------------
ARCHIVELOG PRIMARY
SYS@LONDON:CDB$ROOT:> select log_mode, database_role from v$database;
LOG_MODE DATABASE_ROLE
------------ ----------------
ARCHIVELOG PRIMARY
1. Traditionelle Vorbereitung der CDBs für Data Guard
Folgende Eigenschaften werden bei beiden CDBs aktiviert:
- Force Logging
- automatische Anwendung von Strukturänderungen auf der Standby
- Flashback Database
- Start des Broker Hintergrundprozesses
- tnsnames.ora konfigurieren
SQL> alter database force logging;
SQL> alter system set standby_file_management=auto;
SQL> alter database flashback on;
SQL> alter system set dg_broker_start=true;
SQL> alter system set log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=boston';
$ cat $ORACLE_HOME/network/admin/tnsnames.ora
BOSTON =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = host01.domain)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = BOSTON)
)
)
LONDON =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = host02.domain)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = LONDON)
)
)
2. Passwortlose Konfiguration für CDBs
Für die Wallet Konfiguration muss ein Verzeichnis mit entsprechenden Rechten angelegt werden. In der sqlnet.ora werden die Wallet-Informationen konfiguriert. Anschließend wird mit mkstore ein Wallet angelegt und die Credentials zum Wallet hinzugefügt. Danach ist ein Neustart von CDBs und Listener erforderlich.
Jetzt funktioniert ein passwortloser Connect zu beiden CDBs.
$ WLTLOC=/home/oracle/wallets
$ mkdir -p $WALLETLOC
$ chmod -R 700 $WALLETLOC
-- Verzeichnis /home/oracle für Wallet sollte nur als Testumgebung verwendet werden
$ cat $ORACLE_HOME/network/admin/sqlnet.ora
...
WALLET_LOCATION= (SOURCE= (METHOD=file)
(METHOD_DATA= (DIRECTORY=/home/oracle/wallets)))
SQLNET.WALLET_OVERRIDE = TRUE
$ mkstore -wrl ${WALLETLOC} -create
Enter password: <wallet_passwort>
Enter password again: <wallet_passwort>
$ mkstore -wrl ${WALLETLOC} -createCredential boston sys <sys_passwort>
Enter wallet password: <wallet_passwort>
$ mkstore -wrl ${WALLETLOC} -createCredential london sys <sys_passwort>
Enter wallet password: <wallet_passwort>
$ mkstore -wrl ${WALLETLOC} -listCredential
Enter wallet password: <wallet_passwort>
List credential (index: connect_string username)
2: london sys
1: boston sys
-- CDBs durchstarten
SQL> shutdown immediate
SQL> startup
-- Listener durchstarten
$ lsnrctl stop
$ lsnrctl start
-- Test passwortfreie Verbindungen über Wallets
$ sqlplus /@boston as sysdba
$ sqlplus /@london as sysdba
3. Broker Konfiguration auf beiden CDBs anlegen
Zuerst wird eine Data Guard Konfiguration mit BOSTON als Primary Database angelegt. Anschließend wird eine zweite Data Guard Konfiguration mit LONDON als Primary Database angelegt. Diese zweite Konfiguration wird zur ersten Konfiguration hinzugefügt. Nach dem Aktivieren hat die Broker Konfiguration zwei Primary Databases. Das ist neu und war bis Oracle 19c nicht möglich.
$ dgmgrl /@boston
-- Erste Data Guard Konfiguration
DGMGRL> create configuration 'boston' as connect identifier is boston;
DGMGRL> show configuration
Configuration - boston
Protection Mode: MaxPerformance
Members:
boston - Primary database
Fast-Start Failover: Disabled
Configuration Status:
DISABLED
-- Zweite Data Guard Konfiguration
DGMGRL> connect /@london
Connected to "london"
Connected as SYSDBA.
DGMGRL> create configuration 'london' as connect identifier is
london;
DGMGRL> show configuration
Configuration - london
Protection Mode: MaxPerformance
Members:
london - Primary database
Fast-Start Failover: Disabled
Configuration Status:
DISABLED
-- Zusammenfügen beider Konfigurationen
DGMGRL> connect /@boston
DGMGRL> add configuration 'london' connect identifier is london;
DGMGRL> enable configuration all;
-- Jetzt gibt es 2 Primary Database
DGMGRL> show configuration
Configuration - boston
Protection Mode: MaxPerformance
Members:
boston - Primary database
london - Primary database in london configuration
Fast-Start Failover: Disabled
Configuration Status:
SUCCESS (status updated 8 seconds ago)
4. Initiales Setup für DGPDB
Mit dem folgenden Broker Befehl wird ein Passwort für den vordefinierten common Nutzer DGPDB_INT vergeben. Über diesen Nutzer und einen Datenbanklink erfolgt die interne Kommunikation zwischen beiden CDBs.
DGMGRL> edit configuration prepare dgpdb;
Enter password for DGPDB_INT account at boston: <password_interner_Nutzer>
Enter password for DGPDB_INT account at london: <password_interner_Nutzer>
Prepared Data Guard for Pluggable Database at london.
Prepared Data Guard for Pluggable Database at boston.
SQL> select username, common, con_id from cdb_users where username like '%DGPDB%';
USERNAME COMMON CON_ID
____________ _________ _________
DGPDB_INT YES 1
DGPDB_INT YES 5
5. PDBs hinzufügen zu DGPDB
Anfangs sind die PDBs noch ungeschützt und autark.
DGMGRL> show pluggable database BOS_PDB1 at BOSTON;
Pluggable database - BOS_PDB1 at BOSTON
Data Guard Role: Not Protected
DGMGRL> show pluggable database LON_PDB1 at LONDON;
Pluggable database - LON_PDB1 at LONDON
Data Guard Role: Not Protected
Jetzt werden die Target PDBs als Schutz der Source PDB hinzugefügt.
Im ersten Beispiel wird die PDB BOS_PDB1 zur CDB LONDON (als physical Standby PDB) hinzugefügt (Target), welche die BOS_PDB1 auf der CDB BOSTON (Primary PDB) absichert (Source).
DGMGRL> add pluggable database BOS_PDB1 at LONDON source is BOS_PDB1
at BOSTON pdbfilenameconvert is "'/BOSTON/BOS_PDB1/','/LONDON/BOS_PDB1/'";
Pluggable Database "BOS_PDB1" added
Im zweiten Beispiel wird die PDB LON_PDB1 zur CDB BOSTON (als physical Standby PDB) hinzugefügt (Target), welche die LON_PDB1 auf der CDB LONDON (Primary PDB) absichert (Source).
DGMGRL> add pluggable database LON_PDB1 at BOSTON source is LON_PDB1
at LONDON pdbfilenameconvert is "'/LONDON/LON_PDB1/','/BOSTON/LON_PDB1/'";
Pluggable Database "LON_PDB1" added
Die unterschiedlichen Ergebnisse liefert die Statusabfrage der PDB BOS_PDB1:
- BOS_PDB1 auf BOSTON ist Primary
- BOS_PDB1 auf LONDON ist physical Standby
Auf der Standby ist das Redo Apply noch nicht gestartet, deshalb erkennt man ein Transport- und Apply Lag. Analog umgekehrt sind die Ergebnisse für die PDB LON_PDB1.
DGMGRL> show pluggable database BOS_PDB1 at BOSTON;
Pluggable database - BOS_PDB1 at BOSTON
Data Guard Role: Primary
Con_ID: 5
Active Target: con_id 3 at LONDON
Pluggable Database Status:
SUCCESS
DGMGRL> show pluggable database BOS_PDB1 at LONDON;
Pluggable database - BOS_PDB1 at LONDON
Data Guard Role: Physical Standby
Con_ID: 3
Source: con_id 5 at BOSTON
Transport Lag: 7 minutes 3 seconds (computed 2 seconds ago)
Apply Lag: 7 minutes 3 seconds (computed 2 seconds ago)
Intended State: APPLY-ON
Apply State: Not Running
Pluggable Database Status:
ORA-16914: Redo Apply Services were not started at the standby pluggable database.
Jetzt müssen die PDB Dateien manuell übertragen werden. Das kann entweder mit dem RMAN duplicate Kommando oder mit scp erfolgen. In unserem Beispiel wird scp für die Übertragung von BOS_PDB1 genutzt. Analog erfolgt die Übertragung von LON_PDB1 in umgekehrter Richtung.
-- Auf Host mit CDB LONDON
$ mkdir -p /u01/app/oracle/oradata/LONDON/BOS_PDB1
-- Auf Host mit CDB BOSTON
$ sqlplus /@BOSTON as sysdba
SQL> alter session set container=BOS_PDB1;
SQL> alter database begin backup;
SQL> ! scp -r /u01/app/oracle/oradata/BOSTON/BOS_PDB1/* oracle@lehrvpc242:/u01/app/oracle/oradata/LONDON/BOS_PDB1
oracle@lehrvpc022's password: <oracle>
sysaux01.dbf 100% 620MB 110.0MB/s 00:05
system01.dbf 100% 310MB 96.5MB/s 00:03
temp01.dbf 100% 20MB 140.1MB/s 00:00
undotbs01.dbf 100% 100MB 98.6MB/s 00:01
users01.dbf 100% 465MB 148.0MB/s 00:03
SQL> alter database end backup;
Im Anschluss werden die Standby Redos zur Standby PDB hinzugefügt. Sie werden globaler Container Ebene angelegt (CON_ID=0).
Im folgenden werden die Statements für die physical Standby BOS_PDB1 auf der CDB LONDON gezeigt:
SQL> connect /@LONDON as sysdba
SQL> alter session set container=BOS_PDB1;
SQL> alter database add standby logfile thread 1
group 4 ('/u01/app/oracle/fast_recovery_area/LONDON/onlinelog/standby_redo04.log') size 200M,
group 5 ('/u01/app/oracle/fast_recovery_area/LONDON/onlinelog/standby_redo05.log') size 200M,
group 6 ('/u01/app/oracle/fast_recovery_area/LONDON/onlinelog/standby_redo06.log') size 200M,
group 7 ('/u01/app/oracle/fast_recovery_area/LONDON/onlinelog/standby_redo07.log') size 200M;
SQL> select GROUP#, status, con_id from v$standby_log;
GROUP# STATUS CON_ID
---------- ---------- ----------
4 UNASSIGNED 0
5 UNASSIGNED 0
6 UNASSIGNED 0
7 UNASSIGNED 0
$ dgmgrl /@LONDON
DGMGRL> VALIDATE PLUGGABLE DATABASE BOS_PDB1 AT LONDON;
Ready for Switchover: NO
Data Guard Role: Physical Standby
Apply State: Not Running
Standby Redo Log Files: 4
Source: BOS_PDB1 (con_id 5) at BOSTON
Analog werden die Standby Redo Logs für die physical Standby LON_PDB1 auf der CDB BOSTON hinzugefügt.
Jetzt kann das Redo Apply auf beiden Seiten gestartet werden.
DGMGRL> connect /@BOSTON
DGMGRL> edit pluggable database LON_PDB1 at BOSTON set state='APPLY-ON';
DGMGRL> edit pluggable database BOS_PDB1 at LONDON set state='APPLY-ON';
Damit ist der Konfigurationsprozess abgeschlossen und der Status der beiden Standby PDBs kann überprüft werden.
DGMGRL> show pluggable database LON_PDB1 at BOSTON
Pluggable database - LON_PDB1 at BOSTON
Data Guard Role: Physical Standby
Con_ID: 3
Source: con_id 5 at LONDON
Transport Lag: 0 seconds (computed 2 seconds ago)
Apply Lag: 0 seconds (computed 2 seconds ago)
Intended State: APPLY-ON
Apply State: Running
Apply Instance: BOSTON
Average Apply Rate: 9 KByte/s
Real Time Query: OFF
Pluggable Database Status:
SUCCESS
$ dgmgrl /@LONDON
DGMGRL> show pluggable database BOS_PDB1 at LONDON
Pluggable database - BOS_PDB1 at LONDON
Data Guard Role: Physical Standby
Con_ID: 3
Source: con_id 5 at BOSTON
Transport Lag: 0 seconds (computed 1 second ago)
Apply Lag: 0 seconds (computed 1 second ago)
Intended State: APPLY-ON
Apply State: Running
Apply Instance: LONDON
Average Apply Rate: 10 KByte/s
Real Time Query: OFF
Pluggable Database Status:
SUCCESS
Sowohl Transport Lag als auch Apply Lag sind 0, damit funktionieren sowohl Redo Log Übertragung wie auch Apply Prozess korrekt.
6. PDB Switchover

Bevor ein Switchover auf PDB Ebene erfolgen kann, muss geprüft werden, ob alle Voraussetzungen dafür erfüllt sind. Beim Switchover gibt es keinen Datenverlust, deshalb müssen Übertragung und Apply von Redo Logs fehlerfrei sein. Hier wird die Funktion der physical Standby PDB BOS_PDB1 auf LONDON geprüft.
DGMGRL> show pluggable database bos_pdb1 at LONDON
Pluggable database - BOS_PDB1 at LONDON
Data Guard Role: Physical Standby
Con_ID: 3
Source: con_id 5 at BOSTON
Transport Lag: 0 seconds (computed 0 second ago)
Apply Lag: 0 seconds (computed 0 second ago)
Intended State: APPLY-ON
Apply State: Running
Apply Instance: LONDON
Average Apply Rate: 8 KByte/s
Real Time Query: OFF
Pluggable Database Status:
SUCCESS
DGMGRL> validate pluggable database bos_pdb1 at LONDON
Ready for Switchover: YES
Data Guard Role: Physical Standby
Apply State: Running
Standby Redo Log Files: 4
Source: BOS_PDB1 (con_id 5) at BOSTON
Die Validierung ergab, dass die PDB BOS_PDB1 auf LONDON bereit ist für ein Switchover. Damit kann das Switchover erfolgen.
Nach ca. 13 Sekunden haben beide PDBs die Rollen getauscht.
DGMGRL> switchover to pluggable database bos_pdb1 at LONDON
Performing switchover NOW, please wait...
Switchover succeeded, new primary is "bos_pdb1"
–-> Ehemalige Standby PDB ist jetzt Primary PDB
DGMGRL> show pluggable database bos_pdb1 at LONDON;
Pluggable database - BOS_PDB1 at LONDON
Data Guard Role: Primary
Con_ID: 3
Active Target: con_id 5 at BOSTON
Pluggable Database Status:
SUCCESS
--> Ehemalige Primary PDB ist neue Standby PDB
DGMGRL> SHOW PLUGGABLE DATABASE bos_pdb1 at BOSTON;
Pluggable database - BOS_PDB1 at BOSTON
Data Guard Role: Physical Standby
Con_ID: 5
Source: con_id 3 at LONDON
Transport Lag: 0 seconds (computed 2 seconds ago)
Apply Lag: 0 seconds (computed 2 seconds ago)
Intended State: APPLY-ON
Apply State: Running
Apply Instance: BOSTON
Average Apply Rate: 12 KByte/s
Real Time Query: OFF
Pluggable Database Status:
SUCCESS
Danach wird durch PDB Switchover der Ausgangszustand wieder hergestellt.
DGMGRL> validate pluggable database bos_pdb1 at BOSTON
Ready for Switchover: YES
Data Guard Role: Physical Standby
Apply State: Running
Standby Redo Log Files: 4
Source: BOS_PDB1 (con_id 3) at LONDON
DGMGRL> switchover to pluggable database bos_pdb1 at BOSTON
Performing switchover NOW, please wait...
Switchover succeeded, new primary is "bos_pdb1"
DGMGRL> show pluggable database bos_pdb1 at LONDON
Pluggable database - BOS_PDB1 at LONDON
Data Guard Role: Physical Standby
Con_ID: 3
Source: con_id 5 at BOSTON
Transport Lag: 0 seconds (computed 6 seconds ago)
Apply Lag: 0 seconds (computed 6 seconds ago)
Intended State: APPLY-ON
Apply State: Running
Apply Instance: LONDON
Average Apply Rate: 14 KByte/s
Real Time Query: OFF
Pluggable Database Status:
SUCCESS
7. PDB Failover
Das Failover erfolgt ungeplant, weil eine Primary PDB nicht erreichbar oder fehlerhaft ist. Im Beispiel ist die BOS_PDB1 auf BOSTON “kaputt”. Ziel des Failovers ist möglichst aktuelle Standby PDB, hier erfolgt ein Failover auf die BOS_PDB1 auf LONDON.
DGMGRL> show pluggable database bos_pdb1 at LONDON
Pluggable database - BOS_PDB1 at london
Data Guard Role: Physical Standby
Con_ID: 3
Source: con_id 5 at boston
Transport Lag: 0 seconds (computed 1 second ago)
Apply Lag: 0 seconds (computed 1 second ago)
Intended State: APPLY-ON
Apply State: Running
Apply Instance: london
Average Apply Rate: 10 KByte/s
Real Time Query: OFF
Pluggable Database Status:
SUCCESS
DGMGRL> failover to pluggable database bos_pdb1 at LONDON
Performing failover NOW, please wait...
Failover succeeded, new primary is "bos_pdb1".
Nach dem PDB Failover ist die neue Primary PDB nicht geschützt.
DGMGRL> show pluggable database bos_pdb1 at LONDON
Pluggable database - BOS_PDB1 at london
Data Guard Role: Primary
Con_ID: 3
Active Target: con_id 5 at boston needs to be reinstated
Pluggable Database Status:
DGM-17450: not protected
Es gibt zwei Möglichkeiten, die neue Primary PDB wieder zu schützen:
- Neuaufbau einer neue Standby PDB wie bereits gezeigt
- Synchronisation der ehemaligen Primary PDB als neue Standby PDB (wenn möglich)
In unserem Fall ist eine Synchronisation möglich, nach dem Reinstate ist die neue Primary PDB wieder geschützt.
DGMGRL> reinstate pluggable database bos_pdb1 at BOSTON
Succeeded.
DGMGRL> show pluggable database bos_pdb1 at BOSTON
Pluggable database - BOS_PDB1 at boston
Data Guard Role: Physical Standby
Con_ID: 5
Source: con_id 3 at london
Transport Lag: 0 seconds (computed 2 seconds ago)
Apply Lag: 0 seconds (computed 2 seconds ago)
Intended State: APPLY-ON
Apply State: Running
Apply Instance: boston
Average Apply Rate: 1567 KByte/s
Real Time Query: OFF
Pluggable Database Status:
SUCCESS
DGMGRL> show pluggable database bos_pdb1 at LONDON
Pluggable database - BOS_PDB1 at london
Data Guard Role: Primary
Con_ID: 3
Active Target: con_id 5 at boston
Pluggable Database Status:
SUCCESS
Fazit und Zusammenfassung
Im diesem Blog wurde die Konfiguration der neuen Data Guard Funktionalität Data Guard per PDB (DGPDB) gezeigt. Bei Oracle 23ai kann eine CDB mit der Rolle Primary drei PDB Rollen enthalten:
- Primary PDB
- Physical Standby PDB
- autarke (ungeschützte) PDB (im Beispiel nicht konfiguriert)
DGMGRL> show all pluggable database at BOSTON
PDB Name PDB ID Data Guard Role Data Guard Partner
LON_PDB1 3 Physical Standby LON_PDB1 (con_id 5) at LONDON
BOS_PDB1 5 Primary BOS_PDB1 (con_id 3) at LONDON
DGMGRL> show all pluggable database at LONDON
PDB Name PDB ID Data Guard Role Data Guard Partner
BOS_PDB1 3 Physical Standby BOS_PDB1 (con_id 5) at BOSTON
LON_PDB1 5 Primary LON_PDB1 (con_id 3) at BOSTON
Das Umschalten der Rollen erfolgt nicht mehr auf CDB Ebene, sondern auf PDB Ebene.
Allerdings gibt es bei Oracle 23ai noch einige wesentliche Einschränkungen wie beispielsweise:
- nur Performance Mode möglich (kein Maximum Available, kein Maximum Protection)
- keine Snapshot Standby, keine Far Sync möglich
- nur 2 CDBs können integriert werden
- nur individuelle PDBs sind unterstützt
- keine Enterprise Manager Cloud Control Integration
Aufgrund der genannten Einschränkungen ist dieses innovative Konzept für Produktionsumgebungen derzeit noch nicht geeignet.
Weitere ausführliche Informationen zu Oracle Data Guard 19c finden Sie im Robotron-Praxisworkshop:Praxisworkshop Data Guard Administration Oracle 19c
Kommentare
Keine Kommentare