domingo, 11 de outubro de 2015

Recuperação de blocos corrompidos com o RMAN

No dia-dia de um DBA, um usuário do sistema pode reportar que ocorreu o erro ORA-01578.

Ao saber disso, o DBA deve dar uma olhada no alert.log e procurar por um erro similar a este:

Corrupt block relative dba: 0x01c00083 (file 7, block 131)
Bad header found during buffer read
Data in bad block:
type: 116 format: 5 rdba: 0x20676e69
last change scn: 0x7075.72726f63 seq: 0x74 flg: 0x69
spare1: 0x73 spare2: 0x74 spare3: 0xa
consistency value in tail: 0xea160602
check value in block header: 0x6e6f
block checksum disabled

Reading datafile '/u01/oradata/users_teste.dbf' for corruption at rdba: 0x01c00083 (file 7, block 131)
Reread (file 7, block 131) found same corrupt data (no logical check)
Mon Oct 05 23:56:56 2015
Corrupt Block Found
CONT = 0, TSN = 8, TSNAME = USERS_TESTE
RFN = 7, BLK = 131, RDBA = 29360259
OBJN = 93473, OBJD = 93473, OBJECT = EMP_TESTE, SUBOBJECT =
SEGMENT OWNER = SCOTT, SEGMENT TYPE = Table Segment
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_6232.trc (incident=289009):
ORA-01578: ORACLE data block corrupted (file # 7, block # 131)
ORA-01110: data file 7: '/u01/oradata/users_teste.dbf'
Incident details in: /u01/app/oracle/diag/rdbms/orcl/orcl/incident/incdir_289009/orcl_ora_6232_i289009.trc
Mon Oct 05 23:56:57 2015
Sweep [inc][289009]: completed
Mon Oct 05 23:56:57 2015
Hex dump of (file 7, block 131) in trace file /u01/app/oracle/diag/rdbms/orcl/orcl/incident/incdir_289009/orcl_m000_6320_i289009_a.trc



Levando em conta que você é um bom DBA e está com o seu backup em dia J, podemos utilizar o RMAN para fazer a recuperação deste bloco corrompido.


Validando a tablespace para popular a V$DATABASE_BLOCK_CORRUPTION com a lista de blocos corrompidos:

RMAN> validate tablespace users_teste;

Starting validate at 06-OCT-15
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=12 device type=DISK
channel ORA_DISK_1: starting validation of datafile
channel ORA_DISK_1: specifying datafile(s) for validation
input datafile file number=00007 name=/u01/oradata/users_teste.dbf
channel ORA_DISK_1: validation complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
7 FAILED 0 61 1281 2550298
File Name: /u01/oradata/users_teste.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 0
Index 0 0
Other 2 1219

validate found one or more corrupt blocks
See trace file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_6422.trc for details
Finished validate at 06-OCT-15



Verificando a lista de blocos que estão corrompidos:

RMAN> select * from v$database_block_corruption order by 1,2,3,4;

FILE#      BLOCK#     BLOCKS     CORRUPTION_CHANGE# CORRUPTIO CON_ID
---------- ---------- ---------- ------------------ --------- ----------
7          131        1          0                  CORRUPT   0



Verificando qual objeto está corrompido:

RMAN> SELECT SEGMENT_TYPE,OWNER||'.'||SEGMENT_NAME
FROM DBA_EXTENTS
WHERE FILE_ID = 7 AND 131 BETWEEN BLOCK_ID
AND BLOCK_ID+BLOCKS -1;


SEGMENT_TYPE OWNER||'.'||SEGMENT_NAME
---------------

------------------------------------------------------------------------
TABLE
SCOTT.EMP_TESTE




Recuperando os blocos do backup


Como é um bloco só, podemos recuperar da seguinte forma:

blockrecover datafile 7 block 131;

Outra forma seria:

blockrecover corruption list;


RMAN> blockrecover datafile 7 block 131;

Starting recover at 06-OCT-15
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 00007
channel ORA_DISK_1: reading from backup piece +FRA01/ORCL/BACKUPSET/2015_10_05/nnndf0_tag20151005t234117_0.334.892338095
channel ORA_DISK_1: piece handle=+FRA01/ORCL/BACKUPSET/2015_10_05/nnndf0_tag20151005t234117_0.334.892338095 tag=TAG20151005T234117
channel ORA_DISK_1: restored block(s) from backup piece 1
channel ORA_DISK_1: block restore complete, elapsed time: 00:00:01

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

Finished recover at 06-OCT-15


Validando a tablespace após a recuperação:

RMAN> validate tablespace users_teste;

Starting validate at 06-OCT-15
using channel ORA_DISK_1
channel ORA_DISK_1: starting validation of datafile
channel ORA_DISK_1: specifying datafile(s) for validation
input datafile file number=00007 name=/u01/oradata/users_teste.dbf
channel ORA_DISK_1: validation complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
7 OK 0 61 1281 2550298
File Name: /u01/oradata/users_teste.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 1
Index 0 0
Other 0 1218

Finished validate at 06-OCT-15

Utilizando o DBVerify para validar o datafile após a recuperação:

[oracle@oracle01 trace]$ dbv file=/u01/oradata/users_teste.dbf blocksize=8192 feedback=10000

DBVERIFY: Release 12.1.0.1.0 - Production on Tue Oct 6 00:24:50 2015

Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved.

DBVERIFY - Verification starting : FILE = /u01/oradata/users_teste.dbf
DBVERIFY - Verification complete
Total Pages Examined : 1280
Total Pages Processed (Data) : 1
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing (Index): 0
Total Pages Processed (Other): 1218
Total Pages Processed (Seg) : 0
Total Pages Failing (Seg) : 0
Total Pages Empty : 61
Total Pages Marked Corrupt : 0
Total Pages Influx : 0
Total Pages Encrypted : 0
Highest block SCN : 2550298 (0.2550298)



Alguns pontos:

  • Caso você tenha um Active Data Guard, existe o auto-block media recovery, que tentará fazer a recuperação automática do bloco corrompido.
  • Caso seja um índice, é possível apenas fazer o rebuild deste índice.
  • É possível utilizar a package DBMS_REPAIR para reparar e recuperar blocos corrompidos.



Scripts utilizados para realizar os testes:

CREATE TABLESPACE "USERS_TESTE" DATAFILE '/u01/oradata/users_teste.dbf'
SIZE 10M
AUTOEXTEND ON NEXT 1M MAXSIZE 32767M
LOGGING ONLINE PERMANENT BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL AUTOALLOCATE DEFAULT
NOCOMPRESS SEGMENT SPACE MANAGEMENT AUTO;

CREATE TABLESPACE "USERS_TESTE_IDX" DATAFILE '/u01/oradata/users_teste_idx.dbf'
SIZE 10M
AUTOEXTEND ON NEXT 1M MAXSIZE 32767M
LOGGING ONLINE PERMANENT BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL AUTOALLOCATE DEFAULT
NOCOMPRESS SEGMENT SPACE MANAGEMENT AUTO;

create table scott.emp_teste tablespace users_teste as select * from scott.emp;

CREATE index "SCOTT"."EMP_TESTE_IDX01" on scott.emp_teste("EMPNO") tablespace users_teste_idx;

SELECT header_block FROM dba_segments WHERE segment_name=’EMP_TESTE’;

dd of=/u01/oradata/users_teste.dbf bs=8192 conv=notrunc seek=131 << EOF
forcando corrupcao
EOF

alter system flush buffer_cache;

SQL> select * from scott.emp_teste;
select * from scott.emp_teste
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 7, block # 131)
ORA-01110: data file 7: '/u01/oradata/users_teste.dbf'



0 comentários: