jueves, 11 de noviembre de 2010

Un Bloque corrupto (ORA-01578) y como repararlo con RMAN en 11g

Uno de los errores mas odiados por cualquier DBA es el ORA-01578, un bloque corrupto en nuestra base de datos, y por que de los mas odiados, por que si no tienes un buen respaldo de tus datos, significa tener perdida de datos y tratar de explicar eso a un cliente no es nada facil.
El buen sentido comun te dice que toda base de datos de produccion debe de tener un respaldo, y mil veces mejor si este es en la herramienta de Oracle RMAN, ya que poder recuperar un bloque sin tener que restaurar el datafile, o tener que restaurar tu respaldo a una BD temporal y de ahi tener que exportar/importar tus datos, es una muy buena manera de reducir nuestro MTTR (Mean Time To Recover).
Vamos a poner en practica como poder hacer esto con RMAN y 11g.
Previo a empezar este ejercicio, debemos de tener un hot backup de nuestra base de datos y este debe no debe de estar obsoleto.
Para poder hacer este ejercicio, necesitamos corromper un bloque, hago incapie en que esto se debe de hacer un ambiente de pruebas, no en produccion.
Vamos a buscar el bloque que corresponde a la tabla EMPLOYEES de nuestro esquema HR.
TESTDB >SELECT dbms_rowid.rowid_block_number(rowid) from employees where EMPLOYEE_ID=101;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------
                                 205

Una vez que tenemos el bloque, vamos a utilizar el comando "dd" de Unix para corromper el bloque, sabiendo que la tabla de EMPLOYEES se encuentra en el datafile "users01.dbf"
dd if=/dev/zero of=users01.dbf bs=8192 conv=notrunc seek=205 count=1

Ya que corrompimos el bloque, vamos a validar nuestra base de datos con RMAN, y este comando nos va a mostrar que el datafile "users01.dbf" tiene un bloque corrupto.
rman target=/
RMAN> BACKUP VALIDATE DATABASE ARCHIVELOG ALL;
.
.
.
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
4    FAILED 0              7123         12800           11188245359861
  File Name: /mount/u01/oracle/TESTDB/data/users01.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              4683
  Index      0              332
  Other      1              662
Si checamos la vista V$DATABASE_BLOCK_CORRUPTION, vamos a ver que el bloque 205 del archivo 4 se encuentra corrupto
TESTDB >select * from V$DATABASE_BLOCK_CORRUPTION;

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTION_TYPE
---------- ---------- ---------- ------------------ ---------------------------
         4        205          1                  0 ALL ZERO

RMAN  en 11g trae una nueva funcionalidad de mostrar que errores tiene nuestra base de datos, relacionados a recuperabilidad, asi como asesorarte que puedes hacer para recuperar tus datos y hasta poder aplicar la opcion que te da.
Con el comando "list failure" podemos ver que error tenemos asi como el detalle de este error.
RMAN> list failure;

List of Database Failures
=========================

Failure ID Priority Status    Time Detected Summary
---------- -------- --------- ------------- -------
402        HIGH     OPEN      11-NOV-10     Datafile 4: '/mount/u01/oracle/TESTDB/data/users01.dbf' contains one or more corrupt blocks


RMAN> list failure 402 detail;

using target database control file instead of recovery catalog
List of Database Failures
=========================

Failure ID Priority Status    Time Detected Summary
---------- -------- --------- ------------- -------
402        HIGH     OPEN      11-NOV-10     Datafile 4: '/mount/u01/oracle/TESTDB/data/users01.dbf' contains one or more corrupt blocks
  Impact: Some objects in tablespace USERS might be unavailable
  List of child failures for parent failure ID 402
  Failure ID Priority Status    Time Detected Summary
  ---------- -------- --------- ------------- -------
  405        HIGH     OPEN      11-NOV-10     Block 205 in datafile 4: '/mount/u01/oracle/TESTDB/data/users01.dbf' is media corrupt
    Impact: Object EMPLOYEES owned by HR might be unavailable

Una vez que detectamos el error, podemos decirle a RMAN que nos asesore con el error detectado.
RMAN> advise failure 402;

List of Database Failures
=========================

Failure ID Priority Status    Time Detected Summary
---------- -------- --------- ------------- -------
402        HIGH     OPEN      11-NOV-10     Datafile 4: '/mount/u01/oracle/TESTDB/data/users01.dbf' contains one or more corrupt blocks

analyzing automatic repair options; this may take some time
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=95 device type=DISK
analyzing automatic repair options complete

Mandatory Manual Actions
========================
no manual actions available

Optional Manual Actions
=======================
no manual actions available

Automated Repair Options
========================
Option Repair Description
------ ------------------
1      Perform block media recovery of block 205 in file 4
  Strategy: The repair includes complete media recovery with no data loss
  Repair script: /mount/dump01/oracle/TESTDB/diag/rdbms/TESTDB/TESTDB/hm/reco_1373000937.hm

Si queremos ver unicamente que recimendacion nos esta haciendo RMAN para este error, podemos utilizar el comando "repair failure preview", este solamente te dara la recomendacion, mas no ejecutara la reparacion.
RMAN> repair failure preview;

Strategy: The repair includes complete media recovery with no data loss
Repair script: /mount/dump01/oracle/TESTDB/diag/rdbms/TESTDB/TESTDB/hm/reco_2285570611.hm

contents of repair script:
   # block media recovery
   recover datafile 4 block 205;

Si estamos satisfechos con lo que nos recomienda Oracle, el comando "repair failure" hara la recuperacion de nuestros datos.
RMAN> repair failure;

Strategy: The repair includes complete media recovery with no data loss
Repair script: /mount/dump01/oracle/TESTDB/diag/rdbms/TESTDB/TESTDB/hm/reco_2285570611.hm

contents of repair script:
   # block media recovery
   recover datafile 4 block 205;

Do you really want to execute the above repair (enter YES or NO)? Y
executing repair script

Starting recover at 11-NOV-10
using channel ORA_DISK_1

channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00004
channel ORA_DISK_1: reading from backup piece /mount/copy01/TESTDB/oracle/TESTDB/incr/TESTDB_HOT_11102010_1_11
channel ORA_DISK_1: piece handle=/mount/copy01/TESTDB/oracle/TESTDB/incr/TESTDB_HOT_11102010_1_11 tag=TESTDB_HOTINCR_1110_2321
channel ORA_DISK_1: restored block(s) from backup piece 1
channel ORA_DISK_1: block restore complete, elapsed time: 00:00:25

starting media recovery
media recovery complete, elapsed time: 00:00:03

Finished recover at 11-NOV-10
repair failure complete

Ya que termino de ejecutarse el comando, podemos volver a verificar nuestra BD y veremos que ya no existe el bloque corrupto
RMAN> BACKUP VALIDATE DATABASE ARCHIVELOG ALL;
.
.
.

File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
4    OK     0              7123         12800           11188245359861
  File Name: /mount/u01/oracle/TESTDB/data/users01.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              4684
  Index      0              332
  Other      0              661


TESTDB >select * from V$DATABASE_BLOCK_CORRUPTION;


no rows selected

TESTDB >select FIRST_NAME,LAST_NAME from employees where EMPLOYEE_ID=101;

FIRST_NAME
------------------------------------------------------------
LAST_NAME
---------------------------------------------------------------------------
Neena
Kochhar

Conclusion
RMAN y 11g trae una gran funcion para poder apoyarnos en nuestra recuperacion de datos, de la misma manera el tener nuestros respaldos con RMAN nos permite poder recuperarnos de un bloque corrupto con un MTTR muy bajo, ya que no tenemos que hacer una recuperacion completa de nuestra base de datos para unicamente obtener los bloques perdidos.