Erzeugen einer Physikalischen Standby Datenbank für Oracle Standard Edition

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
sqlplus / as sysdba
create pfile from spfile

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
SQL> create spfile from pfile

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 /
CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY;

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

 

Dieser Beitrag wurde unter ORACLE veröffentlicht. Setze ein Lesezeichen auf den Permalink.