Erzeugen einer Physikalischen Standby Datenbank für Oracle Standard Edition
Auch mit der Oracle Standard Edition ist es möglich einen Datenschutz mit einer Physikalischen Standby Datenbank aufzubauen. Die Dataguard Features mit dem automatisierten Log Shipping sind jedoch nur in der Enterprise Edition verfügbar, weshalb wir unsere Archive Logs von der der Primär Datenbank mithilfe eines Rsync Jobs zur Standby DB übertragen müssen.
Ausgangsszenario unter Oracle Linux 8 ist eine mit dem DBCA frisch erstellte DB mit der SID tl1. Die Standby DB werden wir über ein rman duplicate Komando für uns passend erstellen.
Unsere Umgebung für unsere Oracle DB ist wie folgt installiert worden:
ORACLE_BASE=/oracle ORACLE_HOME=/oracle/product/19.0.0/dbhome_1 ORA_INVENTORY=/home/oracle/oraInventory |
1. Die Primär Datenbank in den Archivelog Modus bringen.
SQL> shutdown immediate; SQL> startup mount; SQL> alter database archivelog; SQL> alter database open; SQL> alter system switch logfile; SQL> archive log list; |
2. Das force logging auf der Primär Datenbank implementieren.
alter database force logging; |
3. Erstellen der Standby Datenbank Control Datei
ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/oracle/product/19.0.0/dbhome_1/dbs/stbycf.ctl'; |
4. Erzeugen der Standby Datenbank
Es wird wird ein zweites Oracle Linux 8 System für die Standby Datenbank installiert.
Die Oracle Software wird wie auf der Primären in denselben Pfad installiert.
5. Erzeugen der Dateien listener, tnsname.ora auf der Primären und Standby DB.
listener.ora techlab1
# listener.ora Network Configuration File: /oracle/product/19.0.0/dbhome_1/network/admin/listener.ora # Generated by Oracle configuration tools. SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = tl1) (ORACLE_HOME = /oracle/product/19.0.0/dbhome_1) (SID_NAME = tl1) ) ) LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = techlab1.techlab.local)(PORT = 1521)) ) (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) ) ADR_BASE_LISTENER = /oracle |
tnsnames.ora techlab 1
Der Eintrag UR=A hilft uns auch bei einer Datenbank im mount status mit rman einloggen zu können.
Hierfür ist auch der statische Eintrag in die listener ora (s. oben) notwendig.
# tnsnames.ora Network Configuration File: /oracle/product/19.0.0/dbhome_1/network/admin/tnsnames.ora # Generated by Oracle configuration tools. TL2 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = techlab2)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = tl2) (UR= A) ) ) TL1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = techlab1)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = tl1) (UR= A) ) ) PDB1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = techlab1)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = pdb1) ) ) |
listener.ora techlab2
# listener.ora Network Configuration File: /oracle/product/19.0.0/dbhome_1/network/admin/listener.ora # Generated by Oracle configuration tools. SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = tl2) (ORACLE_HOME = /oracle/product/19.0.0/dbhome_1) (SID_NAME = tl2) ) ) LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = techlab2.techlab.local)(PORT = 1521)) ) (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) ) ADR_BASE_LISTENER = /oracle |
tnsnames.ora techlab 2
# tnsnames.ora Network Configuration File: /oracle/product/19.0.0/dbhome_1/network/admin/tnsnames.ora # Generated by Oracle configuration tools. TL2 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = techlab2)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = tl2) (UR= A) ) ) TL1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = techlab1)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = tl1) (UR= A) ) ) PDB1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = techlab1)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = pdb1) ) ) |
auf den beiden Hosts muss der Listener gestartet werden.
[oracle@techlab1 admin]$ lsnrctl start [oracle@techlab1 admin]$ lsnrctl status |
6. Kopieren der Parameter Datei zum Standby Host
$ cd $ORACLE_HOME/dbs quit scp inittl1.ora techlab2: /oracle/product/19.0.0/dbhome_1/dbs/inittl2.ora scp orapwtl1 techlab2: /oracle/product/19.0.0/dbhome_1/dbs/orapwtl2 |
Auf dem Standby Server. Achtung das orapw File ist abhängig von Gross/Kleinschreibung der SID.
Bei der SID tl2 muss das File orapwtl2 heißen, ansonsten orapwTL2. Ignoriert man an dieser Stelle die Groß/Kleinschreibung wird man sich mit dem rman niemals einloggen können.
Editieren der Datei inittl2.ora
*.db_name='tl1' *.db_unique_name='tl2' |
Erzeugen der spfile Parameterdatei
SQL> sqlplus / as sysdba |
Erstellen der DB Verzeichnisse
umask 0027 mkdir -p /oracle/admin/tl1/adump mkdir -p /oracle/oradata/TL1 mkdir -p /oracle/oralog/fast_recovery_area/TL1 |
SQL> startup nomount; |
7. Erstellen Sie das folgende rman-Skript:
mkdir -p /home/oracle/scripts/ora_scripts
touch /home/oracle/scripts/ora_scripts/rman_duplicate2_db.rman
vi /home/oracle/scripts/ora_scripts/rman_duplicate2_db.rman
set echo on duplicate target database for standby from active database dorecover nofilenamecheck; |
Verbinden Sie sich nun als Oracle User mit dem Primären Host (wo die tl1 DB läuft) oder öffnen Sie ein neues Terminal und führen Sie den folgenden Befehl aus.
$ rman target sys/ora-adm@TL1 auxiliary sys/ora-adm@TL2 RMAN> @/home/oracle/scripts/ora_scripts/rman_duplicate2_db.rman RMAN> quit |
Wir haben nun eine Standby DB mit hilfe von rman erzeugt.
Jetzt sollte man den STANDBY_FILE_MANAGEMENT Parameter auf AUTO stellen, damit Physikalische Änderungen an der Tablespace Datei Struktur auch auf der Standby DB angewandt werden, welche ansonsten händisch nachzupflegen sind.
Auf dem Standby DB Server techlab2
sqlplus / as sysdba SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO; |
8. Erstellen der start und stop Skripte für die Primär/Standyby DB
techlab1: /home/oracle/.bash_profile ergänzen
# User specific environment and startup programs . /home/oracle/scripts/setEnv.sh |
techlab1: /home/oracle/scripts/setEnv.sh
# Oracle Settings TMP=/tmp; export TMP TMPDIR=$TMP; export TMPDIR ORACLE_HOSTNAME="techlab1.techlab.local"; export ORACLE_HOSTNAME ORACLE_BASE=/oracle; export ORACLE_BASE GRID_HOME="/oracle/app/19.0.0/grid"; export GRID_HOME DB_HOME="$ORACLE_BASE/product/19.0.0/dbhome_1"; export DB_HOME ORA_INVENTORY=/oracle/oraInventory; export ORA_INVENTORY ORACLE_HOME=$DB_HOME; export ORACLE_HOME ORACLE_SID=tl1; export ORACLE_SID ORACLE_TERM=xterm; export ORACLE_TERM BASE_PATH=/usr/sbin:$PATH; export BASE_PATH PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$BASE_PATH; export PATH LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib; export LD_LIBRARY_PATH CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib; export CLASSPATH alias grid=". /home/oracle/scripts/grid_env" alias db=". /home/oracle/scripts/db_env" export CV_ASSUME_DISTID=OEL7.8 |
techlab1: /home/oracle/scripts/start_oracle_services.sh
#!/bin/bash # Oracle Settings TMP=/tmp; export TMP TMPDIR=$TMP; export TMPDIR ORACLE_HOSTNAME="techlab1.techlab.local"; export ORACLE_HOSTNAME ORACLE_BASE=/oracle; export ORACLE_BASE GRID_HOME="/oracle/app/19.0.0/grid"; export GRID_HOME DB_HOME="$ORACLE_BASE/product/19.0.0/dbhome_1"; export DB_HOME ORA_INVENTORY=/oracle/oraInventory; export ORA_INVENTORY ORACLE_HOME=$DB_HOME; export ORACLE_HOME ORACLE_SID=tl1; export ORACLE_SID ORACLE_TERM=xterm; export ORACLE_TERM BASE_PATH=/usr/sbin:$PATH; export BASE_PATH PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$BASE_PATH; export PATH LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib; export LD_LIBRARY_PATH CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib; export CLASSPATH lsnrctl start listener echo "startup" | sqlplus / as sysdba |
techlab1: /home/oracle/scripts/stop_oracle_services.sh
#!/bin/bash # Oracle Settings TMP=/tmp; export TMP TMPDIR=$TMP; export TMPDIR ORACLE_HOSTNAME="techlab1.techlab.local"; export ORACLE_HOSTNAME ORACLE_BASE=/oracle; export ORACLE_BASE GRID_HOME="/oracle/app/19.0.0/grid"; export GRID_HOME DB_HOME="$ORACLE_BASE/product/19.0.0/dbhome_1"; export DB_HOME ORA_INVENTORY=/oracle/oraInventory; export ORA_INVENTORY ORACLE_HOME=$DB_HOME; export ORACLE_HOME ORACLE_SID=tl1; export ORACLE_SID ORACLE_TERM=xterm; export ORACLE_TERM BASE_PATH=/usr/sbin:$PATH; export BASE_PATH PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$BASE_PATH; export PATH LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib; export LD_LIBRARY_PATH CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib; export CLASSPATH lsnrctl stop listener echo "shutdown immediate" | sqlplus / as sysdba |
techlab2: /home/oracle/.bash_profile ergänzen
# User specific environment and startup programs . /home/oracle/scripts/setEnv.sh |
techlab2: /home/oracle/scripts/setEnv.sh
# Oracle Settings export TMP=/tmp export TMPDIR=$TMP export ORACLE_HOSTNAME=techlab2.techlab.local export ORACLE_UNQNAME=tl2 export ORACLE_BASE=/oracle export ORACLE_HOME=$ORACLE_BASE/product/19.0.0/dbhome_1 export ORA_INVENTORY=/oracle/oraInventory export ORACLE_SID=tl2 export PDB_NAME=weblogic export DATA_DIR=/oracle/oradata export PATH=/usr/sbin:/usr/local/bin:$PATH export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib export CV_ASSUME_DISTID=OEL7.8 |
techlab2: /home/oracle/scripts/start_oracle_services.sh
#!/bin/bash export ORACLE_BASE=/oracle export ORACLE_HOME=$ORACLE_BASE/product/19.0.0/dbhome_1 export PATH=$ORACLE_HOME/bin:$PATH export ORACLE_HOSTNAME=techlab2.techlab.local export ORACLE_UNQNAME=tl2 export ORACLE_SID=tl2 lsnrctl start listener echo "startup nomount;" | sqlplus / as sysdba echo "alter database mount standby database;" | sqlplus / as sysdba |
techlab2: /home/oracle/scripts/stop_oracle_services.sh
#!/bin/bash export ORACLE_BASE=/oracle export ORACLE_HOME=$ORACLE_BASE/product/19.0.0/dbhome_1 export PATH=$ORACLE_HOME/bin:$PATH export ORACLE_HOSTNAME=techlab2.techlab.local export ORACLE_UNQNAME=tl2 export ORACLE_SID=tl2 lsnrctl stop listener echo "shutdown immediate" | sqlplus / as sysdba |
9. Eine Unit Datei für den automatischen Start unserer Datenbanken erstellen
Erstellen Sie diese Datei auf Primary und in Standby:
touch /usr/lib/systemd/system/dbora.service
vi /usr/lib/systemd/system/dbora.service [Unit] Description=The Oracle Database Service After=syslog.target network.target [Service] LimitMEMLOCK=infinity LimitNOFILE=65535 RemainAfterExit=yes User=oracle Group=oinstall Restart=no ExecStart=/home/oracle/scripts/start_oracle_services.sh ExecStop=/home/oracle/scripts/stop_oracle_services.sh [Install] WantedBy=multi-user.target |
systemctl daemon-reload
systemctl enable dbora
systemctl start dbora
9. Erzeugen der passwortlosen SSH Kommunikation zwischen den Hosts:
Wichtig: SSH muss für das nachfolgende Skript passwortlos funktionieren. Es sind die Public Schlüssel der beiden Hosts in der jeweiligen Oracle User /home/oracle/.ssh/authorized_keys zu hinterlegen.
su – oracle id uid=54321(oracle) gid=54321(oinstall) Gruppen=54321(oinstall),54322(dba),54323(oper),54324(backupdba),54325(dgdba),54326(kmdba),54330(racdba) ssh-keygen -t rsa ##doppelt return für ohne passphrase, auf beiden Hosts ausführen. Host techlab1: cat ~/.ssh/id_rsa.pub | ssh oracle@techlab2 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" Host techlab2: cat ~/.ssh/id_rsa.pub | ssh oracle@techlab1 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" |
10. Erstellen eines Skripts für das Apply der Standby DB
Das folgende Skript manual_standby.sh rotiert/archiviert das Redolog auf der Primären DB, und synchronisiert über Rsync die Archive Log Dateien welche im Anschluss auf der Standby DB Recovered werden. Es wird ein Tageslog erstellt in dem das Recovery nachvollzogen werden kann. Nach dem konfigurieren und testen des Skriptes kann dies nun in der Crontab aktiviert werden.
mkdir -p /home/oracle/scripts/stb_scripts
touch /home/oracle/scripts/stb_scripts/manual_standby.sh
vi /home/oracle/scripts/stb_scripts/manual_standby.sh
#!/bin/bash #set -x #– —————————————————————————– #– Script : /home/oracle/scripts/stb_scripts/manual_standby.sh #– Task : Aktualisierung der Standby Datenbank #– Author : Stefan M. Dohn, 19.04.2021 #– 19.04.2021 SDohn Creation from scrap #– Last updates: #– —————————————————————————– export ME=$(whoami) export SCRIPT_PATH=$(dirname $(readlink -f $0)) export SCRIPT_NAME=$(basename $0 .sh) export DLOG="manual_standby_$(date +%d%m%Y).log" export PRIMARY_DB="tl1" export PRIMARY_SERVER="techlab1" export STANDBY_DB="tl2" export STANDBY_SERVER="techlab2" MAILTO="oracle" WARNTHRESHOLD=10 if [ „x$ME“ != „xoracle“ ]; then echo "Script muss als User oracle laufen" && exit 1; fi #ENV to set for techlab1 if [ $HOSTNAME = „techlab1“ ] && [ $USER = „oracle“ ] then ORACLE_SID=TL1; export ORACLE_SID ORACLE_HOME=/oracle/product/19.0.0/dbhome_1; export ORACLE_HOME echo "Skript soll nur auf Standby DB laufen! … exit" | tee -a $DLOG exit 0 #Skript soll nur auf der Standby DB laufen #ENV to set for techlab2 elif [ $HOSTNAME = „techlab2“ ] && [ $USER = „oracle“ ] then ORACLE_SID=TL2; export ORACLE_SID ORACLE_HOME=/oracle/product/19.0.0/dbhome_1; export ORACLE_HOME fi #=== FUNCTION ================================================================ # NAME: PRMARC # DESCRIPTION: Archivierung der aktuellen Log-Dateien der Primaerdatenbank TL1 # CREATED: 19.04.2021 13:00 CET / AUTHOR: Stefan M. Dohn #=============================================================================== # PRMARC() { # Archivierung der aktuellen Log-Dateien der Primaerdatenbank TL1 $ORACLE_HOME/bin/sqlplus sys/ora-adm@$PRIMARY_DB as sysdba <<'EOF' | tee -a $DLOG alter system archive log current; exit EOF } #=== FUNCTION ================================================================ # NAME: PRMTRST # DESCRIPTION: Archivelog Transport zur Standby-Seite # DESCRIPTION: Vom Host techlab1 zum lokalen Archivelog Verzeichnis # CREATED: 19.04.2021 13:00 CET / AUTHOR: Stefan M. Dohn #=============================================================================== # PRMTRST() { rsync -e ssh -Pazv techlab1:/oracle/oralog/fast_recovery_area/TL1/archivelog/* /oracle/oralog/fast_recovery_area/TL2/archivelog | tee -a $DLOG # Recovery der Standby DB $ORACLE_HOME/bin/sqlplus sys/ora-adm@$STANDBY_DB as sysdba <<'EOF' | tee -a $DLOG recover automatic standby database; cancel exit EOF } #=== FUNCTION ================================================================ # NAME: ARCHLAG # DESCRIPTION: Den LAG der Archive Log SEQ Nummern zwischen PRIMARY und STANDBY ermittteln # CREATED: 19.04.2021 13:00 CET / AUTHOR: Stefan M. Dohn #=============================================================================== # ARCHLAG() { echo "########## Prüfung auf GAP der Archive-Log-Sequence-Nummern ##########" | tee -a $DLOG echo "########## zwischen Primaer-DB und Standby-DB : `date '+%D %T'` ##########" | tee -a $DLOG PRIMARY=` ssh $PRIMARY_SERVER 'source /home/oracle/scripts/setEnv.sh; sqlplus -silent / as sysdba <<EOF set pagesize 0 feedback off verify off heading off echo off select max(sequence#) from sys.v\\$log_history; exit; EOF' ` STANDBY=`source /home/oracle/scripts/setEnv.sh;sqlplus -silent / as sysdba <<.eof. set pages 0 feed off heading off echo off verify off termout off select max(sequence#) from sys.v\\$log_history; exit .eof.` echo "Primaer-DB "$PRIMARY_DB"-"$PRIMARY | tee -a $DLOG echo "Standby-DB "$STANDBY_DB"-"$STANDBY | tee -a $DLOG LACK=`expr $PRIMARY – $STANDBY` if [ $LACK -gt $WARNTHRESHOLD ] then echo "!!! Standby-DB ist veraltet !!!" | tee -a $DLOG echo "########## Warn Mail versenden: `date '+%D %T'` ##########" | tee -a $DLOG TMP=/tmp/tmp$PID TMPM=$TMP.mail echo "WARNUNG Standby-Datenbank ist scheinbar OUTDATED" >$TMPM echo "Primary-DB "$PRIMARY_DB"-"$PRIMARY >> $TMPM echo "Standby-DB "$STANDBY_DB"-"$STANDBY >> $TMPM echo "Standby liegt $LACK Archive-Log-Dateien zurueck" >> $TMPM echo "Die Situation ist erst kritisch wenn diese Nachricht mehrmals hintereinander kommt." >> $TMPM echo "ACHTUNG "$SCRIPT_PATH"/archive_remove.block wird gesetzt zum Blocken der Bereinigung" >> $TMPM mail < $TMPM -s "WARNUNG!: Standby-DB $STANDBY_DB nicht aktuell" "$MAILTO" rm $TMPM # Verhindern das Archive-Logs geloescht werden (separates Skript) echo "NICHT LOESCHEN" > $SCRIPT_PATH/archive_remove.block fi } #=== FUNCTION ================================================================ # NAME: ARCHAGE # DESCRIPTION: Alte Archivelogs auf Standby loeschen aelter als 8 Tage # CREATED: 19.04.2021 13:00 CET / AUTHOR: Stefan M. Dohn #=============================================================================== # ARCHAGE() { if [ -e „$SCRIPT_PATH“/archive_remove.block ] then echo "!!! Archivelogs duerfen nicht geloescht werden !!!" | tee -a $DLOG echo "Eventuell ist manuelle Intervention auf d. StandBy DB nötig: `date '+%D %T'` ##########" | tee -a $DLOG echo "Wenn alles OK, kann das lock file $SCRIPT_PATH/archive_remove.block gelöscht werden" | tee -a $DLOG exit; fi # Alte Archivelogs auf Standby loeschen aelter als 8 Tage find /oracle/oralog/fast_recovery_area/TL2/archivelog -type f -mtime +8 -exec rm {} \; | tee -a $DLOG # Alte Archivelogs auf Primary loeschen aelter als 8 Tage # Vorraussetzung: Taegliches RMAN Backup der Archivelog Dateien rman target sys/ora-adm@tl1 <<'EOF' | tee -a $DLOG DELETE NOPROMPT ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-8'; crosscheck archivelog all; exit EOF } PRMARC #Archivierung der aktuellen Log-Dateien der Primaerdatenbank TL1 PRMTRST #Archivelog Transport zur Standby-Seite ARCHLAG #Den LAG der Archive Log SEQ Nummern zwischen PRIMARY und STANDBY ermittteln ARCHAGE #Alte Archivelogs auf Standby loeschen aelter als 8 Tage exit |
Download des Skripts: manual_standby
Mit dem Ausführen des Skripts werden nun die DB Changes von der Primären in der Standby DB nachgefahren..
11. Die Archivelog deletion Policy für das rman backup setzen
Für den Primären, hier wird das rman Backup gemacht
rman target / CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY BACKED UP 1 TIMES TO DISK; |
Für unsere Standby Datenbank, hier machen wir keine Backups
rman target / |
Diese Rman Konfiguration muss beim Switchover der Standby zur Primary passend neu gesetzt werden.
Wie kann ich nun überprüfen, ob Objekte wie Tabellen auch wirklich in der Standby DB angelegt werden?
Die Standby DB kann aus dem Recovery herausgenommen werden und als Read Only gestartet werden. Hiermit kann man dann Überprüfen ob die Objekte in der Standby DB stimmig sind.
sqlplus / as sysdba SQL> shutdown immediate; SQL> startup mount; SQL> alter database open read only; SQL> select open_mode from v$database; OPEN_MODE ——————– READ ONLY |
Nachdem Sie die Datenbank schreibgeschützt geöffnet haben, führen Sie alle gewünschten SQL-Befehle aus, um einige Änderungen zu überprüfen, die Sie in der Produktion kennen. Wenn Sie fertig sind, fahren Sie die DB wieder herunter und starten Sie erneut im Standby-Modus. Vergessen Sie nicht, manual_standby.sh in der Crontab wieder zu aktivieren.
Wie starte ich die DB anschliessend wieder für das Recovery?
SQL> shutdown immediate; SQL> startup nomount; SQL> alter database mount standby database; |
Das Skript manual_standby.sh kann ab jetzt wieder für das permanente Recovery genutzt werden.
Wenn ich die Standby DB nun im Fehlerfall als Primäre DB öffnen möchte, wie verfahre ich?
Für dieses Szenario muss sichergestellt werden, dass alle aktuellen Archive Logs auf die Standby Seite syncronisert wurden.
# Aktivieren der Standby DB als Primäre sqlplus / as sysdba SQL> RECOVER AUTOMATIC STANDBY DATABASE; SQL> CANCEL SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH; SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY; SQL> SHUTDOWN IMMEDIATE; SQL> STARTUP; |
Im Anschluss muss natürlich der Cron Job mit dem manual_standby.sh Skript deaktiviert werden.
Welche anderen Skripte sollten noch eingerichtet werden?
a. Ein Skript zum Bereinigen alter archivierter Redo-Protokolle auf der Primärseite.
b. Ein Skript zum Bereinigen alter archivierter Redo-Protokolle im Standby-Modus.
c. Ein Skript zum Rotieren und Archivieren der Datei alert.log, wenn sie groß wird.
d. Ein Skript, mit dem die Datei alert.log auf ORA-xxxxx-Fehler überwacht und an Nagios gemeldet wird, falls diese gefunden werden (sowohl im primären als auch im Standby-Modus).
e. Ein Skript zum Anmelden (über ssh autologin) und zum Überprüfen der neuesten archivierten Redolog-Datei. Melden Sie sich dann auch im Standby-Modus an und überprüfen Sie die Datei alert.log, um zu überprüfen, ob diese Transaktionen angewendet wurden.
f. Das Archivelog GAP zwischen Primäre und Standby DB sollte mit dem Recover Script gleichzeitig ermittlet werden. Bei über 10 nicht applizierten Archivelog Dateien wird eine Lock Datei und eine Warnung per Mail gesendet.
Wie kann ich nun z.B. mit Nagios Monitoren das das letzte applizierte Redolog nicht zu lange her ist. Bzw. haben wir durch zu lange Lerrlaufzeiten beim Redo Apply eine Fehlerfall?
Das folgende SQL checkt wie lange die letzte Änderung in der Standby DB her ist.
SQL> select sysdate-max(checkpoint_time) from v$datafile_header; SYSDATE-MAX(CHECKPOINT_TIME) —————————- ,000219907 SQL> |
Diesen Wert kann man in Nagios mit einem geigneten Schwellwert checken.
Ein Beispiel Skript für das Überprüfen auf ORA- Fehler im alert.log
#!/bin/bash #set -x #– —————————————————————————– #– Script : /home/oracle/scripts/ora_scripts/checkalertlog.sh #– Task : Check the alert.log file for ORA- Errors and send mail #– Author : Stefan M. Dohn, 15.04.2021 #– 15.04.2021 SDohn Creation from scrap #– Last updates: #– —————————————————————————– PATH=$PATH:/usr/local/bin; export PATH ORACLE_BASE="/oracle"; export ORACLE_BASE MAILRECEIVER="oracle" if [ „$1“ ] then ORACLE_SID=$1 else if [ ! „$ORACLE_SID“ ] then echo "Error: No ORACLE_SID set or provided as an argument" exit 1 fi fi #Get into Oracle trace directory if [ -e $ORACLE_BASE/diag/rdbms/“$ORACLE_SID“/“$ORACLE_SID“/trace ] then cd $ORACLE_BASE/diag/rdbms/"$ORACLE_SID"/"$ORACLE_SID"/trace || exit else echo "$ORACLE_BASE/diag/rdbms/$ORACLE_SID/$ORACLE_SID/trace does not exist! … exit" exit 1 fi # Copy the current alert log into a temporary file and empty the original cp alert_"$ORACLE_SID".log alert_"$ORACLE_SID".log.temp cp /dev/null alert_"$ORACLE_SID".log # Check the copy in the temporary file for ORA- errors grep 'ORA-' alert_"$ORACLE_SID".log.temp > /dev/null # If found, email the Oracle user with the contents of the alert log if [ $? = 0 ] then MAILTEXT="$ORACLE_SID database alert log error" echo "$MAILTEXT" | mail -s "$MAILTEXT" -a alert_"$ORACLE_SID".log.temp $MAILRECEIVER fi # Move the contents of the temp file onto the permanent copy of the log # and remove the temp file. cat alert_"$ORACLE_SID".log.temp >> alert_"$ORACLE_SID".log.1 rm alert_"$ORACLE_SID".log.temp |