Backup und Recovery – eine Frage der Konsistenz

03.
Februar
2020
Veröffentlicht von: Katja Werner

Der vorliegende Monatstipp behandelt das Thema incomplete Recovery (Point-in-Time-Recovery, Recovery-until-SCN, Recovery-until-cancel) mit dem RMAN. Dabei wird insbesondere auf die Themen Konsistenz der Datenbank Backups, SCN, fuzzy Datenfiles und fractured Blöcke eingegangen. Die dargestellten Backup- und Recovery-Mechanismen gelten auch für vollständige Recoveries, aber an Hand der incomplete Recoveries wird die faszinierende Funktionsweise deutlicher.

Zur besseren Anschaulichkeit wurden Tests auf einer Oracle Datenbank, Version 19.3., Enterprise Edition durchgeführt. Die Backups erfolgten in Form von Backupsets.

Konsistenz von Backups

Konsistenz. Dies ist das Zauberwort für Backup und Recovery, alles dreht sich hier um Konsistenz. Konsistenz der Datenbank bedeutet, dass alle Datenbank-Blöcke, ja sogar die dazu gehörigen Betriebssystem-Blöcke zueinander passen, sprich Daten von exakt demselbem Zeitpunkt enthalten. Eine Datenbank lässt sich nur öffnen, wenn sie konsistent ist. Konsistenz hat nichts damit zu tun, ob man alle Daten bis zum Schluss wieder herstellt (vollständiges Recovery) oder ob man ein unvollständiges (incomplete) Recovery durchführt.

Naturgemäß sind bei Online-Backups, also Backups einer geöffneten Datenbank im Archivelog Modus, inkonsistent. Denn während der RMAN sichert, werden auf den Datenfiles laufend Daten geschrieben, gelöscht oder geändert. Wie also wird die Konsistenz sichergestellt?

Der RMAN erkennt Inkonsistenzen. An bestimmten Stellen behebt er sie gleich beim Backup, mehr dazu weiter unten. Generell jedoch sichert der RMAN die Datenfiles einfach mit ihren Inkonsistenzen, „protokolliert“ jedoch die fürs Erkennen von Inkonsistenzen bei Backup und Recovery relevanten SCNs. Die Archived Redologs werden später beim Recovery benötigt, um die Datenfiles alle auf denselben Zeitpunkt (= dieselbe System Change Number SCN) vorzurollen, sprich: Konsistenz herzustellen. Erst dann lässt sich die Datenbank erfolgreich öffnen.

Sehen wir uns im Folgenden genauer an, an welchen Stellen Inkonsistenzen vorkommen können und wie Oracle damit umgeht.

Zum einen können Inkonsistenzen entstehen, wenn bei einem Datenbank-Backup Datenfiles nacheinander gesichert werden. So haben die zum Backup gehörenden Datenfiles in Abhängigkeit von „ihrem“ Backupset unterschiedliche Checkpoint SCNs (späterer Backup-Beginn = höhere Checkpoint SCN).

Zum zweiten kann es auch innerhalb eines Datenfiles zu Inkosistenzen kommen. In diesem Zusammenhang verwendet man den Begriff fuzzy Datenfile. Was passiert genau? Der RMAN sichert zum Zeitpunkt 1 die ersten Blöcke aus dem Datenfile, zum Zeitpunkt 2 die nächsten usw.. Wenn er jedoch am Ende des Datenfiles die letzten Blöcke sichert, sagen wir zum Zeitpunkt 3, dann haben sich evtl. weiter vorn bereits gesicherte Blöcke erneut geändert. Der RMAN merkt, dass sich während des Wegschreibens des Datenfiles Blöcke geändert haben und protokolliert die höchste SCN mit. Das ist die fuzzy SCN. Sie kann der View V$BACKUP_DATAFILE, beim Kommando restore database preview sowie in höheren Oracle Versionen dem Output des list backup-Kommandos entnommen werden. In diesem Blog-Eintrag wird dieses Verhalten sehr schön erklärt. Der Blog ist bereits von 2006 und es gab seitdem sicherlich einige Änderungen, aber das Prinzip wird ähnlich sein.

Eine dritte „Art“ von Inkosistenz entsteht dadurch, dass der RMAN die einzelnen Blöcke der Datenfiles in der entsprechenden Datenbank-Blockgröße (Parameter db_block_size) verarbeitet. Nun besteht aber zum Beispiel ein 8K-Datenbank-Block aus Betriebssystem-Blöcken, die nur eine Größe von je 512 Byte haben. Ändern sich Betriebssystem-Blöcke innerhalb eines Datenbank-Blocks während der RMAN sie liest, so sind die in ihnen enthaltenen Daten von 2 oder mehr unterschiedlichen Zeitpunkten. Der Datenbank-Block ist damit in sich inkonsistent, es ist ein fractured Block. Fractured Blocks werden im Alertlog so protokolliert: „Bad check value found during backing up datafile“. Der RMAN bemerkt solche Inkonsistenzen und liest den betroffenen Datenbank-Block ein zweites Mal. Sofern der Datenbank-Block diesmal ok ist, wird er ins Backup aufgenommen. Ist jedoch der Reread wiederum nicht erfolgreich, markiert der RMAN den Block als korrupt und er kann nicht aus dem Backup wieder hergestellt werden. Weitere Einzelheiten sind in der My-Oracle-Support-Note 1950383.1 zu finden.

Incomplete Recovery

Wenn ein Incomplete Recovery (Point-in-Time-Recovery, Recovery-until- SCN, Recovery-until-cancel)  stattfinden soll, stellt sich immer die Frage, bis zu welchem Zeitpunkt genau recovert werden soll: Produktive Datenbanken sollen nach einem notwendigen Restore natürlich so weit wie irgend möglich recovert werden, um Datenverlust zu minimieren. Wird hingegen recovert, um Daten zurückzuerhalten, die versehentlich gelöscht wurden, muss der Recovery-Zeitpunkt kurz vor dem Löschzeitpunkt liegen. Beim dritten Recovery-Szenario – Erstellen einer Testdatenbank aus dem Backup einer produktiven Datenbank – kommt es meist nicht auf die Aktualität der Daten, sondern vielmehr auf eine möglichst kurze Recovery-Zeit an. In diesem Fall ist es Best-Practice immer auf einen Zeitpunkt kurz nach Backup-Ende zu recovern. So kann man einerseits die Recovery-Zeiten möglichst kurz halten und andererseits ohne weitere Checks sicher sein, eine konsistente Datenbank zu erhalten (in unserem folgenden Beispiel sehen wir, dass es vermutlich gar nicht immer notwendig wäre, bis nach Backup-Ende zu recovern, trotzdem ist dies die „sicherste“ Variante).

Für alle drei Szenarien gilt: nach dem Recovery muss die Datenbank konsistent sein, um sie öffnen zu können.

Das folgende Beispiel soll uns dazu dienen, den Backup- und Recovery-Prozess besser zu verstehen und praktisch nachzuvollziehen, welche SCNs für ein erfolgreiches Recovery ausschlaggebend sind. Dazu sichern wir eine Testdatenbank und stellen sie aus dem Backup mit möglichst kurzer Recovery-Dauer wieder her. Dabei beobachten wir, wie sich der Status der Datenfiles sowie die SCNs in den einzelnen Schritten ändern.

Zur Vorbereitung erstellen wir eine Tabelle mit genügend vielen Einträgen, damit das Update später wenigstens ein paar Minuten dauert. Im Beispiel reichte eine Tabelle mit 20 Millionen Zeilen für eine Update-Dauer von mehr als von 5 Minuten. Zeit genug, in der Zwischenzeit ein Backup zu nehmen.

create table t1 (t1_nr number,bemerkung varchar2(80)) tablespace users;
insert into t1 values (1,'Hello RMAN');
insert into t1 select * from t1;
-- mehrfach ausführen (bis ca. 20 Mio Zeilen in t1)
commit;

Wenn die Tabelle erstellt ist, starten wir ein Update darauf. Es läuft länger als das Backup. So wollen wir sicherstellen, dass Datenblöcke während des Backups geändert werden und so für unseren Test fuzzy Datenfiles zu erzwingen. Parallel dazu erfolgt das Backup der Datenbank:

SQL> update t1 set t1_nr=2;
RMAN> backup incremental level 0 database tag=level0 plus archivelog tag=arch;

Nach Beendigung von Backup und Update sind die Vorbereitungen abgeschlossen und nun wollen wir die Datenbank restoren und recovern.

Vor dem Herunterfahren für den anschließenden Restore werfen wir einen Blick in die View V$BACKUP_DATAFILE. Hier sehen wir, dass für zwei Datenfiles (UNDOTBS1- und USERS-Tablespace) eine SCN für ABSOLUTE_FUZZY_CHANGE# gesetzt ist. Diese sind jeweils größer als die SCN für den Checkpoint (CHECKPOINT_CHANGE#) zu Beginn des Backups. Klar, dass diese SCNs höher sind, denn das Update lief nach Beginn des Backups weiter und änderte Blöcke in den Datefiles. Die Files sind fuzzy. ABSOLUTE_FUZZY_CHANGE# beträgt 3590407 für das Datenfile des UNDOTBS1- bzw. 3597062 für das des USERS-Tablespaces.:

select a.file#,b.name,a.incremental_level lv,a.checkpoint_change#,a.checkpoint_time,a.absolute_fuzzy_change#,a.completion_time,a.con_id from v$backup_datafile a,v$datafile b where a.file#=b.file# order by con_id,file#;

Output (gekürzt)

FILE# NAME                                          CHECKPOINT_CHANGE#    CHECKPOINT_TIME     ABSOLUTE_FUZZY_CHANGE#    COMPLETION_TIME
                    
1     +DATA01/ORCL/DATAFILE/system.260.1012668037   3587366               26.01.2020 13:57:17 0                         26.01.2020 13:57:26
3     +DATA01/ORCL/DATAFILE/sysaux.262.1012668047   3587366               26.01.2020 13:57:17 0                         26.01.2020 13:57:24
5     +DATA01/ORCL/DATAFILE/undotbs1.264.1012668053 3587366               26.01.2020 13:57:17 3590407                   26.01.2020 13:59:13
7     +DATA01/ORCL/DATAFILE/users.268.1012668073    3587366               26.01.2020 13:57:17 3597062                   26.01.2020 13:59:32

Die COMPLETION_TIME der View V$BACKUP_DATAFILE ist die Zeit, zu der das Datenfile fertig ins Backupset geschrieben wurde. Der 26.01.2020 13:59:32 ist gleichzeitig das Ende des Datenbank-Backups.

Die View V$DATAFILE_HEADER sieht so aus:

select file#,name,tablespace_name,status,recover,fuzzy,checkpoint_change#,checkpoint_time from v$datafile_header order by file#;

FILE# NAME                                          TABLESPACE_NAME STATUS    REC   FUZ    CHECKPOINT_CHANGE#    CHECKPOINT_TIME
                            
1     +DATA01/ORCL/DATAFILE/system.260.1012668037   SYSTEM          ONLINE    NO    YES    3627696               26.01.2020 14:00:48
3     +DATA01/ORCL/DATAFILE/sysaux.262.1012668047   SYSAUX          ONLINE    NO    YES    3627696               26.01.2020 14:00:48
5     +DATA01/ORCL/DATAFILE/undotbs1.264.1012668053 UNDOTBS1        ONLINE    NO    YES    3627696               26.01.2020 14:00:48
7     +DATA01/ORCL/DATAFILE/users.268.1012668073    USERS           ONLINE    NO    YES    3627696               26.01.2020 14:00:48

Der aktuelle CHECKPOINT_CHANGE#-SCN ist nun schon höher als die CHECKPOINT_CHANGE#-SCN in der View V$BACKUP_DATAFILE zu Beginn des Backups. Man beachte die Werte für RECOVER und FUZZY, während des Restores/Recoveries ändern sie sich auf „YES“ bzw. „NO“. Das sehen wir weiter unten.

Jetzt starten wir den Restore im RMAN:

RMAN> restore database;

Zum Ende des Restores zeigt uns die View V$DATAFILE_HEADER, dass die Datafiles ein Recovery notwendig haben und dass die Datenfiles des USERS- und UNDO-Tablespaces fuzzy sind. Wir erkennen auch die CHECKPOINT_CHANGE#-SCN vom Beginn des Backups wieder.

select file#,name,tablespace_name,status,recover,fuzzy,checkpoint_change#,checkpoint_time from v$datafile_header order by file#;

FILE# NAME                                          TABLESPACE_NAME    STATUS    REC    FUZ    CHECKPOINT_CHANGE#    CHECKPOINT_TIME

1     +DATA01/ORCL/DATAFILE/system.260.1012668037   SYSTEM             ONLINE    YES    NO     3587366               26.01.2020 13:57:17
3     +DATA01/ORCL/DATAFILE/sysaux.262.1012668047   SYSAUX             ONLINE    YES    NO     3587366               26.01.2020 13:57:17
5     +DATA01/ORCL/DATAFILE/undotbs1.264.1012668053 UNDOTBS1           ONLINE    YES    YES    3587366               26.01.2020 13:57:17
7     +DATA01/ORCL/DATAFILE/users.268.1012668073    USERS              ONLINE    YES    YES    3587366               26.01.2020 13:57:17

Bevor wir das Recovery starten, könnten wir im RMAN "restore database preview" laufen lassen. Dieses Statement sagt uns ganz klar, bis wohin wir mindestens recovern müssten, um die Datenbank in einen konsistenten Zustand zu bekommen:


recovery will be done up to SCN 3587366
Media recovery start SCN is 3587366
Recovery must be done beyond SCN 3597062 to clear datafile fuzziness

Es ist dieselbe Information, die wir auch der View V$BACKUP_DATFILE entnehmen können. 3587366 ist die Checkpoint SCN zu Beginn des Backups, 3597062 ist die Fuzzy SCN des USERS-Datenfiles, die höhere der beiden Fuzzy-SCNs.

Würden wir versuchen, vor die Checkpoint SCN zu Backup-Beginn zu recovern, zum Beispiel auf die SCN 3587365, würden wir folgenden Fehler bekommen:

RMAN> recover database until scn 3587365;

RMAN-03002: failure of recover command at 01/26/2020 14:48:32
RMAN-06556: datafile 1 must be restored from backup older than SCN 3587365

Natürlich, das Datenfile ist zu aktuell für die gewählte SCN, somit müsste es von einem vorigen Backup restored/recovered werden.

Auch wenn wir versuchen, auf eine SCN zwischen Beginn Backup und Fuzzy SCN zu recovern, würden wir einen Fehler erhalten:

RMAN> recover database until scn 3597061;
...
archived log file name=+FRA01/ORCL/ARCHIVELOG/2020_01_26/thread_1_seq_412.310.1030715885 thread=1 sequence=412
Oracle Error:
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01194: file 7 needs more recovery to be consistent
ORA-01110: data file 7: '+DATA01/ORCL/DATAFILE/users.268.1012668073'

media recovery complete, elapsed time: 00:00:20

Aus Oracle-Sicht ist das Media Recovery erfolgreich – wir konnten zur gewählten SCN recovern. Aber: aus Oracle-Sicht ist die Datenbank immer noch nicht konsistent und deshalb wird sie sich so nicht öffnen lassen. Die CHECKPOINT_CHANGE# ist durch das Recovery gestiegen, auch das Datenfile zum UNDO-Tablespace ist nicht mehr fuzzy. Allerdings gibt es noch ein fuzzy Datenfile für den USERS-Tablespace. Die View V$DATAFILE_HEADER sieht jetzt so aus:

select file#,name,tablespace_name,status,recover,fuzzy,checkpoint_change#,checkpoint_time from v$datafile_header order by file#;

FILE# NAME                                          TABLESPACE_NAME    STATUS    REC    FUZ    CHECKPOINT_CHANGE#    CHECKPOINT_TIME
                            
1     +DATA01/ORCL/DATAFILE/system.260.1012668037   SYSTEM             ONLINE    YES    NO     3594392               26.01.2020 13:57:48
3     +DATA01/ORCL/DATAFILE/sysaux.262.1012668047   SYSAUX             ONLINE    YES    NO     3594392               26.01.2020 13:57:48
5     +DATA01/ORCL/DATAFILE/undotbs1.264.1012668053 UNDOTBS1           ONLINE    YES    NO     3594392               26.01.2020 13:57:48
7     +DATA01/ORCL/DATAFILE/users.268.1012668073    USERS              ONLINE    YES    YES    3594392               26.01.2020 13:57:48

Beseitigen wir nun auch die letzte Inkonsistenz durch Recovern bis zur SCN 3597062:

RMAN> recover database until scn 3597062;

Erneutes Ansehen von V$DATAFILE_HEADER – kein fuzzy Datenfile mehr.

select file#,name,tablespace_name,status,recover,fuzzy,checkpoint_change#,checkpoint_time from v$datafile_header order by file#;

FILE# NAME                                          TABLESPACE_NAME    STATUS    REC    FUZ    CHECKPOINT_CHANGE#    CHECKPOINT_TIME
                            
1     +DATA01/ORCL/DATAFILE/system.260.1012668037   SYSTEM             ONLINE    YES    NO     3597062               26.01.2020 13:57:59
3     +DATA01/ORCL/DATAFILE/sysaux.262.1012668047   SYSAUX             ONLINE    YES    NO     3597062               26.01.2020 13:57:59
5     +DATA01/ORCL/DATAFILE/undotbs1.264.1012668053 UNDOTBS1           ONLINE    YES    NO     3597062               26.01.2020 13:57:59
7     +DATA01/ORCL/DATAFILE/users.268.1012668073    USERS              ONLINE    YES    NO     3597062               26.01.2020 13:57:59

Nun lässt sich die Datenbank problemlos öffnen:

RMAN> alter database open resetlogs;

Wohlgemerkt: wir haben in diesem – zugegebenermaßen kurzen Test – nicht wie Best Practice bis nach Backup-Ende um 13:59:32 (CHECKPOINT_CHANGE# wäre ca. 3627696) recovert, sondern nur bis 13:57:59. Trotzdem ist unsere Datenbank konsistent und lässt sich öffnen.

Mit dem Öffnen der Datenbank ändert sich sofort die Checkpoint-Time auf die nun aktuelle Zeit. RECOVER steht jetzt auf NO. Die Files erscheinen wieder als Fuzzy, nun aber in unserer korrekt geöffneten Datenbank.

FILE# NAME                                          TABLESPACE_NAME    STATUS    REC    FUZ    CHECKPOINT_CHANGE#    CHECKPOINT_TIME
                            
1     +DATA01/ORCL/DATAFILE/system.260.1012668037   SYSTEM             ONLINE    NO    YES     3597066               26.01.2020 15:05:43
3     +DATA01/ORCL/DATAFILE/sysaux.262.1012668047   SYSAUX             ONLINE    NO    YES     3597066               26.01.2020 15:05:43
5     +DATA01/ORCL/DATAFILE/undotbs1.264.1012668053 UNDOTBS1           ONLINE    NO    YES     3597066               26.01.2020 15:05:43
7     +DATA01/ORCL/DATAFILE/users.268.1012668073    USERS              ONLINE    NO    YES     3597066               26.01.2020 15:05:43

Eine Anmerkung am Rande: bei einem Vergleich der letzten beiden Outputs ist die CHECKPOINT_CHANGE# nur um 4 gestiegen wohingegen die CHECKPOINT_TIME über eine Stunde höher ist. Dies widerlegt die These, dass die Checkpoint SCN aus dem Unterschied in der CPU-Zeit oder ähnlichem berechnet wird. Vielmehr zählt Oracle „einfach“ höher. Bleibt die Frage, wo und vor allem wie lange die CHECKPOINT_TIME-CHECKPOINT#-Kombination protokolliert wird. Einen Hinweis könnte der Fehler ORA-08181 beim Ausführen der Funktion scn_to_timestamp geben (MOS 361480.1). Dies können wir evtl. in einem späteren Monatstipp erforschen.

Fazit

Inkonsistenzen, die während des Backups einer Online-Datenbank naturgemäß entstehen, werden beim Recovery bereinigt. Nur eine konsistente Datenbank lässt sich öffnen. Gängige Praxis sowie am einfachsten und sichersten ist es, bis zu einer SCN kurz nach Backup-Ende zu recovern.

Die SCN, bis zu der mindestens recovert werden muss, lässt sich aus der View V$BACKUP_DATAFILE ermitteln. Hier muss für das Backup die höchste CHECKPOINT_CHANGE# und die höchste ABSOLUTE_FUZZY_CHANGE# ermittelt werden – die höhere der beiden ist die SCN bis zu der mindestens recovert werden muss, damit die Datenbank in sich konsistent ist und geöffnet werden kann.

 

Jede Menge Know-how für Sie!

In unserer Know-How Datenbank finden Sie mehr als 300 ausführliche Beiträge zu den Oracle-Themen wie DBA, SQL, PL/SQL, APEX und vielem mehr.
Hier erhalten Sie Antworten auf Ihre Fragen.