Oracle Block Corruption
Korrupte Blöcke in einer (Oracle) Datenbank sind etwas ziemlich
Unangenehmes. Vorallem wenn alles in NOLOGGING Modus läuft, also keine
Archivlogs geschrieben werden und ein Offline-Backup (Cold-Backup)
schon länger zurückliegt, da der Betriebsablauf nur kurze und seltene Downtimes für ein
Backup vorsieht. Ich habe das bis jetzt zweimal erlebt und die Ursache
dafür war immer ein Hardware-Defekt. Beim ersten Mal war es so, dass
die Verbindung vom Rechner zum Storage des öfteren einfach weg war. Das
hat wohl mit der der Zeit dazu geführt, dass immer mehr Blöcke kaputt
gingen, da das Storage mitten unter einem Schreibvorgang in einen Block
weg war. Problem ist blos, das die Datenbank sich anschließend zwar
wieder starten läßt, aber das Ganze solange niemand merkt, bis
tatsächlich mal dann eine Query über so einen kaputten Block
drübermaschiert. Beim zweiten Vorfall war die Firmware des Controllers
für das SUN 3510 Storage buggy. Der Controller hat nämlich schlicht und
ergreifend nicht gemerkt, das eine Platte einen fehlerhaften Block
gemeldet hat und hat diese Platte somit auch nicht aus dem RAID 5
Verbund genommen. Wie das allerdings alles so laufen konnte, ist nicht
mal SUN ganz klar.
Nun ja... Es empfiehlt sich deshalb regelmäßig einen Verify mit Hilfe des Oracle-Tools dbv über die Datenfiles zu machen (und natürlich ein Backup ;-). Da die Files READ-ONLY geöffnet werden,
kann man das entweder direkt auf den Live-Datenfiles tun oder besser
man checkt die Datenfiles nach dem Backup. dbv
erkennt zwar auch nicht alles, aber grobe Fehler in den Datenstrukturen
werden auf jeden Fall sichtbar. Das sollte aber zu Traffic armer Zeit
passieren, da dbv schon Einiges an I/O benötigt.
Wie so ein Fehler sich bemerkbar macht, sieht man z.B. hier:
SQL> CREATE TABLE test AS SELECT * FROM TESTTABLE;
*
FEHLER in Zeile 1:
ORA-12801: Fehler in parallelem Abfrage-Server P015 angezeigt
ORA-01578: ORACLE-Datenblock beschädigt (Datei Nr. 56, Block Nr. 357316)
ORA-01110: Datendatei 56: '/u01/data/DATENBANK/data/datenfile.dbf'
Nun in diesem Falle sollte man zuerst Oracle Metalink Note 28814.1
zu Rate ziehen und außerdem alle relevaten Logs auf der Maschine
checken, den die Wahrscheinlichkeit eines Hardwaredefekts ist recht
groß. Es kommt nun drauf an, welches Segment es erwischt hat. Wenn z.B.
ein Objekt im Data Dictionary betroffen ist, wird man meistens um ein
DB-Recovery nicht drumrumkommen. Ist ein Index betroffen, kann man oft
Glück haben und ein Index Rebuild erledigt die Sache gleich wieder. Ist
eine Tabelle hin, kann man zwar die "guten" Daten noch rausholen, aber
ohne Backup gehen dabei fast immer Daten verloren. Ist die Tabelle
partitioniert, kann man einen sog. Partitionstausch (ALTER TABLE ...
EXCHANGE PARTITION ...) machen. D.h. man erstellt eine neue Tabelle und
tauscht die defekte Partition durch diese neue Tabelle aus. Damit ist
die Tabelle dann gewissermaßen für die Anwendungen wieder "ganz". Diese
Tabelle sollte möglichst die gleichen Storagedaten der Partition haben
und natürlich
auch die gleichen Spalten. Das könnte man z.B. wie folgt machen:
CREATE TABLE test_save TABLESPACE tablespace STORAGE ( ... ) AS
SELECT * FROM test WHERE rownum=1;
Sollte das schon nicht mehr hinhauen, kann man das DBMS_REPAIR-Paket verwenden:
EXEC DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('SCHEMANAME','test');
"test" ist hier die Tabelle, die die korrupten Blöcke enthält. Damit sollte dann der CREATE TABLE ... AS SELECT ...
jetzt funken. Damit bekommt man dann z.B. auch die "guten" Daten in die neue
Tabelle, wenn man die WHERE-Klausel wegläßt. Man sollte allerdings die korrupte Tabelle nicht einfach
dropen, sondern am Besten mit ALTER TABLE test RENAME TO test_corrupted;
umbenennen. Dann hat man die Daten noch, um sich die Daten noch genauer
anschauen zu können. Man kann dann ja versuchen, die alte Tabelle neu
anzulegen und die Daten rekonstruieren. Eventl. vorhandene Constraints
wird man ausschalten müssen.
Die interessanten Dokumente dazu findet man im Oracle Metalink, wenn man
nach der Note 28814.1 sucht. Die Not 33405.1 gibt Auskunft über die
Vorgehensweise, wenn man DBMS_REPAIR.SKIP_CORRUPT_BLOCKS
verwenden möchte. Wie man an die Daten mit Hilfe der ROWID oder von
Index-Scans wieder ran kommt, beschreibt Note 61685.1 (für Oracle 8i+).
Nun... Die Moral von der Geschicht, betriebe keine Oracle-Datenbank
ohne vernünftiges Backup nicht ;-) Wenn man noch dazu keine Archivlogs
hat, ist man doppelt aufgeschmissen. Ansonsten könnte man die Datenbank
sogar aus einem uralt Cold-Backup mit den Archivlogs wieder hinbiegen.
Aber manchmal hat man eben auch das nicht. Dann bleibt nur das letzte
Coldbackup und dann sind die Daten vom diesem Backupzeitpunkt bis zum
Schluß u.U. weg. Und wenn man auch das nicht hat... Ja dann... Dann muß man damit rechnen, das Daten einfach futsch sind. DAS ist dann richtig geil ;-)
Posted at 08:45nachm. Juni 09, 2005 by cetixx in Computers | Kommentare [0]