Benutzer-Werkzeuge

Webseiten-Werkzeuge


dba:block_recover

Database Block Recover - ORA-01578: ORACLE-Datenblock beschädigt

Blockfehler treten selten auf, zum Beispiel in VM Umgebungen nach Stromausfällen.

Fehler

Ein RMan Backup läuft nicht durch und bricht mit dieser Fehlermeldung ab:

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================

RMAN-03009: failure of backup command on ORA_DISK_1 channel at 06/13/2014 17:44:33
ORA-19566: exceeded limit of 0 corrupt blocks for file /oracle/GPI/oradata/user_data_01.dbf

Anlayse

Am einfachsten kann RMAn die Anlyse durchführen. Eine Analyse mit „dbv“ ( dbv file=oracle/GPI/oradata/user_data_01.dbf BLOCKSIZE=8192 userid=„/ as sysdba“ ) zeigt zwar die Fehler, hat aber in meinen Fall die Block Error View nicht mit Daten gefüllt

Mit RMAN die Datendatei analysieren mit „VALIDATE DATAFILE“:

RMAN> VALIDATE DATAFILE 4;
 
Starting validate at 17-JUN-13
USING target DATABASE control file instead OF recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=157 device TYPE=DISK
channel ORA_DISK_1: starting validation OF datafile
channel ORA_DISK_1: specifying datafile(s) FOR validation
INPUT datafile file NUMBER=00004 name=/oracle/GPI/oradata/user_data_01.dbf
channel ORA_DISK_1: validation complete, elapsed TIME: 00:28:05
List OF Datafiles
=================
File STATUS Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
5    FAILED 0              22536        4057345         515739533 
  File Name: /oracle/GPI/oradata/user_data_01.dbf
  Block TYPE Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  DATA       0              1812504         
  INDEX      0              1351035         
  Other      4784           891369          
 
validate found one OR more corrupt blocks
See trace file /oracle/GPI/diag/rdbms/GPI/GPIDB/trace/GPI_ora_17620.trc FOR details
Finished validate at 17-JUN-13

In der Datenbank wird über RMAn die View v$database_block_corruption mit diesen Informationen gefüllt.

Über die View können nun die betroffenen Objekte ausgewertet werden:

SET linesize 120 pagesize 4000 recsep off
 
COLUMN segment_name    format a16 heading "Segment|Name"
COLUMN tablespace_name format a16 heading "Tablespace|Name"
COLUMN partition_name  format a10 heading "Partition|Name"
COLUMN owner           format a14
COLUMN relative_fno    format 9999 heading "File|No"
COLUMN segment_type    format a0  heading "Segment|Type"
COLUMN file#           format 9999 heading "File|Id"
COLUMN defekt_range    format a18 heading "defect|range"
 
prompt CHECK OF the DATABASE has detected corrupt blocks
 
SELECT COUNT(*) FROM  v$database_block_corruption;
 
prompt ...
prompt CHECK which TABLES are affected
prompt
 
SELECT ext.owner
     , ext.segment_name
	  , ext.segment_type
	  , ext.relative_fno
	  , ext.partition_name
	  , ext.tablespace_name
	  , blc.file# 
	  , blc.block# ||' for '||blc.blocks AS defekt_range
 FROM dba_extents ext
   ,  v$database_block_corruption blc
WHERE ext.file_id = blc.file# 
  AND blc.block# BETWEEN ext.block_id AND ext.block_id + ext.blocks - 1
/  

Für die aktuellste Version see auch http://orapowershell.codeplex.com/SourceControl/latest#sql/tab_defekt_blocks.sql

RMAN Backup trotz defekten Blöcken anlegen - mit "set MAXCORRUPT" defekte Blöcke überspringen

Darauf achten, dass die alten RMAN Backup NICHT gelöscht werden!
RMAN> run {
SET MAXCORRUPT FOR datafile 5 TO 10000;
BACKUP AS COMPRESSED BACKUPSET DATABASE tag 'FULL_CORRUPT';
backup CURRENT controlfile;
backup spfile;
backup archivelog ALL;
}

Die DB Blöcke aus einem alten Backup wieder einspielen

Mit „BLOCKRECOVER CORRUPTION LIST“ lassen sich alle Blöcke aus der v$database_block_corruption recovern. (Alternativ: BLOCKRECOVER mit Angabe der Block Nummer )

Alle Archive bis zum aktuellen Zeitpunkt müssen noch zur Verfügung stehen!

Datenbank ist im MOUNT Status gestartet!

Recover starten (im Beispiel war das letzte Backup ohne Fehler bereits 18 Tage alt) :

RMAN>BLOCKRECOVER CORRUPTION LIST RESTORE UNTIL TIME 'SYSDATE-18';

Die Blöcke werden nun aus dem alten Backup wieder hergestellt, pro Block geht RMAn über alle Archive und prüft ob für diesen Block Daten angewendet werden müssen, d.h. es kann etwas dauern.

Um die Performance zu steigern, kann es sich lohnen, zuerst alle Archive wieder mit RMAN auf die Platte zu legen um das wiederholte Auspacken aus dem Backup Sets zu vermeiden.

Prüfen ob alles geklappt hat

RMAN> VALIDATE DATAFILE 4;
 
Starting validate at 27-JUN-13
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=16 device TYPE=DISK
channel ORA_DISK_1: starting validation OF datafile
channel ORA_DISK_1: specifying datafile(s) FOR validation
INPUT datafile file NUMBER=00005 name=/oracle/GPI/oradata/user_data_01.dbf
channel ORA_DISK_1: validation complete, elapsed TIME: 00:00:55
List OF Datafiles
=================
File STATUS Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
5    OK     0              22286        4057345         518197271 
  File Name: /oracle/GPI/oradata/user_data_01.dbf
  Block TYPE Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  DATA       0              1742666         
  INDEX      0              1289033         
  Other      0              1003359         
 
Finished validate at 27-JUN-13
Ein neues Backup anlegen und dann die Archive und alten Backups aufräumen!

Was tun wenn kein Backup mehr exisiert?

Defekte Blöcke mit Event überspringen

Diese ist mir allerdings in einer Umgebung mit einer echten physikalischen Block Korruption nicht gelungen.

Defekte Blöcke überspringen:

ALTER system SET events=10231 trace name context forever,level 10' ;

Neue Tabelle anlegen mit den Daten der defekten Tabelle:

CREATE TABLE new_table AS SELECT * FROM defect_table;

BESSER

  • DDL der alten Tabelle ermittelten mit zum Beispiel ⇒ tab_ddl.sql Script
  • Abhängige Objekte wie Indexe der Tabelle löschen
  • Alte Tabelle umbenennen
  • Neue Tabelle mit dem DDL anlegen
  • Daten in die neue Tabelle kopieren

Daten in der neuen Tabelle prüfen und die alte Tabelle löschen:

DROP TABLE defect_table;
RENAME new_tab TO defect_table;

Trace wieder abschalten:

ALTER system SET events ’10231 trace name context off’;

Defekte Blöcke mit SQL überspringen

Falls der Block nur einen Index betrifft, diesen einfach neu anlegen.

Nur die Blöcke lesen die nicht betroffen sind:

CREATE TABLE new_tab  AS 
 SELECT FROM defect_table 
   WHERE rowid NOT IN(SELECT rowid 
	                     FROM defect_table WHERE dbms_rowid.rowid_block_number(rowid)=:block )
/								

Sind mehr als ein Block betroffen mit v$database_block_corruption entsprechend joinen! Block Range beachten!

DBMS_REPAIR

Quellen

Cookies helfen bei der Bereitstellung von Inhalten. Durch die Nutzung dieser Seiten erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Rechner gespeichert werden. Weitere Information
"Autor: Gunther Pipperr"
dba/block_recover.txt · Zuletzt geändert: 2014/07/02 22:00 von Gunther Pippèrr