News
DBA-Tipp: Substitutionsvariablen für flexible, plattformunabhängige RMAN-Backups

Die Information ist ein schnelllebiges Gut. Jeden Tag werden wir mit hunderten Informationen zugemüllt. Deshalb sind wir bestrebt uns auf das Wesentliche zu konzentrieren und nur substantiell nachhaltige Informationen bereitzustellen.

Icon Unternehmen

Skriptgesteuerte Backups mit Oracle RMAN sollten sich mittlerweile als Standardverfahren für das Online-Backup von Oracle Datenbanken etabliert haben. Im heutigen DBA-Tipp sollen zwei Möglichkeiten gezeigt werden, wie man Backupscripts grundsätzlich parametrieren kann. Zudem soll der Vorteil der Verwendung von Substitutionsvariablen ggü. here documents deutlich werden.

Zu diesem Zweck nehmen wir folgendes Szenario an:

  • Es sind Backups von zwei Datenbanken, "orcl" und "foo", zu erstellen
  • Das Backupverzeichnis lautet /backup/oracle/<datenbankname>/<level>
  • Montag bis Samstags sollen inkrementelle Level 1 Backups erstellt werden, Sonntags ein Level 0 Backup
  • Alle Backups sollen über ein gemeinsames Skript abgewickelt werden, maximal unter Zuhilfenahme eines gemeinsamen RMAN-Commandfiles

Es lässt sich unschwer erkennen, dass die Lösung darauf angewiesen ist, mehrere Parameter dynamisch an das Backupskript zu übergeben. In Unix-/Linux-Umgebungen ist die Umsetzung mittels Shellvariablen und eines "here document" recht einfach möglich (wobei das Beispielskript davon ausgeht, dass die Umgebung bereits korrekt konfiguriert ist):

#! /bin/bash
# rman_backup.sh

# Der 1. Skriptparameter benennt die zu sichernde Datenbank.
# Dieser Wert wird im Beispiel für diverse Pfadunterscheidungen
# genutzt
DATABASE_NAME=$1

# Der 2. Skriptparameter ist die Connectinformation zur Datenbank.
# Im Beispiel werden hier Username und Passwort übergeben, was in
# der Realität natürlich auf keinen Fall so umgesetzt werden sollte.
# Ideal wäre statt dessen die Nutzung des Secure External Password
# Store (SEPS). 
DATABASE_CONNECT=$2

if [ $(date +%a) == 'Sun' ]; then
  # Sonntags Level 0 Backup
  BACKUP_LEVEL=0
else
  # Montag bis Samstag Level 1 Backup
  BACKUP_LEVEL=1
fi

# Das RMAN-Kommando wird unter Zuhilfenahme der Shellvariablen
# dynamisch aufgebaut und ausgeführt
rman target ${DATABASE_CONNECT} <<-RMAN
  backup
    check logical
    incremental level ${BACKUP_LEVEL}
    database
    format '/backup/oracle/${DATABASE_NAME}/${BACKUP_LEVEL}/%U';
RMAN

Die Backups der beiden Datenbanken könnten nun durch folgende Skriptaufrufe gestartet werden:

$ rman_backup.sh orcl sys/oracle@orcldbserver/orcl
$ rman_backup.sh foo sys/oracle@foodbserver/orcl

Am Beispiel der orcl-Sicherung sehen wir, wie die Aufrufparameter bzw. Shellvariablen ersetzt wurden:

[oracle@backupserver]$ bash -x rman_backup.sh orcl sys/oracle@orcldbserver/orcl
+ DATABASE_NAME=orcl                        
+ DATABASE_CONNECT=sys/oracle@orcldbserver/orcl

++ date +%a                                                           
+ '[' Thu == Sun ']'                                                  
+ BACKUP_LEVEL=1
+ rman target sys/oracle@orcldbserver/orcl

Recovery Manager: Release 11.2.0.3.0 - Production on Thu Jan 8 16:13:47 2015

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

connected to target database: ORCL (DBID=1393943109)

RMAN> 2> 3> 4> 5>
Starting backup at 2015-01-08 16:13:48
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=47 device type=DISK
channel ORA_DISK_1: starting incremental level 1 datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00001 name=+DATA/orcdb02/datafile/system.367.866166491
...
channel ORA_DISK_1: starting piece 1 at 2015-01-08 16:13:49
channel ORA_DISK_1: finished piece 1 at 2015-01-08 16:13:52
piece handle=/backup/oracle/orcl/1/0vps7e5t_1_1 tag=TAG20150108T161349
comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
...
Finished backup at 2015-01-08 16:13:54

RMAN>

Recovery Manager complete.

Wenngleich durchaus gebräuchlich, ist diese Variante wenig übersichtlich, da die RMAN-Kommandos Bestandteil des Shellskripts sind. Darüber hinaus ist diese Variante, wie bereits erwähnt, nicht auf Windows-Systemen umsetzbar. Daher nun die zweite Variante, die für beide Umgebungen funktioniert.

Das RMAN-Binary kann Parameter auf der Kommandozeile übernehmen, die innerhalb RMAN als Substitutionsvariablen wie aus SQL-Skripts bekannt verfügbar sind. Hierfür ist bei Aufruf des RMAN als letzter Parameter das Schlüsselwort USING, gefolgt von den zu übergebenden Werten anzugeben. Übertragen auf obiges Beispiel sähe das Backupskript für Linux folgendermaßen aus:

#! /bin/bash
# rman_backup.sh
DATABASE_NAME=$1
DATABASE_CONNECT=$2

if [ $(date +%a) == 'Sun' ]; then
  # Sonntags Level 0 Backup
  BACKUP_LEVEL=0
else
  # Montag bis Samstag Level 1 Backup
  BACKUP_LEVEL=1
fi

# Das RMAN-Kommando nutzt nun ein externes RMAN-Commandfile,
# dem die nötigen Parameter an der Kommandozeile übergeben werden
rman target ${DATABASE_CONNECT} \
    @rman_backup.rman using ${DATABASE_NAME} ${BACKUP_LEVEL}

Das entsprechende RMAN-Commandfile verwendet die übergebenen Parameter als Substitutionsvariablen:

# rman_backup.rman
backup
  check logical
  incremental level &2
  database
  format '/backup/oracle/&1/&2/%U';

Wiederum erfolgt der Aufruf durch:

$ rman_backup.sh orcl sys/oracle@orcldbserver/orcl
$ rman_backup.sh foo sys/oracle@foodbserver/orcl

Auch hier beispielhaft das Log der orcl-Sicherung mit ersetzten Shell- und Substitutionsvariablen. Diesmal erfolgt die Übergabe der Parameter über den USING-Konstrukt direkt in das RMAN-Skript und erst dort erfolgt die Ersetzung. Somit wäre diese Variante – im Gegensatz zum ersten Beispiel – auch unter Windows nutzbar

[oracle@backupserver]$ bash -x rman_backup.sh orcl sys/oracle@orcldbserver/orcl
+ DATABASE_NAME=orcl
+ DATABASE_CONNECT=sys/oracle@orcldbserver/orcl
++ date +%a
+ '[' Thu == Sun ']'
+ BACKUP_LEVEL=1
+ rman target sys/oracle@orcldbserver/orcl @rman_backup.rman using orcl 1

Recovery Manager: Release 11.2.0.3.0 - Production on Thu Jan 8 16:17:33 2015

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

connected to target database: ORCL (DBID=1393943109)

RMAN> # rman_backup.rman
2> backup
3>   check logical
4>   incremental level 1
5>   database
6>   format '/backup/oracle/orcl/1/%U';
7>
Starting backup at 2015-01-08 16:17:34
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=28 device type=DISK
channel ORA_DISK_1: starting incremental level 1 datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00001 name=+DATA/orcdb02/datafile/system.367.866166491
...
channel ORA_DISK_1: starting piece 1 at 2015-01-08 16:17:35
channel ORA_DISK_1: finished piece 1 at 2015-01-08 16:17:38
...
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 2015-01-08 16:17:40

Recovery Manager complete.

Fazit: Parametrierbare RMAN-Backupscripts stellen eine modulare Möglichkeit zum Sichern von Oracle-Datenbanken dar. Nur unter Linux/Unix ist durch die Verfügbarkeit der „here documents“ die Parametrierung direkt im Backupscript möglich.

Die Auslagerung der Backuplogik in RMAN-Commandfiles, verbunden mit der Verwendung von Substitutionsvariablen, erhöht Übersichtlichkeit und Wartbarkeit von Backupskripten und hebt darüber hinaus die Plattformabhängigkeit des Backupscirpts auf.