Hierbei handelt es sich um nur eine Variante eine Standby-Datenbank zu erstellen.

In einem der nächsten Artikel werden wir eine Standby-Datenbank aus einem RMAN Backup erstellen.

Nach meiner Ansicht die wirklich einfachste Methode um eine „Physical-Standby“ Datenbank zu erstellen. Die Vorarbeit aus dem Artikel Template VM zahlt sich nun aus.

Was haben wir gemacht:

  • Eine VM mit RHEL 8 erstellt und die Pachtes installiert
  • Das Betriebssystem für die Verwendung von Oracle Datenbanken eingerichtet
  • Die Oracle Datenbank Binaries und die letzten RU’s (Patching 12.2c/18c/19c ...) installiert.

Die fertige Installation wird aus zwei Data Guard Knoten bestehen:

Hostname IP-Adresse DB_UNIQUE_NAME
demo-db1.demo.local 192.168.111.141 demo_db1
demo-db2.demo.local 192.168.111.142 demo_db2

 

 

 

 Der erste Schritt ist das Klonen der Template VM

Der Snapshot ist schon vorbereitet

Wir machen einen "Linked-Clone", hat primär Platzgründe. Für einen Live-Betrieb würde ich einen "Full-Clone" machen.

Damit wir die VM wiederfinden, trägt diese den Namen des Servers.

Das Provisionieren dauert nur eine Sekunde, da die Betriebssystemblöcke bei Bedarf kopiert werden.

 

Einrichtung Knoten 1 (demo-db1.demo.local)

Wie in Template VM beschrieben wird die IP-Adresse und der Hostname geändert.

Wir haben jetzt in 30 Sekunden einen Datenbank-Server mit den aktuellen RedHat und Oracle Patches bereitgestellt.

[oracle@demo-db1@] /home/oracle 
$ ifconfig
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.111.141  netmask 255.255.255.0  broadcast 192.168.111.255
        inet6 fe80::20c:29ff:fea4:3c9b  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:a4:3c:9b  txqueuelen 1000  (Ethernet)
        RX packets 106  bytes 10290 (10.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 154  bytes 16622 (16.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
...

[oracle@demo-db1@] /home/oracle 
$ hostname
demo-db1.demo.local

 

LISTENER einrichten

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = demo-db1.demo.local)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST = 
    (SID_DESC =
      (GLOBAL_DBNAME = DEMO_DB1_DGMGRL.demo.local)
      (ORACLE_HOME = /app/oracle/product/19c)
      (SID_NAME = DEMO)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = DEMO_DB1_DGB.demo.local)
      (ORACLE_HOME = /app/oracle/product/19c)
      (SID_NAME = DEMO)
    )
  )

LISTENER starten und den Status prüfen

[oracle@demo-db1@DEMO] /home/oracle 
$ lsnrctl status

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 22-DEC-2020 06:27:30

Copyright (c) 1991, 2020, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=demo-db1.demo.local)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production
Start Date                22-DEC-2020 06:27:22
Uptime                    0 days 0 hr. 0 min. 7 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /app/oracle/product/19c/network/admin/listener.ora
Listener Log File         /app/oracle/diag/tnslsnr/demo-db1/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=demo-db1.demo.local)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "DEMO_DB1_DGB.demo.local" has 1 instance(s).
  Instance "DEMO", status UNKNOWN, has 1 handler(s) for this service...
Service "DEMO_DB1_DGMGRL.demo.local" has 1 instance(s).
  Instance "DEMO", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully

 

 

Nur wird die Datenbank mit DBCA erstellt.

Die ORACLE_SID zeigt auf "DEMO"

[oracle@demo-db1@DEMO] /home/oracle 
$ echo $ORACLE_SID
DEMO

Nun kommen nurnoch die wichtigste Screenshots

 

 

Wir erstellen eine Container Datanbank

 

 

 

Anpassungen für die Standby Datenbank auf dem Knoten 1 (demo-db1.demo.local)

Standby Logfiles erzeugen

-- Vorab das Verzeichnis erstellen
mkdir -p /oradata/DEMO/redo_standby

-- Die Standby Logfiles müssen so groß wie die REDO-Logs sein!
alter database add standby logfile ('/oradata/DEMO/redo_standby/std01.log') size 200M;
alter database add standby logfile ('/oradata/DEMO/redo_standby/std02.log') size 200M;
alter database add standby logfile ('/oradata/DEMO/redo_standby/std03.log') size 200M;

alter system set standby_file_management=AUTO scope=both;

Force Logging aktivieren

ALTER DATABASE FORCE LOGGING;

Standby Controlfile erzeugen

ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/tmp/demo_stby.ctl';

LOG_FILE_NAME_CONVERT muss gesetzt werden, da sonst die Datenbank nicht funktioniert

ALTER SYSTEM SET log_file_name_convert='dummy','dummy' scope=spfile;

DB_FILE_NAME_CONVERT sollte auch gesetzt werden, hat jedoch bei unserer Konfiguration keinen Einfluss

ALTER SYSTEM SET  DB_FILE_NAME_CONVERT = 'dummy','dummy' scope=spfile;

DataGuard Broker starten

alter system set dg_broker_start=true scope=spfile; 

 

Einrichtung Knoten 2 (demo-db2.demo.local)

Auf demo-db1.demo.local wird ein Shutdown durchgeführt, im Anschluss wird die VM geklont.

Wir wollen wieder Platz sparen deshalb "linked clone"!

Die Bereitstellung ist wieder in einer Sekunde passiert.

Aktuell gibt es den Host und die IP doppelt, deshalb vorerst nur den 2 Knoten starten.

Nun wieder wie schon in Template VM beschrieben Hostname und IP-Adresse ändern.

  • /etc/hostname
  • /etc/sysconfig/network-scripts/ifcfg-ens160

Zur Sicherheit führen wir einen Restart des Knoten 2 durch.

Nach dem Restart nochmals prüfen ob alles so ist wie es sein soll.

[oracle@demo-db2@] /home/oracle 
$ hostname
demo-db2.demo.local
[oracle@demo-db2@] /home/oracle 
$ ifconfig
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.111.142  netmask 255.255.255.0  broadcast 192.168.111.255
        inet6 fe80::20c:29ff:fe5a:c5c3  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:5a:c5:c3  txqueuelen 1000  (Ethernet)
        RX packets 118  bytes 11412 (11.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 169  bytes 17554 (17.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
...

Nach dem Klonen darf die Datenbank auf den 2 Knoten nur im "MOUNT" Status geöffnet werden!

 

Listener anpasssen

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = demo-db2.demo.local)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = DEMO_DB2_DGMGRL.demo.local)
      (ORACLE_HOME = /app/oracle/product/19c)
      (SID_NAME = DEMO)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = DEMO_DB2_DGB.demo.local)
      (ORACLE_HOME = /app/oracle/product/19c)
      (SID_NAME = DEMO)
    )
  )

Tnsnames anpassen

DEMO =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = demo-db2.demo.local)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = demo.demo.local)
    )
  )

LISTENER_DEMO =
  (ADDRESS = (PROTOCOL = TCP)(HOST = demo-db2.demo.local)(PORT = 1521))

 Listener starten und den Status prüfen

[oracle@demo-db2@DEMO] /app/oracle/product/19c/network/admin 
$ lsnrctl status

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 22-DEC-2020 07:51:26

Copyright (c) 1991, 2020, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=demo-db2.demo.local)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production
Start Date                22-DEC-2020 07:51:21
Uptime                    0 days 0 hr. 0 min. 5 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /app/oracle/product/19c/network/admin/listener.ora
Listener Log File         /app/oracle/diag/tnslsnr/demo-db2/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=demo-db2.demo.local)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "DEMO_DB2_DGB.demo.local" has 1 instance(s).
  Instance "DEMO", status UNKNOWN, has 1 handler(s) for this service...
Service "DEMO_DB2_DGMGRL.demo.local" has 1 instance(s).
  Instance "DEMO", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully

 Auf der Standby Datenbank demo-db2.demo.local müssen die Controlfiles mit dem  Standby-Controlfile ersetzt werden.

Wir starten die Datenbank mit "nomount" und lassen uns die Namen und Speicherorte der Contorlfiles anzeigen.

SQL> startup nomount;
ORACLE instance started.

Total System Global Area 4982831824 bytes
Fixed Size		    9145040 bytes
Variable Size		  905969664 bytes
Database Buffers	 4060086272 bytes
Redo Buffers		    7630848 bytes
SQL> show parameter control

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
control_file_record_keep_time	     integer	 7
control_files			     string	 /oradata/DEMO/control01.ctl, /
						 oradata/fast_recovery_area/DEM
						 O/control02.ctl

Kopieren der Controlfies

oracle@demo-db2@DEMO] /tmp 
$ cp /tmp/demo_stby.ctl /oradata/DEMO/control01.ctl
[oracle@demo-db2@DEMO] /tmp 
$ cp /tmp/demo_stby.ctl /oradata/fast_recovery_area/DEMO/control02.ctl
[oracle@demo-db2@DEMO] /tmp

 

Die Konfiguration mit den Datenbank spezifischen Parametern

Nun sind bei Knoten gestartet, der Listener läuft ab beiden Knoten und die Datenbank ist im Status "MOUNT" geöffnet.

demo-db1.demo.local

alter system set db_unique_name=demo_db1 scope=spfile;

# Vorab das Verzeichnis erstellen!
alter system set db_recovery_file_dest='/oradata/fast_recovery_area/DEMO_DB1' scope=spfile;

demo-db2.demo.local

alter system set db_unique_name=demo_db2 scope=spfile;

# Vorab das Verzeichnis erstellen!
alter system set db_recovery_file_dest='/oradata/fast_recovery_area/DEMO_DB2' scope=spfile;

Nun kann die Datenbank auf dem Knoten 1 geöffnet werden.

Die Datenbank auf den Knoten 2 ist noch im mount Status.

Parameter prüfen!

demo-db1.demo.local

SQL> show parameter recovery

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest		     string	 /oradata/fast_recovery_area/DE
						 MO_DB1
db_recovery_file_dest_size	     big integer 12561M
recovery_parallelism		     integer	 0
remote_recovery_file_dest	     string
SQL> show parameter unique

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_unique_name			     string	 DEMO_DB1

demo-db2.demo.local

SQL> show parameter recovery

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest		     string	 /oradata/fast_recovery_area/DE
						 MO_DB2
db_recovery_file_dest_size	     big integer 12561M
recovery_parallelism		     integer	 0
remote_recovery_file_dest	     string
SQL> show parameter unique

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_unique_name			     string	 DEMO_DB2

 

DataGuard einrichten und starten

Die Tnsname.ora muss noch auf beiden Knoten erweitert werden

DG_DEMO_DB1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = demo-db1.demo.local)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = DEMO_DB1_DGMGRL.demo.local)
    )
  )

DG_DEMO_DB2 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = demo-db2.demo.local)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = DEMO_DB2_DGMGRL.demo.local)
    )
  )

 Auf beiden Knoten prüfen, ob beide TNS-Aliase erreichbar sind!

demo-db1.demo.local

oracle@demo-db1@DEMO] /app/oracle/product/19c/network/admin 
$ sqlplus sys/Oracle123@dg_demo_db1 as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Dec 22 08:20:51 2020
Version 19.9.0.0.0

Copyright (c) 1982, 2020, Oracle.  All rights reserved.


Verbunden mit: 
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.9.0.0.0

SQL> select host_name from v$instance;

HOST_NAME
----------------------------------------------------------------
demo-db1.demo.local

SQL> exit
Verbindung zu Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.9.0.0.0 beendet
[oracle@demo-db1@DEMO] /app/oracle/product/19c/network/admin 
$ sqlplus sys/Oracle123@dg_demo_db2 as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Dec 22 08:21:07 2020
Version 19.9.0.0.0

Copyright (c) 1982, 2020, Oracle.  All rights reserved.


Verbunden mit: 
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.9.0.0.0

SQL> select host_name from v$instance;

HOST_NAME
----------------------------------------------------------------
demo-db2.demo.local

SQL>

 

demo-db2.demo.local

[oracle@demo-db2@DEMO] /app/oracle/product/19c/network/admin 
$ sqlplus sys/Oracle123@dg_demo_db1 as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Dec 22 08:22:48 2020
Version 19.9.0.0.0

Copyright (c) 1982, 2020, Oracle.  All rights reserved.


Verbunden mit: 
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.9.0.0.0

SQL> select host_name from v$instance;

HOST_NAME
----------------------------------------------------------------
demo-db1.demo.local

SQL> exit
Verbindung zu Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.9.0.0.0 beendet
^[[A[oracle@demo-db2@DEMO] /app/oracle/product/19c/network/admin 
$ sqlplus sys/Oracle123@dg_demo_db2 as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Dec 22 08:23:02 2020
Version 19.9.0.0.0

Copyright (c) 1982, 2020, Oracle.  All rights reserved.


Verbunden mit: 
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.9.0.0.0

SQL> select host_name from v$instance;

HOST_NAME
----------------------------------------------------------------
demo-db2.demo.local

SQL>

 

Den DataGuard Broker einrichten

[oracle@demo-db1@DEMO] /app/oracle/product/19c/network/admin 
$ dgmgrl sys/Oracle123@DG_DEMO_DB1
DGMGRL for Linux: Release 19.0.0.0.0 - Production on Tue Dec 22 08:26:18 2020
Version 19.9.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Welcome to DGMGRL, type "help" for information.
Connected to "DEMO_DB1"
Connected as SYSDBA.
DGMGRL> create configuration DEMO as primary database is demo_db1 connect identifier is DG_DEMO_DB1;
Configuration "demo" created with primary database "demo_db1"
DGMGRL> add database demo_db2 as connect identifier is DG_DEMO_DB2 maintained as physical ;
Database "demo_db2" added
DGMGRL> edit database demo_db1 set property 'logxptmode' ='sync' ;
Property "logxptmode" updated
DGMGRL> edit database demo_db2 set property 'logxptmode' ='sync' ;
Property "logxptmode" updated
DGMGRL>  enable configuration ;
Enabled.
### Die ersten paar Sekunden können Fehler kommen!!!
### Ein "alter system switch logfile;" hilft in der Regel
DGMGRL> show configuration;

Configuration - demo

  Protection Mode: MaxPerformance
  Members:
  demo_db1 - Primary database
    demo_db2 - Physical standby database 

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS   (status updated 25 seconds ago)

 

Switchover zurm DEMO_DB2

GMGRL> switch over to demo_db2;
Unrecognized command "switch", try "help"
DGMGRL> swtichover to demo_db2;
Unrecognized command "swtichover", try "help"
DGMGRL> switchover to demo_db2;
Performing switchover NOW, please wait...
Operation requires a connection to database "demo_db2"
Connecting ...
Connected to "DEMO_DB2"
Connected as SYSDBA.
New primary database "demo_db2" is opening...
Operation requires start up of instance "DEMO" on database "demo_db1"
Starting instance "DEMO"...
Connected to an idle instance.
ORACLE instance started.
Connected to "DEMO_DB1"
Database mounted.
Connected to "DEMO_DB1"
Switchover succeeded, new primary is "demo_db2"
DGMGRL>
###DEMO_DB2
SQL> select host_name, status, DATABASE_STATUS, INSTANCE_ROLE ,INSTANCE_MODE from v$instance;

HOST_NAME							 STATUS
---------------------------------------------------------------- ------------
DATABASE_STATUS   INSTANCE_ROLE      INSTANCE_MO
----------------- ------------------ -----------
demo-db2.demo.local						 OPEN
ACTIVE		  PRIMARY_INSTANCE   REGULAR


SQL> select DATABASE_ROLE from v$database;

DATABASE_ROLE
----------------
PRIMARY

SQL> 


###DEMO_DB1
SQL> select host_name, status, DATABASE_STATUS, INSTANCE_ROLE ,INSTANCE_MODE from v$instance;

HOST_NAME							 STATUS
---------------------------------------------------------------- ------------
DATABASE_STATUS   INSTANCE_ROLE      INSTANCE_MO
----------------- ------------------ -----------
demo-db1.demo.local						 MOUNTED
ACTIVE		  PRIMARY_INSTANCE   REGULAR


SQL> select DATABASE_ROLE from v$database;

DATABASE_ROLE
----------------
PHYSICAL STANDBY

SQL> 

 

Schlusswort

Natürlich habe ich vor jedem wichtigen Schritt einen Snapshot der VM gemacht.

Wir wollen ja die Vorteile voll und ganz nutzen und im Fehlerfall eine einfache Fallback-Möglichkeit haben.

 

Fazit: Mit der richtigen Methode kann man in unter 30 Minuten eine komplette DataGuard Datenbank erstellen.