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
- Einrichtung Knoten 1 (demo-db1.demo.local)
- Anpassungen für die Standby Datenbank
- Einrichtung Knoten 2 (demo-db2.demo.local)
- Spezifische Datenbank-Parameter
- DataGuard einrichten und starten
- Schlusswort
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.