1. Start
  2. Unternehmen
  3. Blog
  4. Data Guard per PDB bei Oracle 23ai

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 BOSTONkaputt”. 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

Kommentar schreiben

* Diese Felder sind erforderlich