dbv file=SYSTEM01.DBFAnzeige defekter Datenfiles.
select * from v$recover_file;Anzeige benötigter Redo-Logs.
select * from v$recovery_log;Anzeige Archive Logs.
select * from v$archived_log;
Stellen Sie sich vor, Sie haben eine Datenbank namens testdb29, welche sich im NOARCHIVELOG-Modus befindet. Die Control-Dateien haben Sie auf drei Platten verteilt, um im Crash noch eine Control-Datei zur Verfügung zu haben. Sie planen, ein OFFLINE-Backup jede Nacht durchzuführen. Die Sicherung soll in den Ordner /backup01 gespeichert werden. Von dort aus werden dann die darin enthaltenen Dateien auf Band gesichert.
Datenbankname: testdb29
Controldatei1 /oracle/oradata/testdb29/control01.ctl
Controldatei2 /control01/testdb29/control02.ctl
Controldatei3 /control02/testdb29/control03.ctl
Datendateien: /oracle/oradata/testdb29/users01.dbf
/oracle/oradata/testdb29/system01.dbf
/oracle/oradata/testdb29/temp01.dbf
/oracle/oradata/testdb29/rbs01.dbf
/oracle/oradata/testdb29/idx01.dbf
Redo-Log-Dateien /oracle/oradata/testdb29/redo01.log
/oracle/oradata/testdb29/redo02.log
/oracle/oradata/testdb29/redo03.log
Sicherungsort: /backup01
In diesem Beispiel führen wir die notwendigen Operationen mit Hilfe von SQLPLUS durch.
Natürlich ist es für einen Administrator nicht üblich jede Nacht die Sicherung manuell durchzuführen. Aus diesem Grunde wird an dieser Stelle das oben beschriebene Beispiel mit Hilfe eines Skriptes durchgeführt, welches automatisch jede Nacht gegen 22:00 Uhr ausgeführt wird. Als Basis der Automatisierung wird eine Shell-Script-Datei namens cold-backup.sh erzeugt.
# cold-backup.sh sqlplus "sys/sys@testdb29 as sysdba" @~/sql-scripte/shutdown.sql cp /oracle/oradata/testdb29/* /backup01 cp /control01/test/control02.ctl /backup01 cp /control02/test/control03.ctl /backup01 sqlplus "sys/sys@testdb29 as sysdba" @~/sql-scripte/startup.sqlDieses Script ruft SQLPLUS mit der Parameterdatei shutdown.sql auf.
shutdown immediate startup restrict shutdown normal exitDiese Parameterdatei shutdown.sql fährt die Datenbank mit der Option IMMEDIATE herunter und anschließend wird die Datenbank normal mit der Einschränkung RESTRICT gestartet und normal heruntergefahren. Nun wird SQLPLUS durch den Befehl exit beendet und die Abarbeitung der Befehle in der cold-backup.sh fortgeführt. Es folgen die eigentlichen Copy-Befehle, gefolgt vom abschließenden Aufruf von SQLPLUS mit der Parameterdatei startup.sql.
startup exitDiese Parameterdatei erledigt nichts weiter als das erneute Hochfahren der Datenbank.
select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ INACTIVE 232 401561 /oracle/oradata/testdb29/redo01.log CURRENT 233 401562 /oracle/oradata/testdb29/redo02.log INACTIVE 231 400998 /oracle/oradata/testdb29/redo03.logIn unserem Beispiel ist die Datei redo02.log die aktuelle Online-Redo-Log-Datei.
Wir wollen nun den oben beschriebenen Vorgang testen. Die Datenbank muss nun zuerst einmal durch ein Cold Backup gesichert werden. Nun wird eine neue Tabelle namens big im Tabelspace users erzeugt, ein Datensatz eingefügt und mit COMMIT abgeschlossen. Die Transaktion ist demnach beendet und der Datensatz befindet sich (natürlich erst nach dem Checkpoint) irgendwo in der Datei /oracle/oradata/testdb29/users01.dbf (da der Tablespace users nur aus dieser Datei besteht).
create table big(s1 int) tablespace users; insert into big values(1); commit;Angenommen die Datei users01.dbf wird beschädigt und Sie ersetzen diese durch deren Sicherungsdatei. Die Tabelle big samt Inhalt befindet sich selbstverständlich nicht in dieser Datei, da die Tabelle big zum Zeitpunkt der Sicherung noch nicht existierte. Alle notwendigen Informationen für ein Rollforward befinden sich jedoch im aktuellen Online-Redo-Log (falls kein Log-Switch erfolgte) - und genau das machen wir uns nunmehr zu Nutze.
Als erstes fahren wir die Instanz herunter und kopieren die gesicherte Datei users01.dbf nach /oracle/oradata/testdb29. Nun fahren Sie die Instanz normal hoch.
shutdown abort; host cp /backup01/users01.dbf /oracle/oradata/testdb29/ exit startup; ... Datenbank mit Mount angeschlossen. ORA-01113: Für Datei '3' ist eine Datenträger-Recovery notwendig ORA-01110: Datendatei 3: '/oracle/oradata/testdb29/users01.dbf'Da die eben wiederhergestellte Datei users01.dbf nicht die aktuelle Version der Datei ist, sondern lediglich eine wiederhergestellte Sicherungskopie, ist ein Datenträger-Recovery notwendig. Da sich aber alle notwendigen Informationen im aktuellen Online-Redo-Log befinden, ist dies kein Problem. Die nach der Sicherung erstellte Tabelle ist selbstverständlich wieder da.
recover datafilfe '/oracle/oradata/testdb29/users01.dbf';
select * from big;
S1
---------
1
Hierfür ist es notwendig, dass Sie als erstes die Tabelle big löschen und danach ein Cold Backup durchführen (für das Cold Backup können Sie am besten das erstellte Skript benutzen). Als nächstes müssen Sie herausfinden, welches Online-Redo-Log die aktuelle Online-Redo-Log-Datei darstellt.
select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ INACTIVE 232 401561 /oracle/oradata/testdb29/redo01.log INACTIVE 233 401562 /oracle/oradata/testdb29/redo02.log CURRENT 234 401564 /oracle/oradata/testdb29/redo03.logNehmen wir an, dass im Augenblick die Transaktionen in der Online-Redo-Log-Datei redo03.log mit der LSN 234 gespeichert werden. Nun erstellen Sie die Tabelle big erneut und führen einen oder zwei Log-Switches durch.
create table big(s1 int) tablespace users; insert into big values(1); commit; alter system switch logfile; alter system switch logfile;Dadurch befindet sich die Transaktion nicht mehr im aktuellen Online-Redo-Log, sondern in einem der beiden anderen Online-Redo-Logs.
select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ INACTIVE 235 422305 /oracle/oradata/testdb29/redo01.log CURRENT 236 422306 /oracle/oradata/testdb29/redo02.log INACTIVE 234 421564 /oracle/oradata/testdb29/redo03.logNehmen wir an, dassdie LSN 234 noch vorhanden ist. Demnach ist auch noch die Transaktion vorhanden und eine Wiederherstellung sollte möglich sein.
Wie im oberen Beispiel nehmen wir an, die Datei users01.dbf wird beschädigt und Sie ersetzen diese durch deren Sicherungsdatei. Die Tabelle big samt Inhalt befindet sich selbstverständlich nicht in dieser Datei, da die Tabelle big zum Zeitpunkt der Sicherung noch nicht existierte. Alle notwendigen Informationen für ein Rollforward befinden sich jedoch in einer der Online-Redo-Log-Dateien (nicht jedoch in der aktuellen Online-Redo-Log-Datei) und genau das machen wir uns nunmehr zu Nutze.
Als erstes fahren wir die Instanz herunter und kopieren die gesicherte Datei users01.dbf nach /oracle/oradata/testdb29. Nun fahren Sie die Instanz normal hoch.
shutdown abort; host cp /backup01/users01.dbf /oracle/oradata/testdb29/ exit startup; ... Datenbank mit Mount angeschlossen. ORA-01113: Für Datei '3' ist eine Datenträger-Recovery notwendig ORA-01110: Datendatei 3: '/oracle/oradata/testdb29/users01.dbf'Laut Ausgabe ist für die Datei 3 ein Datenträger-Recovery notwendig. Alle notwendigen Transaktionen befinden sich in der Online-Redo-Log-Datei mit der LSN 234, die noch vorhanden ist (redo03.log).
recover datafilfe '/oracle/oradata/testdb29/users01.dbf';
select * from big;
S1
---------
1
Ale Ergebnis zeigt sich hier, dass bei Vorhandensein der notwendigen Transaktionsdaten eine Wiederherstellung auch im NOARCHIVELOG möglich ist.
Als initialer Schritt wird wiederum die Tabelle big gelöscht (um den Ursprungszustand wieder herzustellen) und ein Cold-Backup erzeugt. Nun müssen Sie wieder herausfinden, welches Online-Redo-Log die aktuelle Online-Redo-Log-Datei darstellt. Hierfür können wir wieder die oben beschrieben Abfrage benutzen.
select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ INACTIVE 235 422305 /oracle/oradata/testdb29/redo01.log INACTIVE 236 422306 /oracle/oradata/testdb29/redo02.log CURRENT 237 442308 /oracle/oradata/testdb29/redo03.logAngenommen im Augenblick werden die Transaktionen in der Online-Redo-Log-Date redo03.log mit der LSN 237 gespeichert. Nun erstellen Sie die Tabelle big erneut, fügen einen Datensatz hinzu und führen anschließend drei Log-Switches durch.
create table big(s1 int) tablespace users; insert into big values(1); commit; alter system switch logfile; alter system switch logfile; alter system switch logfile;Dadurch befindet sich die Transaktion weder im aktuellen Online-Redo-Log, noch in einem der beiden anderen Online-Redo-Logs. In der unten ausgeführten Abfrage ist zu erkennen, dass die LSN 237 nicht mehr vorhanden ist, die Transaktion also nicht mehr verfügbar ist.
select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ INACTIVE 238 443218 /oracle/oradata/testdb29/redo01.log INACTIVE 239 443219 /oracle/oradata/testdb29/redo02.log CURRENT 240 443220 /oracle/oradata/testdb29/redo03.logWir nehmen nunmehr an, die Datei users01.dbf wird beschädigt und Sie ersetzen diese durch deren Sicherungsdatei. Alle notwendigen Informationen für ein Rollforward befinden sich jedoch nicht mehr in einer der Online-Redo-Log-Dateien.
Als erstes fahren wir die Instanz9 herunter und kopieren die gesicherte Datei users01.dbf nach /oracle/oradata/testdb29. Nun fahren Sie die Instanz normal hoch.
shutdown abort; host cp /backup01/users01.dbf /oracle/oradata/testdb29/ exit startup; ... Datenbank mit Mount angeschlossen. ORA-01113: Für Datei '3' ist eine Datenträger-Recovery notwendig ORA-01110: Datendatei 3: '/oracle/oradata/testdb29/users01.dbf'Wenn wir nun probieren, ein Datenträger-Recovery durchzuführen, so fragt Oracle nach der entsprechenden Datei, in der die Transaktionen drinstehen, in diesem Fall nach der Dateien mit der LSN 237. Da diese jedoch nicht mehr vorhanden ist bzw. eine andere LSN hat, schlägt ein Recovery fehl.
recover datafilfe '3';
...
Log angeben: {<RET=suggested | filename | AUTO | Cancel}
Die einzige Möglichkeit ist nunmehr ein vollständiges Wiederherstellen der Datenbank unter Verlust der Tabelle big.
Unglücklicherweise befinden sich diese Änderungen nicht mehr in den Online-Redo-Log-Dateien, so dass eine der weiter oben beschriebenen Methoden hier leider nicht in Frage kommt. Nun wird die Datei temp01.dbf beschädigt und die Datenbank muss wiederhergestellt werden.
Da sich die Transaktionen nicht mehr in den Online-Redo-Log-Dateien befinden, ist zuerst einmal von einer kompletten Wiederherstellung auszugehen. Dies würde jedoch einen Verlust der wichtigen Daten vom Montag 10:00 Uhr bedeuten. Daher ist es möglich, hier einen anderen Weg zu wählen. Da sich im Tablespace temp keine wichtigen Daten befinden, kann dieser gelöscht und neu erzeugt werden.
Um dieses Scenario einmal genauer zu betrachten, legen wir wieder die Datenbank testdb29 aus dem vorigen Kapiteln zugrunde. Voraussetzung ist wiederum, dass ein Cold Backup (angenommen Sonntag 22:00 Uhr) dieser Datenbank existiert. Nun (angenommen Montag 10:00 Uhr) erstellen wir die wichtige Datei big und füllen diese mit Datensätzen. Leider wird die Datei temp01.dbf im Laufe des Montags beschädigt. Ein erneutes Hochfahren der Instanz scheitert demzufolge. Sie können die beschädigte Datei, die das Öffnen der Datenbank verhindert, mit der Anweisung
ALTER DATABASE DATAFILE datafilename OFFLINE DROP;löschen, anschließend die Datenbank öffnen, den Tablespace löschen und danach den Tablespace neu erstellen. Nun können Sie ganz normal weiterarbeiten.
Anmerkung: Vergessen Sie nicht, bei einem shutdown immediate den angemeldeten Benutzern eine Nachricht zukommen zu lassen, bevor Sie die Datenbank herunterfahren. Sie werden es Ihnen danken.
Betrachten wir wieder die Datenbank testdb29. Diese Datenbank sollte sich im ArchiveLog-Modus befinden. Sie müssen die Datenbank hierfür lediglich herunterfahren und folgende Einträge in die init.ora vornehmen:
log_archive_start = true log_archive_dest_1 = "location=/oracle/oradata/testdb29/archive" log_archive_format = %%ORACLE_SID%%T%TS%S.ARCDurch den ersten Eintrag wird der Hintergrundprozess Archiver, der die Online-Redo-Log-Dateien sichert, automatisch gestartet. Durch den zweiten Eintrag wird das Ziel angegeben, in das die Online-Redo-Log-Dateien gesichert werden sollen. Durch den dritten Eintrag wird lediglich das Format der gesicherten Online-Redo-Log-Dateien definiert.
Anschließend müssen Sie die Datenbank im Status MOUNT versetzen und den Modus in ArchiveLog ändern. Anschließend kann dann die Datenbank geöffnet werden.
ALTER DATABASE ARCHIVELOG; ALTER DATABASE OPEN;Wir nehmen an, dass diese Datenbank testdb29 durch ein Offline-Backup ganz normal gesichert wurde. Der Sicherungsordner sei /backup01. Hier sollte sich nun eine Sicherung aller Datendateien, Controldateien und Online-Redo-Log-Dateien befinden. Nun erstellen wir eine Tabelle PRODUKT im Tablespace USERS und tragen dort zwei Beispielprodukte ein.
select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ INACTIVE 160 563628 /oracle/oradata/testdb29/redo03.log CURRENT 161 564809 /oracle/oradata/testdb29/redo02.log INACTIVE 159 561580 /oracle/oradata/testdb29/redo01.log create table produkt(nr int, productname char(10)) tablespace users; insert into produkt values(1,'Milch'); insert into produkt values(2,'Käse'); commit; alter system switch logfile;Angenommen, dass sich die After-Images beider Produkte (also die Produkte selber) in der Online-Redo-Log-Datei mit der LSN 161 (current) befinden. Nach dem Hinzufügen wurde ein Log-Switch ausgeführt. Das bedeutet, dass die Online-Redo-Log-Datei mit der LSN 161 nicht mehr die aktuelle Online-Redo-Log-Datei ist. Nun fügen wir zwei weitere Produkte hinzu.
select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ INACTIVE 160 563628 /oracle/oradata/testdb29/redo03.log ACTIVE 161 564809 /oracle/oradata/testdb29/redo02.log CURRENT 162 565003 /oracle/oradata/testdb29/redo01.log insert into produkt values(3,'Butter'); insert into produkt values(4,'Kekse'); commit; alter system switch logfile;Angenommen, dass sich die After-Images dieser beiden Produkte in der Online-Redo-Log-Datei mit der LSN 162 befinden. Die ersten beiden Produkte sind natürlich weiterhin in der Online-Redo-Log-Datei mit der LSN 161. Nun fügen wir zwei weitere Produkte hinzu.
select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ CURRENT 163 565008 /oracle/oradata/testdb29/redo03.log INACTIVE 161 564809 /oracle/oradata/testdb29/redo02.log INACTIVE 162 565003 /oracle/oradata/testdb29/redo01.log insert into produkt values(5,'Waffeln'); insert into produkt values(6,'Brot'); commit; alter system switch logfile;Angenommen, dass sich die After-Images dieser beiden neuen Produkte in der Online-Redo-Log-Datei mit der LSN 163 befinden. Die ersten Produkte sind natürlich weiterhin in der Online-Redo-Log-Datei mit der LSN 161 bzw. in der Online-Redo-Log-Datei mit der LSN 162. Ausschnitt aus den Online-Redo-Log-Dateien
LSN 161 1 Milch
2 Käse
LSN 162 3 Butter
4 Kekse
LSN 163 5 Waffeln
6 Brot
Nun fügen wir zwei weitere Produkte hinzu.
alter system switch logfile; select v1.status,v1.sequence#,v1.first_change#,v2.member from v$log v1,v$logfile v2 where v1.group# = v2.group# ; STATUS SEQUENCE# FIRST_CHANGE# MEMBER ------------------------------------------------------------------ ACTIVE 163 565008 /oracle/oradata/testdb29/redo03.log CURRENT 164 565013 /oracle/oradata/testdb29/redo02.log INACTIVE 162 565003 /oracle/oradata/testdb29/redo01.log insert into produkt values(7,'Honig'); insert into produkt values(8,'Marmelade'); commit; alter system switch logfile;Angenommen, dass sich die After-Images dieser beiden neuen Produkte in der Online-Redo-Log-Datei mit der LSN 164 befinden. Die ersten beiden Produkte, die sich in der Online-Redo-Log-Datei mit der LSN 161 befinden, sind jedoch nicht mehr verfügbar. Diese Online-Redo-Log-Datei wurde überschrieben. Da sich die Datenbank jedoch im Modus ARCHIVELOG befindet, wurden die nicht aktuellen Online-Redo-Log-Dateien durch den Hintergrundprozess Archiver bereits weggesichert. Sie müssten sich wohlbehalten in genau dem Ordner, den wir in der INIT-Datei als Parameter angegeben haben.
cd /oracle/oradata/testdb29/archive ls -1 TESTT001S00163.ARC TESTT001S00162.ARC TESTT001S00161.ARC
shutdown immediate;
host
rm /oracle/oradata/testdb29/users01.dbf
exit
startup
...
Datenbank mit Mount angeschlossen.
ORA-01157: Datendatei 3 kann nicht identifiziert/gesperrt werden
Siehe DBWR-Trace-Datei.
ORA-01110: Datendatei 3: '/oracle/oradata/testdb29/users01.dbf'
Wir stellen nun die Datendatei users01.dbf von der Sicherung wieder her und versuchen nun erneut, die Datenbank testdb29 zu öffnen.
host cp /backup01/users01.dbf /oracle/oradata/testdb29/ exit alter database open; * FEHLER in Zeile 1: ORA-01113: Für Datei '3' ist eine Datenträger-Recovery notwendig ORA-01110: Datendatei 3: '/oracle/oradata/testdb29/users01.dbf'Wir müssen nun die Transaktionen, die seit der Sicherung durchgeführt wurden, erneut durchführen lassen. Dies wird durch ein Recovery erreicht. Da sich in unserem Fall die ganze Recovery-Aktion nur auf eine Datendatei bezieht, muss natürlich auch nur diese eine Datendatei durch ein Recovery wiederhergestellt werden. Für das Recovery der Datendatei users01.dbf benutzen Sie folgende Anweisung:
RECOVER DATAFILE '/oracle/oradata/testdb29/users01.dbf';Oracle versucht nun zu ermitteln, welche Redo-Log-Dateien angewendet werden müssen. In unserem Falle sind es die Dateien mit den LSN 161, 162, 163 und 164. Die Redo-Log-Datei mit der LSN 161 befindet sich jedoch nicht mehr unter den Online-Redo-Log-Dateien. Sie wurde jedoch bereits archiviert.
Nun fragt Oracle: Log angeben. Hier können Sie entweder mit ENTER den Vorschlag von Oracle annehmen, eine eigene Datei angeben (wenn Sie es wirklich besser wissen), oder die Anweisung AUTO eingeben. AUTO bedeutet, dass Oracle selbständig sich die richtigen archivierten Redo-Log-Dateien heraussucht und die Datendatei wiederherstellt. Wie Sie in dem oberen Beispiel erkennen können, ist im Anschluss alles ordnungsgemäß wieder vorhanden.
Hot Backups werden Tablespace-bezogen durchgeführt. Zuerst wird der Tablespace für die Sicherung vorbereitet. Anschließend werden die Dateien des entsprechenden Tablespaces mit Hilfe eines Betriebssystembefehls gesichert und nach dem Sichern der beteiligten Dateien wird die Sicherung.
ALTER TABLESPACE users01 BEGIN BACKUP; host cp /oracle/oradata/testdb29/users01.dbf /backup01/ exit ALTER TABLESPACE users01 END BACKUPSollten Sie versuchen, die entsprechenden Dateien ohne ALTER TABLESPACE BEGIN BACKUP und ALTER TABLESPACE END BACKUP zu sichern, sind diese gesicherten Dateien für eine Wiederherstellung unbrauchbar. Nachdem ein Tablespace mit ALTER TABLESPACE BEGIN BACKUP in den Hot Backup Modus versetzt wurde, ändert sich das interne Verhalten. Die erste gravierende Veränderung bezieht sich auf das Aufzeichnen der Änderungen in den Redo-Log-Dateien. Es wird jetzt nicht mehr lediglich ein After-Image des verändernden Datensatzes aufgezeichnet, sondern jeweils ein Before Image des gesamten Blockes (Oracle-Block - nicht Betriebssystem-Block!), in dem sich der veränderte Datensatz befindet. Desweiteren wird die SCN zu Beginn des Befehls ALTER TABLESPACE BEGIN BACKUP in den Headern der einzelnen Datendateien 'eingefroren', das heißt, bis zum Befehl ALTER TABLESPACE END BACKUP bleibt diese SCN identisch. Folglich befindet sich in der Sicherung der Datendateien in jedem Falle die SCN, die zu Beginn der Sicherung aktuell war. Diese Vorgehensweise ist notwendig, da Oracle nicht weiss, zu welchen Zeitpunkt das Betriebssystem den Block mit dem Header der Datendatei sichert. Würde die SCN während der Sicherung nicht eingefroren werden, so könnte die SCN in den Datendateien der Sicherung größer als die SCN sein, die zu Beginn von ALTER TABLESPACE BEGIN BACKUP aktuell war. Für das korrekte Anwenden der Redo-Log-Einträge ist es jedoch zwingend erforderlich, dass die SCN der gesicherten Datendateien der SCN zu Beginn der Sicherung entsprechen. Nun kommen wir zur zweiten wichtigen Änderung in der Arbeitsweise. In den Redo-Log-Einträgen werden gesamte Block-Images gespeichert. Warum?
Ein Oracle-Block ist in der Regel ein Vielfaches eines Betriebssystem-Blockes. Die Größe eines Oracle-Blockes wird in der entsprechenden INI-Datei durch den Parameter DB_BLOCK_SIZE (z. B. 8192) festgelegt. Gebräuchliche Werte liegen zwischen 2K und 8k. Wenn das Betriebssystem aber mit einer Blockgröße von 2048 Byte arbeitet, so werden beim Sichern der Datendateien jeweils Blöcke von 2048 Byte gesichert. Ein Oracle-Block wird also nicht als Ganzes zur gleichen Zeit gesichert, sondern die Betriebssystemblöcke können zu verschiedenen Zeiten durch das Betriebssystem gesichert werden. Es ist demnach auch möglich, das in der Sicherung ein Oracle-Block nicht konsistent ist. Nehmen wir hierfür folgendes Beispiel an:
8K entspricht einem Oracle-Block
1 Milch 1 DM 2K 1 BS Block 2 Käse 3 DM 3 Butter 5 DM 4 Brot 2 DM 2K 1 BS Block 5 Wurst 7 DM 6 Sekt 8 DM 2K 1 BS Block 7 Äpfel 11 DM 8 Trauben 9 DM 2K 1 BS Block 9 Grütze 12 DM
Sie sehen einen Oracle-Block bestehend aus 4 Betriebssystemblöcken. Angenommen gegen 12:00 Uhr soll dieser Block gesichert werden (natürlich im Zuge der Sicherung der gesamten Datendatei bzw. gesamten Datendateien des entsprechenden Tablespaces). Dieser Block gehört zur Datendatei usr02.dbf und diese wiederum zum Tablespace users2. Gegen 12:00 Uhr wird also dieser Tablespace in den Hot Backup Modus versetzt
alter tablespace users2 begin backup;Gegen 12:01 wird der Betriebssystemblock gesichert. Dieser Betriebssystemblock sieht dann gesichert folgendermaßen aus:
1 Milch 1 DM 2K 1 BS Block 2 Käse 3 DM 3 Butter 5 DMGegen 12:02 Uhr wird der Preis aller Produkte um 100% erhöht:
UPDATE products SET unitprice=unitprice*2; COMMIT;In diesem Fall werden die entsprechenden Seiten in den Daten-Buffer geladen und entsprechen verändert. Dadurch werden diese Blöcke zu Dirty-Blocks und im Zuge des nächsten Checkpoints auf der Platte aktualisiert. Nehmen wir an, dass ein Checkpoint gegen 12:03 Uhr auftrat und die Dirty-Buffers zurück in die Datendateien geschrieben wurden. Folglich sieht der Oracle-Block 12:03 Uhr folgendermassen aus:
1 Milch 2 DM 2K 1 BS Block 2 Käse 6 DM 3 Butter 10 DM 4 Brot 4 DM 2K 1 BS Block 5 Wurst 14 DM 6 Sekt 16 DM 2K 1 BS Block 7 Äpfel 22 DM 8 Trauben 19 DM 2K 1 BS Block 9 Grütze 24 DMGegen 12:04 Uhr sichert nun das Betriebssystem den zweiten, dritten und vierten Betriebssystemblock. Der gesicherte Oracle-Block würde zum Zeitpunkt 12:05 Uhr nun folgendermassen aussehen:
1 Milch 1 DM 2K 1 BS Block 2 Käse 3 DM 3 Butter 5 DM 4 Brot 4 DM 2K 1 BS Block 5 Wurst 14 DM 6 Sekt 16 DM 2K 1 BS Block 7 Äpfel 22 DM 8 Trauben 19 DM 2K 1 BS Block 9 Grütze 24 DMDer Oracle-Block ist in sich nicht mehr konistent. Ein Teil der Preise wurde verändert, ein anderer noch nicht. Hierbei spricht man allgemein von einem Block-Split. Bei einem Recovery würden wir vor einem Problem stehen. Aus genau diesem Grund wird in der Online-Redo-Log-Datei bei einer Veränderung ein Before-Image des Blockes aufgezeichnet, also ein Image mit den alten Preisen.
Wird nun die entsprechende Sicherung (mit teilweise gesplitteten Blöcken) wiederhergestellt, so ist die SCN ja immer noch die, die zum Zeitpunkt des ALTER TABLESPACE BEGIN BACKUP (in unserem Beispiel 100) aktuell war. Da die während der Sicherung veränderten Oracle-Blöcke in den Online-Redo-Log-Dateien stehen, können diese beim Wiederherstellen der Sicherung schnell die inkonsistenten Oracle-Blöcke ersetzen.
Nachdem die Sicherung der entsprechenden Datendateien beendet ist, wird der Hot Backup Modus durch ALTER TABLESPACE END BACKUP wieder aufgehoben. Nachdem der Hot Backup Modus aufgehoben wurde, wird die Checkpoint SCN in den Headern der einzelnen beteiligten Datendateien wieder auf den aktuellen Stand gesetzt und alles geht seinen gewohnten Gang weiter.
Die Konsequenz dieser Arbeitsweise ist natürlich, dass zwischen ALTER TABLESPACE BEGIN BACKUP und ALTER TABLESPACE END BACKUP der Log-Verkehr zunimmt, sprich die Redo-Log-Dateien nehmen an Größe stärker zu als sonst. Folglich sollte man das Hot Backup nur zu Zeiten geringer DML-Aktivität durchführen, also zu Zeiten, wo wenig eingefügt, geändert und gelöscht wird. Desweiteren sollten Sie jeden Tablespace einzeln sichern, um die Zeit, die der Tablespace sich im Hot-Backup-Mode befindet, zu minimieren.
Richtig:
ALTER TABLESPACE user BEGIN BACKUP; HOST; cp /oracle/oradata/testdb29/usr02.dbf /backup01/ cp /oracle/oradata/testdb29/usr03.dbf /backup01/ EXIT ALTER TABLESPACE user END BACKUP; ALTER TABLESPACE idx BEGIN BACKUP; HOST; cp /oracle/oradata/testdb29/idx02.dbf /backup01/ cp /oracle/oradata/testdb29/idx03.dbf /backup01/ EXIT ALTER TABLESPACE idx END BACKUP;Falsch:
ALTER TABLESPACE user BEGIN BACKUP; ALTER TABLESPACE idx BEGIN BACKUP; HOST; cp /oracle/oradata/testdb29/usr02.dbf /backup01/ cp /oracle/oradata/testdb29/usr03.dbf /backup01/ cp /oracle/oradata/testdb29/idx02.dbf /backup01/ cp /oracle/oradata/testdb29/idx03.dbf /backup01/ EXIT ALTER TABLESPACE user END BACKUP; ALTER TABLESPACE idx END BACKUP;Für das Wiederherstellen einer Sicherung benötigen Sie mindestens alle Redo-Log-Dateien, die zwischen ALTER TABLESPACE ... BEGIN BACKUP und ALTER TABLESPACE ... END BACKUP erzeugt wurden. Dies reicht aber dann auch nur für ein Incomplete Recovery. Für ein Complete Recovery benötigen Sie alle Redo-Log-Dateien von Beginn der Sicherung an.
Vorgehensweise beim Hot Backup:
ARCHIVE LOG LIST;Falls sich die Datenbank noch nicht im ArchiveLog-Modus befindet, so wechseln Sie in den ArchiveLog-Modus. Hierbei muß die Datenbank gemountet sein:
alter database mount: alter database archivelog; archive log start; alter database open;
archive log list;Angenommen, dass die aktuelle Log Sequenz die Nummer 3 ist. Das heisst, die LSN 3 ist die erste LSN, die für das spätere Wiederherstellen erforderlich ist.
ALTER TABLESPACE users BEGIN BACKUP
ALTER TABLESPACE users END BACKUP
archive log list;Angenommen, dass die aktuelle Log Sequenz die Nummer 4 ist. Das heisst, die LSN 4 ist die letzte LSN, die für das spätere Wiederherstellen zwingend erforderlich ist. Für ein Complete Recovery sind natürlich alle Redo-Log-Dateien von LSN 3 beginnend, notwendig.
select * from v$backup;
archive log list;Angenommen, dass die erste LSN, ist die LSN 5.
ALTER TABLESPACE user2 BEGIN BACKUP host cp /oracle/oradata/testdb29/usr02.dbf /backup01/ exit ALTER TABLESPACE user2 END BACKUP
create table produkt(nr int, productname char(10)) tablespace users; insert into produkt values(1,'Milch'); insert into produkt values(2,'Käse'); insert into produkt values(3,'Käse'); commit; alter system switch logfile; archive log list;Angenommen, dass die nächste zu archivierende Log-Sequenz die 6 ist, muß die LSN 5 schon archiviert worden sein. Im Archivierungsorder müsste diese Datei schon zu finden sein (arc00005.001). Die After-Images der drei eben eingefügten Datensätze befinden sich demnach in der Datei arc00005.001.
insert into produkt values(4,'Brot'); insert into produkt values(5,'Kekse'); insert into produkt values(6,'Mehl'); commit; alter system switch logfile; archive log list;Angenommen, dass die nächste zu archivierende Log-Sequenz die 7 ist, muß die LSN 6 schon archiviert worden sein. Im Archivierungsorder müsste diese Datei schon zu finden sein (arc00006.001). Die After-Images der drei eben eingefügten Datensätze befinden sich demnach in der Datei arc00006.001.
insert into produkt values(7,'Tee'); insert into produkt values(8,'Saft'); insert into produkt values(9,'Nektar'); insert into produkt values(10,'Obst'); commit; alter system switch logfile; archive log list;Angenommen, dass die nächste zu archivierende Log-Sequenz die 8 ist, muß die LSN 7 schon archiviert worden sein. Im Archivierungsorder müsste diese Datei schon zu finden sein (arc00007.001). Die After-Images der drei eben eingefügten Datensätze befinden sich demnach in der Datei arc00007.001.
shutdown immediate; host rm /oracle/oradata/testdb29/usr2.dbf exit
startup;
...
Datenbank mit MOUNT angeschlossen.
ORA-01157: Datendatei 7 kann nicht identifiziert/gesperrt werden
Siehe DBWR-Trace-Datei.
ORA-01110: Datendatei 7: '/oracle/oradata/testdb29/users02.dbf'
alter database open; * Fehler in Zeile 1: ORA-01113: Für Datei '7' ist eine Datenträger-Recovery notwendig ORA-01110: Datendatei 7: '/oracle/oradata/testdb29/users02.dbf'
RECOVER DATABASE testdb29; ALTER DATABASE OPEN;
ALTER DATABASE BACKUP CONTROLFILE TO 'control01.bkp';Hierdurch wird die Controldatei in einer Binärdatei namens control01.bkp gesichert.
alter database backup controlfile to '/backup/control.bkt';Recover
shutdown immediate; -- Control-Dateien kopieren startup mount; recover database until cancel using backup control file; -- Mit CANCEL abbrechen. alter database open resetlogs;
alter database backup controlfile to trace;Das erstellte Skript finden Sie in dem Ordner, der als USER_DUMP_DEST in der INI-Datei definiert wurde. In unserem Fall liegt die entsprechende Datei in /oracle/admin/testdb29/udump. In diesem Skript finden Sie die entsprechende CREATE CONTROLFILE-Anweisung. Folgende Schritte müssen Sie durchführen, um eine neue Control-Datei zu erstellen:
ALTER DATABASE CREATE DATAFILE 'dateiname'Nun müssen Sie nur noch ein Recovery durchführen, um den aktuellen Stand der Datei zu erhalten. Lassen Sie uns ein Beispiel durchspielen. Als Grundlage dient wiederum unsere Datenbank testdb29 mit dem Tablespace user2, bestehend aus den beiden Dateien usr02.dbf und usr03.dbf. Wir werden als erstes eine weitere dritte Datei usr04.dbf hinzufügen.
alter tablespace user2 add datafile '/oracle/oradata/testdb29/usr04.dbf' size 5m;Anschließend werden wir in diesem Tablespace eine Tabelle erzeugen und dort einige Datensätze eintragen und einen Log-Switch erzwingen. Nun werden wir die Instanz herunterfahren, die Datei usr04.dbf löschen und versuchen, die Instanz wieder hochzufahren.
create table produkt(nr int, productname char(10)) tablespace users;
insert into produkt values(1,'Milch');
insert into produkt values(2,'Butter');
insert into produkt values(3,'Käse');
commit;
alter system switch logfile;
shutdown immediate;
host;
rm /oracle/oradata/testdb29/usr04.dbf
exit
startup;
...
Datenbank mit Mount angeschlossen.
ORA-01157: Datendatei 9 kann nicht identifiziert/gesperrt werden
Siehe DBWR-Trace-Datei.
ORA-01110: Datendatei 9: '/oracle/oradata/testdb29/users04.dbf'
Wir sehen in diesem Beispiel, dass Oracle natürlich die beschädigte Datei usr04.dbf zum Öffnen benötigt. Hierfür können wir einfach die Datei erstellen und probieren, die Datenbank erneut zu öffnen.
alter database create datafile '/oracle/oradata/testdb29/users04.dbf'; alter database open; * FEHLER in Zeile 1: ORA-01113: Für Datei '9' ist eine Datenträger-Recovery notwendig ORA-01110: Datendatei 9: '/oracle/oradata/testdb29/users01.dbf'Natürlich ist noch ein Datenträger-Recovery für die Datei users04.dbf notwendig. Hierfür müssen alle Redo-Log-Dateien seit Erstellen der beschädigten Datendatei vorhanden sein. Die notwendigen Transaktionen werden dann auf die neu erstellte Datendatei users04.dbf angewendet, so dass diese Datei dann den Stand der beschädigten Datei hat.
recover datafile '/oracle/oradata/testdb29/users04.dbf'; alter database open;Woher weiß aber Oracle, wo die notwendigen anzuwendenden Transaktionen für die Datei beginnen? Oracle speichert in der Control-Datei die aktuelle SCN beim Erstellen einer Datei. Ab hier muss dann begonnen werden, die entsprechenden Transaktionen vorwärts zu rollen, um für die Datendatei den aktuellen Stand wiederherzustellen.
Hinweis: Diese Methode funktioniert nur für Datendateien, die erstellt wurden, nachdem die Datenbank in den ArchiveLog-Modus wechselte.
RECOVER DATAFILE datafilename; RECOVER TABLESPACE tablespacename; RECOVER DATABASE;Sie können die RECOVER-Anweisung entweder mit SQLPLUS oder im RMAN durchführen.
Eine ungewollte unvollständige Wiederherstellung könnte durchgeführt werden müssen, wenn Sie bemerken, dass bei der Wiederherstellung eine Redo-Log-Datei fehlt. Prinzipiell gibt es drei verschiedene unvollständige Wiederherstellungsmöglichkeiten
ALTER DATABASE OPEN RESETLOGSgeöffnet werden. Hierdurch werden die Online-Redo-Log-Dateien zurückgesetzt, die anschließend wieder benutzt werden können.
shutdown immediate; host; cp /oracle/oradata/testdb29/* /backup01 exitNehmen wir an, Sie fahren die Datenbank am Montag gegen 8:00 Uhr wieder hoch. Folgendes passiert dann in folgenden zeitlichen Abständen:
create table produkt(nr int, productname char(10)) tablespace users;
insert into produkt values(1,'Milch'); commit;
insert into produkt values(2,'Käse'); commit;
insert into produkt values(3,'Butter'); commit;
drop table produkt;
alter system switch logfile;
shutdown immediate; host; cp /backup01/* /oracle/oradata/testdb29/ exitNun versuchen Sie die Instanz zu erneut hochzufahren und zu öffnen. Es ist ein Recovery notwendig. Wir müssen die Datenbank bis zum Zeitpunkt Montag 8:25 Uhr wiederherstellen. Hierfür führen Sie eine zeitbasierte Wiederherstellung durch
RECOVER DATABASE UNTIL TIME 03.02.2003 08:25:00Anschließend öffnen Sie die Datenbank mit der Option RESETLOGS, um die Online-Redo-Logs zurückzusetzen.
ALTER DATABASE OPEN RESETLOGSDie Tabelle mit den Produkten ist wieder da, da das Löschen der Tabelle erst nach 8:25:00 geschehen ist.
Wir wollen nun dieses Beispiel einmal praktisch umsetzen. Voraussetzung hierfür ist, dass sich die Datenbank im ArchiveLog-Modus befindet und der Archiver-Prozess läuft.
archive log list;Im ersten Schritt führen wir eine vollständige Sicherung als Cold Backup durch
shutdown immediate; host; cp /oracle/oradata/testdb29/* /backup01/ exitIm zweiten Schritt starten fahren wir die Instanz wieder hoch und schauen uns das aktuelle Log an. Wir erzeugen dann eine Tabelle mitarbeiter im Tablespace users und fügen dort zwei Datensätze ein. Diese Datensätz stehen demnach im Log Nummer 9.
startup; archive log list; create table mitarbeiter(MiNr int, MiName varchar2(30)) tablespace users; insert into mitarbeiter values(1,'Anna'); insert into mitarbeiter values(2,'Berta'); commit;Jetzt führen wir zwei Log-Switches durch.
alter system switch logfile; alter system switch logfile; archive log list;Durch den Archiver-Prozess wurden folgende Logs gesichert.
ls -1 ARC00007.001 ARC00008.001 ARC00009.001 ARC00010.001Wir fügen zwei Datensätze ein. Diese Datensätz stehen demnach im Log Nummer 11.
archive log list; insert into mitarbeiter values(3,'Carla'); insert into mitarbeiter values(4,'Doris'); commit;Jetzt führen wir zwei Log-Switches durch.
alter system switch logfile; alter system switch logfile; archive log list;Durch den Archiver-Prozess wurden folgende Logs gesichert.
ARC00007.001 ARC00008.001 ARC00009.001 ARC00010.001 ARC00011.001 ARC00012.001Wir fügen zwei wietere Datensätze ein. Diese Datensätz stehen demnach im Log Nummer 13.
archive log list; insert into mitarbeiter values(5,'Emil'); insert into mitarbeiter values(6,'Frank'); commit;Jetzt führen wir zwei Log-Switches durch.
alter system switch logfile; alter system switch logfile; archive log list;Zusammengefasst stehen folgende Redo-Einträge in folgenden archivierten Logs.
Log Nummer 9 1 Anna und 2 Berta Log Nummer 11 3 Carla und 4 Doris Log Nummer 13 5 Emil und 6 FrankJetzt wird die Datei users01.dbf des Tablespace users beschädigt. Es muss eine Wiederherstellung erfolgen. Zu allem Schaden ist auch noch das archivierte Log arc00011.001 (mit der Carla und der Doris) verloren gegangen. Die Datenbank fährt nicht mehr ordnungsgemäß hoch.
shutdown immediate;
host;
rm /oracel/ora92/rdbms/ARC00011.001
rm /oracle/oradata/testdb29/users01.dbf
exit
startup;
...
Datenbank mit Mount angeschlossen.
ORA-01157: Datendatei 7 kann nicht identifiziert/gesperrt werden
Siehe DBWR-Trace-Datei.
ORA-01110: Datendatei 7: '/oracle/oradata/testdb29/users01.dbf'
Wir versuchen nun, die Datei users01.dbf von der Offline-Sicherung wiederherzustellen und ein Recover durchzuführen.
Bedenken Sie, dass in der users01.dbf zum Zeitpunkt der Offline-Sicherung die Tabelle mitarbeiter noch nicht existiert.
host;
cp /backup01/* /oracle/oradata/testdb29/
exit
recover datafile 7;
...
ORA-00289: Vorschlag: /oracel/ora92/rdbms/ARC00009.001
Log angeben: {<RET=suggested | filename | AUTO | Cancel}
auto
Wiederherstellung nicht mehr erforderlich.
...
ORA-00308: Archive-Log '/oracel/ora92/rdbms/ARC00011.001'
kann nicht geöffnet werden.
Oracle hat hier nach den archivierten Log-Dateien gefragt, die anzuwenden sind.
Es wurde hierbei AUTO angegeben, um Oracle zu veranlassen, die archivierten Logs selbständig zu ermitteln und anzuwenden.
Leider fehlt das archivierte Log arc00011.001 (mit unserer Carla und unserer Doris).
Versuchen wir ein Cancel-basiertes Recovery der Datenbank mit der Offline-Sicherung der Datei users01.dbf. Wir geben hier nicht AUTO ein, sondern bestätigen jedes archivierte LOG mit ENTER bis zum achivierten Log arc00011.001. Dort geben wir CANCEL ein, um die Sicherung anzubrechen.
host;
cp /backup01/* /oracle/oradata/testdb29/
exit
recover database until cancel;
...
Log angeben: {<RET=suggested | filename | AUTO | Cancel}
cancel
Wie wir leider feststellen müssen war das Recovery zwar erfolgreich, ein Öffnen der Datenbank mit der Option RESETLOGS zum Zurücksetzen der Online-Redo-Log-Dateien würde fehlschlagen, da die anderen Backup-Dateien nicht 'alt' genug sind.
alter database open resetlogs; * FEHLER in Zeile 1: ORA-01152: Backup-Datei zum Wiederherstellen der Datei 1 war nicht alt genug.Die Ironie des Schicksals ist es nun, die gesamte Datenbank von der letzten Sicherung wiederherzustellen und anschließend das Cancel-basierte Recovery durchzuführen. Hiermit verlieren wir leider nicht nur den Datensatz von Carla und Doris, sondern auch alle anderen Datesätze, die nach dem LOG 10 in andere Tabellen anderer Tablespaces eingegeben wurden und deren Dateien womöglich noch in Ordnung sind.
Stefan Hietel dama.go GmbH, Robert Warnke http://rowa.giso.de