
Manchmal enthält die Java-Anwendungskonfiguration die "primäre" IP-Adresse des Datenbankservers, die sich beispielsweise in den folgenden Fällen ändern kann:
- Kontrollierter Wechsel der Datenbankrollen. "Primär" wird zu "Standby" und umgekehrt wird "Standby" zu "Primär". Dieser Vorgang wird üblicherweise als "Umschaltung" bezeichnet.
- Notfallwechsel der "Standby" -Rolle in "Primär". Dies wird allgemein als "Failover" bezeichnet.
In beiden Fällen muss die Anwendung nicht nur die IP-Adresse des neuen "Primär" -Servers "kennen", sondern bei Bedarf auch darauf zugreifen können. Im Folgenden finden Sie eine Kurzanleitung zur Verwendung des Oracle Universal Connection Pool (UCP) sowie eine "Switchover" -Demo.
Für das Experiment werden wir verwenden:
- MacBook mit 16 GB RAM (mehr als 8 GB für das Experiment erforderlich)
- Virtual Box Version 6.1.12
- 2x virtuelle Maschinen (im Folgenden VM) mit CentOS 7 Minimal , von denen jede hat
- 2x vCPU
- 2048 GB RAM (vorübergehend bis zu 8 GB nacheinander)
- 40 GB Festplatte
- Audio deaktiviert, um 100% CPU-Auslastung zu vermeiden
- Oracle-Datenbank 19c
Befolgen wir diese Schritte:
- Virtuelle Maschinen konfigurieren
- Oracle installieren
- Oracle-Replikation
- Installieren und Konfigurieren von Oracle Grid
- "Switchover" Java

Wir erstellen virtuelle Maschinen (im Folgenden VMs) mit dem Typ Linux Red Hat. Wenn Virtual Box gestartet wird, werden Sie aufgefordert, die ISO auszuwählen, von der aus die VM gestartet werden soll (im Experiment wird CentOS-7-x86_64-Minimal-1908.iso verwendet). Belassen Sie alles standardmäßig, starten Sie es neu, aktualisieren Sie es, installieren Sie "Virtual Box Guest Additions" und deaktivieren Sie die Firewall, damit sie nicht im Weg steht. "Jeder weiß, wie die Politur gelöscht wird", daher stellen wir nur fest, dass wir nach dem Aktualisieren von VMs ihre Netzwerkschnittstellen vom NAT-Adapter auf den "virtuellen Hostadapter" vboxnet0 umstellen. Stellen Sie für diesen Adapter, der in Virtual Box-Tools erstellt werden kann, die Adresse 192.168.56.1/24 manuell ein und deaktivieren Sie DHCP. Grundsätzlich ist dies die IP-Adresse des Standard-Gateways für VMs und die Adresse der Java-Anwendung. Nur zur Klarheit. Und wenn Sie unter CentOS noch Internet benötigen,dann können Sie NAT unter macOS aktivieren::
- Wechseln Sie mit dem Befehl 'sudo su -' zu root.
- Erlauben Sie die Verkehrsumleitung mit dem Befehl 'sysctl -w net.inet.ip.forwarding = 1'.
- Fügen Sie den Inhalt der Datei /etc/pf.conf zur Datei /var/root/pfnat.conf hinzu, in die anstelle von Zeile 3 die Regel für NAT eingefügt wird:
nat on enX von vboxnet0: Netzwerk zu einem beliebigen -> (enX)
Dabei ist enX der Name der Netzwerkschnittstelle mit der Standardroute. - Führen Sie den Befehl 'pfctl -f pfnat.conf -e' aus, um die Paketfilterregeln zu aktualisieren.
Die Schritte 2 bis 4 können in einem Befehl ausgeführt werden.
sysctl -w net.inet.ip.forwarding=1 \
&& grep -v -E -e '^#.*' -e '^$' /etc/pf.conf | head -n2 > pfnat.conf \
&& INET_PORT=$(netstat -nrf inet | grep default | tr -s ' ' | cut -d ' ' -f 4) \
&& echo "nat on ${INET_PORT} from vboxnet0:network to any -> (${INET_PORT})" >> pfnat.conf \
&& grep -v -E -e '^#.*' -e '^$' /etc/pf.conf | tail -n+3 >> pfnat.conf \
&& pfctl -f pfnat.conf -e
Fügen Sie / etc / hosts aller VMs einheitliche Einträge hinzu, damit sie sich gegenseitig nach Domänennamen "pingen" können.
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.78 oracle1.localdomain oracle1
192.168.56.79 oracle2.localdomain oracle2
Oracle installieren

Wir führen die Installation "Nur Software" auf oracle1 und oracle2 mit RPM- Paketen durch , deren Verzeichnis von MacOS über Virtual Box (Maschine-> Einstellungen-> Freigegebener Ordner) freigegeben werden kann.
yum -y localinstall oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm
yum -y localinstall oracle-database-ee-19c-1.0-1.x86_64.rpm
Als Nächstes erstellen wir eine DBMS-Instanz auf der VM "oracle1". Führen Sie dazu das entsprechende Skript unter dem Benutzer oralce aus.
/etc/init.d/oracledb_ORCLCDB-19c configure
Dieser Vorgang dauert einige Zeit. Fügen Sie nach dem Erstellen einer Instanz auf beiden Hosts die folgenden Zeilen zur Datei /home/oracle/.bash_profile hinzu:
export ORACLE_HOME="/opt/oracle/product/19c/dbhome_1"
export ORACLE_BASE="/opt/oracle"
export ORACLE_SID="ORCLCDB"
export PATH=$PATH:$ORACLE_HOME/bin
Nun, wir konfigurieren ssh auch so, dass Sie sofort eine Verbindung als Oracle-Benutzer herstellen können. Wir stellen über ssh eine Verbindung zum Host her und stellen unter dem Oracle-Benutzer eine Verbindung zur Datenbank her.
user@macbook:~$ ssh oracle@oracle1
Last login: Wed Aug 12 16:17:05 2020
[oracle@oracle1 ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Wed Aug 12 16:19:44 2020
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL>
Eigentlich Oracle. Für das Experiment müssen wir auch die Replikation einrichten.
Oracle-Replikation.

Um die Replikation einzurichten, verwenden wir eine leicht modifizierte Anweisung :
- Wir übertragen die Datenbank auf dem oracle1-Server in den "Archivierungsmodus". Führen Sie dazu die Befehle in sqlplus aus:
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN; - Aktivieren Sie "Protokollierung erzwingen" auf dem oracle1-Server, ohne sqlplus zu verlassen.
ALTER DATABASE FORCE LOGGING;
ALTER SYSTEM SWITCH LOGFILE; - Erstellen Sie "Redo Log" -Dateien auf dem oracle1-Server.
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 10 ('/opt/oracle/oradata/ORCLCDB/standby_redo01.log') SIZE 209715200;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 11 ('/opt/oracle/oradata/ORCLCDB/standby_redo02.log') SIZE 209715200;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 12 ('/opt/oracle/oradata/ORCLCDB/standby_redo03.log') SIZE 209715200;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 13 ('/opt/oracle/oradata/ORCLCDB/standby_redo04.log') SIZE 209715200; - Aktivieren Sie "FLASHBACK" auf dem oracle1-Server. Ohne das funktioniert es nicht.
SQL> host
[oracle @ oracle1 ~] $ mkdir / opt / oracle / recovery_area
[oracle @ oracle1 ~] $ exit
SQL> System ändern set db_recovery_file_dest_size = 2g scope = both;
SQL> alter system set db_recovery_file_dest = '/ opt / oracle / recovery_area' scope = both;
SQL> ALTER DATABASE FLASHBACK ON; - Wir aktivieren etwas Automatisches auf dem oracle1 Server.
SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;
- tnsnames.ora listener.ora oracle1 oracle2 :
oracle1, $ORACLE_HOME/network/admin/tnsnames.oraLISTENER_ORCLCDB = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521)) ORCLCDB = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521)) ) (CONNECT_DATA = (SID = ORCLCDB) ) ) ORCLCDB_STBY = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521)) ) (CONNECT_DATA = (SID = ORCLCDB) ) )
oracle1, $ORACLE_HOME/network/admin/listener.oraLISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521)) (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) ) SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = ORCLCDB_DGMGRL) (ORACLE_HOME = /opt/oracle/product/19c/dbhome_1) (SID_NAME = ORCLCDB) ) ) ADR_BASE_LISTENER = /opt/oracle
oracle2, $ORACLE_HOME/network/admin/tnsnames.oraLISTENER_ORCLCDB = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521)) ORCLCDB = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521)) ) (CONNECT_DATA = (SID = ORCLCDB) ) ) ORCLCDB_STBY = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521)) ) (CONNECT_DATA = (SID = ORCLCDB) ) )
oracle2, $ORACLE_HOME/network/admin/listener.oraLISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521)) (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) ) SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = ORCLCDB_STBY_DGMGRL) (ORACLE_HOME = /opt/oracle/product/19c/dbhome_1) (SID_NAME = ORCLCDB) ) ) ADR_BASE_LISTENER = /opt/oracle
- oracle1
listener-.
[oracle@oracle1 ~]$ lsnrctl reload
[oracle@oracle1 ~]$ lsnrctl status
LSNRCTL for Linux: Version 19.0.0.0.0 — Production on 15-AUG-2020 08:17:24
Copyright © 1991, 2019, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle1.localdomain)(PORT=1521)))
STATUS of the LISTENER
— Alias LISTENER
Version TNSLSNR for Linux: Version 19.0.0.0.0 — Production
Start Date 15-AUG-2020 08:09:57
Uptime 0 days 0 hr. 7 min. 26 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /opt/oracle/product/19c/dbhome_1/network/admin/listener.ora
Listener Log File /opt/oracle/diag/tnslsnr/oracle1/listener/alert/log.xml
Listening Endpoints Summary…
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracle1.localdomain)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=oracle1.localdomain)(PORT=5500))(Security=(my_wallet_directory=/opt/oracle/admin/ORCLCDB/xdb_wallet))(Presentation=HTTP)(Session=RAW))
Services Summary…
Service «ORCLCDB» has 1 instance(s).
Instance «ORCLCDB», status READY, has 1 handler(s) for this service…
Service «ORCLCDBXDB» has 1 instance(s).
Instance «ORCLCDB», status READY, has 1 handler(s) for this service…
Service «ac8d8d741e3e2a52e0534e38a8c0602d» has 1 instance(s).
Instance «ORCLCDB», status READY, has 1 handler(s) for this service…
Service «orclpdb1» has 1 instance(s).
Instance «ORCLCDB», status READY, has 1 handler(s) for this service…
The command completed successfully
( Data Guard: ORCLCDB_DGMGRL)[oracle@oracle1 ~]$ lsnrctl status
LSNRCTL for Linux: Version 19.0.0.0.0 — Production on 15-AUG-2020 08:17:32
Copyright © 1991, 2019, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle1.localdomain)(PORT=1521)))
STATUS of the LISTENER
— Alias LISTENER
Version TNSLSNR for Linux: Version 19.0.0.0.0 — Production
Start Date 15-AUG-2020 08:09:57
Uptime 0 days 0 hr. 7 min. 34 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /opt/oracle/product/19c/dbhome_1/network/admin/listener.ora
Listener Log File /opt/oracle/diag/tnslsnr/oracle1/listener/alert/log.xml
Listening Endpoints Summary…
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracle1.localdomain)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=oracle1.localdomain)(PORT=5500))(Security=(my_wallet_directory=/opt/oracle/admin/ORCLCDB/xdb_wallet))(Presentation=HTTP)(Session=RAW))
Services Summary…
Service «ORCLCDB» has 1 instance(s).
Instance «ORCLCDB», status READY, has 1 handler(s) for this service…
Service «ORCLCDBXDB» has 1 instance(s).
Instance «ORCLCDB», status READY, has 1 handler(s) for this service…
Service «ORCLCDB_DGMGRL» has 1 instance(s).
Instance «ORCLCDB», status UNKNOWN, has 1 handler(s) for this service…
Service «ac8d8d741e3e2a52e0534e38a8c0602d» has 1 instance(s).
Instance «ORCLCDB», status READY, has 1 handler(s) for this service…
Service «orclpdb1» has 1 instance(s).
Instance «ORCLCDB», status READY, has 1 handler(s) for this service…
The command completed successfully - SYS oracle1.
SQL> alter user sys identified by "pa_SSw0rd";
- oracle2 listener .
[oracle@oracle2 ~]$ lsnrctl start
[oracle@oracle2 ~]$ orapwd file=$ORACLE_BASE/product/19c/dbhome_1/dbs/orapwORCLCDB entries=10 password=pa_SSw0rd
[oracle@oracle2 ~]$ echo "*.db_name='ORCLCDB'" > /tmp/initORCLCDB_STBY.ora
[oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/oradata/ORCLCDB/pdbseed
[oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/oradata/ORCLCDB/ORCLPDB1
[oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/admin/ORCLCDB/adump
[oracle@oracle2 ~]$ mkdir /opt/oracle/recovery_area
[oracle@oracle2 ~]$ sqlplus / as sysdba
SQL> STARTUP NOMOUNT PFILE='/tmp/initORCLCDB_STBY.ora'
[oracle@oracle2 ~]$ rman TARGET sys/pa_SSw0rd@ORCLCDB AUXILIARY sys/pa_SSw0rd@ORCLCDB_STBY
RMAN> DUPLICATE TARGET DATABASE FÜR STANDBY AUS AKTIVER DATENBANK DORECOVER SPFILE SET db_unique_name = 'ORCLCDB_STBY' COMMENT 'Ist Standby' NOFILENAMECHECK; - Starten Sie Data Guard auf beiden Servern (oracle1 und oracle2).
SQL> ALTER SYSTEM SET dg_broker_start = true;
- Stellen Sie auf dem oracle1-Server eine Verbindung zur Data Guard-Verwaltungskonsole her und erstellen Sie eine Konfiguration.
[oracle @ oracle1 ~] $ dgmgrl sys / pa_SSw0rd @ ORCLCDB
DGMGRL> KONFIGURATION ERSTELLEN my_dg_config ALS PRIMÄRE DATENBANK IST ORCLCDB CONNECT IDENTIFIER IST ORCLCDB;
DGMGRL> ADD DATABASE ORCLCDB_STBY ALS CONNECT IDENTIFIER IST ORCLCDB_STBY ALS PHYSIKALISCH WARTET;
DGMGRL> Konfiguration aktivieren;
Als Ergebnis der Erstellung eines Replikats und der Aktivierung von Data Guard haben wir den folgenden Status:
DGMGRL> show configuration
Configuration - my_dg_config
Protection Mode: MaxPerformance
Members:
orclcdb - Primary database
orclcdb_stby - Physical standby database
Warning: ORA-16854: apply lag could not be determined
Fast-Start Failover: Disabled
Configuration Status:
WARNING (status updated 40 seconds ago)
Dies ist ein schlechter Zustand. Warten wir ein wenig ...
DGMGRL> show configuration
Configuration - my_dg_config
Protection Mode: MaxPerformance
Members:
orclcdb - Primary database
orclcdb_stby - Physical standby database
Fast-Start Failover: Disabled
Configuration Status:
SUCCESS (status updated 55 seconds ago)
Jetzt ist der Staat gut! Das Replikat ist jedoch sehr passiv und akzeptiert keine Leseanforderungen (OPEN MODE: MOUNTED).
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED MOUNTED
3 ORCLPDB1 MOUNTED
Lassen Sie uns das Replikat aktivieren, damit es Leseanforderungen akzeptiert. Dann können wir in Zukunft den Server mit der "primären" Basis entladen. Dies wird als "Active Data Guard" oder aktiver Standby bezeichnet . Führen Sie auf dem oracle2-Server die folgende Befehlsfolge in sqlplus aus:
alter database
recover managed standby database cancel;
alter database open;
alter database
recover managed standby database
using current logfile
disconnect from session;
alter pluggable database all open;
Jetzt können Sie aus dem Replikat lesen (OFFENER MODUS: NUR LESEN):
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCLPDB1 READ ONLY NO
Und in der DataGuard-Konsole auf dem oracle1-Server sieht alles gut aus:
DGMGRL> show configuration;
Configuration - my_dg_config
Protection Mode: MaxPerformance
Members:
orclcdb - Primary database
orclcdb_stby - Physical standby database
Fast-Start Failover: Disabled
Configuration Status:
SUCCESS (status updated 19 seconds ago)
Trotz der Tatsache, dass Data Guard jetzt aktiv ist, ist der Cluster immer noch weitgehend passiv. Er wird uns und unserer erstaunlichen Java-Anwendung immer noch kein Wort sagen, dass Primary nicht mehr Primary ist. Dazu muss ein anderer Dienst, ONS (Oracle Notification Services), auf den Clusterservern ausgeführt werden. Die Installation von Oracle Database reicht anscheinend nicht aus, um diesen Dienst auszuführen. Wir müssen Oracle Grid installieren.
Installieren und Konfigurieren von Oracle Grid.

Hier ist alles ganz einfach: Wie bei der Installation von Oracle Database folgen wir einfach den offiziellen Anweisungen .
- oracle1 oracle2 root Oracle Grid, gcc-c++, oracle asm. Virtual Box, Oracle, Oracle Grid .
mkdir -p /opt/oracle/product/19c/grid \ && cp -r /mnt/oracle_grid_19300/LINUX/* /opt/oracle/product/19c/grid/ \ && chown -R oracle:oinstall /opt/oracle/product/19c/grid
yum install -y gcc-c++
groupadd asm && usermod -aG asm oracle
- , oracle, Oracle Grid.
cd /opt/oracle/product/19c/grid/ && ./runcluvfy.sh stage -pre hacfg
Verifying Physical Memory ...FAILED
Required physical memory = 8GB
Verifying Swap Size ...FAILED
Required = 2.6924GB (2823138.0KB); Found = 2GB (2097148.0KB)]
- , swap, Oracle Grid , . - oracle2, oracle1.
SQL> shutdown immediate
# poweroff
- oracle1 8192 , VM swap root.
dd if=/dev/zero of=/swap_file bs=1G count=7 \ && chmod 600 /swap_file && mkswap /swap_file \ && echo '/swap_file swap swap defaults 0 0' >> /etc/fstab \ && swapoff -a && swapon -a - , , .
[oracle@oracle1 grid]$ cd /opt/oracle/product/19c/grid/ && ./runcluvfy.sh stage -pre hacfg
Pre-check for Oracle Restart configuration was successful.
! Oracle Grid. - oracle oracle1 /opt/oracle/product/19c/grid/ grid_configwizard.rsp.
cd /opt/oracle/product/19c/grid/ && touch grid_configwizard.rsp
grid_configwizard.rsp , oracle restart, ASM .
oracle.install.responseFileVersion=/oracle/install/rspfmt_crsinstall_response_schema_v19.0.0
INVENTORY_LOCATION=/opt/oracle/oraInventory
oracle.install.option=CRS_SWONLY
ORACLE_BASE=/opt/oracle
oracle.install.asm.OSDBA=oinstall
oracle.install.asm.OSASM=asm
oracle.install.asm.SYSASMPassword=oracle
oracle.install.asm.diskGroup.name=data
oracle.install.asm.diskGroup.redundancy=NORMAL
oracle.install.asm.diskGroup.AUSize=4
oracle.install.asm.diskGroup.disksWithFailureGroupNames=/dev/sdb
- oracle grid .
./gridSetup.sh -silent \ -responseFile /opt/oracle/product/19c/grid/grid_configwizard.rsp - , oracle grid root, .
/opt/oracle/product/19c/grid/root.sh - , oracle restart root roothas.sh.
cd /opt/oracle/product/19c/grid/crs/install/ && ./roothas.sh
- oracle runInstaller.
cd /opt/oracle/product/19c/grid/oui/bin/ \ && ./runInstaller -updateNodeList \ ORACLE_HOME=/opt/oracle/product/19c/grid \ -defaultHomeName CLUSTER_NODES= CRS=TRUE - oracle1 /etc/fstab , /swap_file, 2048 RAM.
- " Oracle Grid" VM oracle2.
- , , Oracle Restart. oracle1 oracle Oracle Restart.
srvctl add database -db ORCLCDB \ -oraclehome /opt/oracle/product/19c/dbhome_1 \ -role PRIMARY
/opt/oracle/product/19c/grid/bin/crsctl modify \ res ora.cssd -attr "AUTO_START=always" -unsupported
/opt/oracle/product/19c/grid/bin/crsctl stop has
/opt/oracle/product/19c/grid/bin/crsctl start has - oracle2 oracle Oracle Restart.
/opt/oracle/product/19c/grid/bin/crsctl modify \ res ora.cssd -attr "AUTO_START=always" -unsupported
/opt/oracle/product/19c/grid/bin/crsctl stop has
/opt/oracle/product/19c/grid/bin/crsctl start has
srvctl add database -db ORCLCDB_STBY \ -oraclehome /opt/oracle/product/19c/dbhome_1 \ -role PHYSICAL_STANDBY \ -spfile /opt/oracle/product/19c/dbhome_1/dbs/spfileORCLCDB.ora \ -dbname ORCLCDB -instance ORCLCDB - Fügen Sie auf beiden Servern, oracle1 und oracle2, unter dem Benutzer oracle einen Listener zur Oracle Restart-Konfiguration hinzu.
srvctl add listener - Fügen Sie auf dem oracle1-Server unter dem Benutzer oracle der Konfiguration hinzu und starten Sie den Datenbankdienst ORCLCDB.
srvctl add service -db ORCLCDB -service orclpdb -l PRIMARY -pdb ORCLPDB1
srvctl start service -db ORCLCDB -service orclpdb - Fügen Sie auf dem oracle2-Server unter dem Benutzer oracle den Datenbankdienst ORCLCDB_STBY zur Konfiguration hinzu und starten Sie die Datenbankinstanz
srvctl add service -db ORCLCDB_STBY -service orclpdb -l PRIMARY -pdb ORCLPDB1
srvctl start database -db ORCLCDB_STBY - Starten Sie auf dem Server oracle1 und oracle2 den Dienst ons.
srvctl enable ons
srvctl start ons
Demo "Switchover" in einer Java-Testanwendung

Infolgedessen verfügen wir über 2 Oracle-Server mit Replikation im aktiven Standby-Modus und Ons-Dienst, an die Switch-Ereignisse gesendet werden, und die Java-Anwendung kann diese Ereignisse bei ihrem Eintreffen verarbeiten.
Erstellen wir einen Testbenutzer und eine Tabelle in Oracle.
oracle1 oracle sqlplus
sqlplus / as sysdbaalter session set container=ORCLPDB1;CREATE USER testus IDENTIFIED BY test DEFAULT TABLESPACE USERS QUOTA UNLIMITED ON USERS;GRANT CONNECT, CREATE SESSION, CREATE TABLE TO testus;CREATE TABLE TESTUS.MESSAGES (TIMEDATE TIMESTAMP, MESSAGE VARCHAR2(100));
Nach dem Erstellen eines Testbenutzers und einer Tabelle stellen wir eine Verbindung zum oracle2-Server her und "öffnen" die Instanz zum Lesen, um sicherzustellen, dass die Replikation funktioniert.
[oracle@oracle2 ~]$ sqlplus / as sysdba
SQL> alter pluggable database all open;
SQL> alter session set container=ORCLPDB1;
SQL> column table_name format A10;
SQL> column owner format A10;
SQL> select table_name, owner from dba_tables where owner like '%TEST%';
TABLE_NAME OWNER
---------- ----------
MESSAGES TESTUS
Die Testanwendung besteht nur aus einer Klasse Main. In einer Schleife versucht sie, einen Datensatz zur Testtabelle hinzuzufügen und dann denselben Datensatz zu lesen (siehe die Methoden "putNewMessage ()" und "getLastMessage ()"). Es gibt auch die Methode "getConnectionHost ()", die vom Objekt "connection" unter Verwendung der "Reflection API" die IP-Adresse der Verbindung zur Datenbank abruft. Wie Sie in der Konsole sehen können, ändert sich diese Adresse nach dem "Umschalten".
Starten Sie die Testanwendung und führen Sie die "Umschaltung" in der Data Guard-Konsole aus.
DGMGRL> switchover to orclcdb_stby;
Wir sehen, wie sich die IP-Adresse der Verbindung im Anwendungsprotokoll ändert. Die Ausfallzeit beträgt 1 Minute:
[Wed Aug 26 23:56:55 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:55| ?
[Wed Aug 26 23:56:56 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:56| ?
[Wed Aug 26 23:56:57 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:57| ?
[Wed Aug 26 23:56:58 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:02 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:06 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:10 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:14 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:18 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:23 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:27 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:31 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:35 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:39 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:43 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:47 MSK 2020]: SQLException: - !
[Wed Aug 26 23:57:51 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:52| ?
[Wed Aug 26 23:57:53 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:53| ?
[Wed Aug 26 23:57:54 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:54| ?
Schalten Sie zurück, um sicherzugehen.
DGMGRL> switchover to orclcdb;
Die Situation ist symmetrisch.
[Wed Aug 26 23:58:54 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:58:54| ?
[Wed Aug 26 23:58:55 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:58:55| ?
[Wed Aug 26 23:58:56 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:00 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:04 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:08 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:12 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:16 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:20 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:24 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:28 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:32 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:36 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:40 MSK 2020]: SQLException: - !
[Wed Aug 26 23:59:44 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:59:45| ?
[Wed Aug 26 23:59:46 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:59:46| ?
Achten wir auch auf die TCP-Verbindungen auf den Hosts oralce1 und oracle2. Der Datenport ist nur auf dem primären Port mit Verbindungen belegt, der ONS-Port ist sowohl auf dem primären als auch auf dem Replikat belegt.
Vor der Umstellung.
oracle1
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22"
ESTAB 0 0 192.168.56.78:1521 192.168.56.1:49819 users:(("oracle_21115_or"...))
ESTAB 0 0 192.168.56.78:1521 192.168.56.1:49822 users:(("oracle_21117_or"...))
ESTAB 0 0 [::ffff:192.168.56.78]:6200 [::ffff:192.168.56.1]:49820 users:(("ons"...))
oracle2
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22"
ESTAB 0 0 [::ffff:192.168.56.79]:6200 [::ffff:192.168.56.1]:49821 users:(("ons"...))
Nach der Umstellung.
oracle1
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v 22 Wed Aug 26 16:57:57 2020
ESTAB 0 0 [::ffff:192.168.56.78]:6200 [::ffff:192.168.56.1]:51457 users:(("ons"...))
oracle2
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22" Wed Aug 26 16:58:35 2020
ESTAB 0 0 192.168.56.79:1521 192.168.56.1:52259 users:(("oracle_28212_or"...))
ESTAB 0 0 192.168.56.79:1521 192.168.56.1:52257 users:(("oracle_28204_or"...))
ESTAB 0 0 [::ffff:192.168.56.79]:6200 [::ffff:192.168.56.1]:51458 users:(("ons"...))
Fazit
Daher haben wir einen Data Guard-Cluster in einer Laborumgebung mit einer minimalen Anzahl von Einstellungen simuliert und eine Failover-Verbindung einer Test-Java-Anwendung implementiert. Jetzt wissen wir, was der Entwickler vom DBA und den DBA vom Entwickler will. Es bleibt noch zu starten und zu testen, aber möglicherweise im Rahmen eines separaten Artikels.