O
banco de dados Oracle fornece diferentes métodos para detecção e correção de
corrupção de blocos de dados. Uma maneira de controlar a corrupção de dados do
bloco é a utilização do pacote de DBMS_REPAIR.
Nesse
artigo serão apresentadas as características da “package” DBMS_REPAIR, seus
componentes e como utilizá-la para detectar e reparar um bloco corrompido no
banco de dados.
Existem
duas tabelas que devem ser criadas antes de usar a “package” DBMS_REPAIR, são
as tabelas (REPAIR_TABLE e ORPHAN_KEY_TABLE).
Nota: Estas tabelas devem ser criadas no esquema SYS.
Abaixo a relação das “procedures” que compõem a “package” DBMS_REPAIR.
Procedure                          Descrição
ADMIN_TABLES                  Cria duas tabelas que serão utilizadas
pela “procedure” CHECK_OBJECT 
                                           e armazenam informações sobre corrupção
bloco.
CHECK_OBJECT                 Detecta as corrupções nas tabelas ou índices.
DUMP_ORPHAN_KEYS       Gera o relacionamento dos índices que
apontam para linhas na tabela 
                                           que estão com os blocos
corrompidos.
FIX_CORRUPT_BLOCKS      Corrige os blocos corrompidos.
REBUILD_FREELISTS          Reconstrói os “freelists” do objeto. 
SEGMENT_FIX_STATUS      Fornece as capacidades de correção do
bloco danificado.
SKIP_CORRUPT_BLOCKS   Esta “procedure” que ignora blocos marcados
como corrompidos durante 
                                           a verificação. Se esta
opção não for utilizada, o banco de dados irá 
                                           gerar o erro ORA-1578
quando forem encontrados blocos corrompidos.
Criação das tabelas REPAIR_TABLE e
ORPHAN_KEY_TABLE, utilizando a “procedure” ADMIN_TABLES.
Criação da tabela REPAIR_TABLE
SQL>conn “/ as sysdba”
Conected.
SQL> BEGIN
2 (DBMS_REPAIR.ADMIN_TABLES
3 TABLE_NAME => 'REPAIR_TABLE',
4 TABLE_TYPE => dbms_repair.repair_table,
5 ACTION => dbms_repair.create_action,
6 TABLESPACE => 'USERS');
7 END;
8 /
SQL> BEGIN
2 (DBMS_REPAIR.ADMIN_TABLES
3 TABLE_NAME => 'REPAIR_TABLE',
4 TABLE_TYPE => dbms_repair.repair_table,
5 ACTION => dbms_repair.create_action,
6 TABLESPACE => 'USERS');
7 END;
8 /
PL/SQL procedure
successfully completed.
Conteúdo da tabela REPAIR_TABLE:
DESC REPAIR_TABLE
 Name                         Null?    Type
 ----------------------------
-------- --------------
 OBJECT_ID                    NOT NULL NUMBER
 TABLESPACE_ID                NOT NULL NUMBER
 RELATIVE_FILE_ID             NOT NULL NUMBER
 BLOCK_ID                     NOT NULL NUMBER
 CORRUPT_TYPE                 NOT NULL NUMBER
 SCHEMA_NAME                  NOT NULL VARCHAR2(30)
 OBJECT_NAME                  NOT NULL VARCHAR2(30)
 BASEOBJECT_NAME                       VARCHAR2(30)
 PARTITION_NAME                        VARCHAR2(30)
 CORRUPT_DESCRIPTION                   VARCHAR2(2000)
 REPAIR_DESCRIPTION                    VARCHAR2(200)
 MARKED_CORRUPT               NOT NULL VARCHAR2(10)
 CHECK_TIMESTAMP              NOT NULL DATE
 FIX_TIMESTAMP                         DATE
 REFORMAT_TIMESTAMP                    DATE
Criação da tabela ORPHAN_KEY_TABLE
SQL> BEGIN
2 (DBMS_REPAIR.ADMIN_TABLES
3 TABLE_NAME => 'ORPHAN_KEY_TABLE',
4 TABLE_TYPE => dbms_repair.orphan_table,
5 ACTION => dbms_repair.create_action,
6 TABLESPACE => 'USERS');
7 END;
8 /
PL/SQL procedure
successfully completed.
Conteúdo da tabela ORPHAN_KEY_TABLE:
DESC ORPHAN_KEY_TABLE
 Name                         Null?    Type
 ----------------------------
-------- -----------------
 SCHEMA_NAME                  NOT NULL VARCHAR2(30)
 INDEX_NAME                   NOT NULL VARCHAR2(30)
 IPART_NAME                            VARCHAR2(30)
 INDEX_ID                     NOT NULL NUMBER
 TABLE_NAME                   NOT NULL VARCHAR2(30)
 PART_NAME                             VARCHAR2(30)
 TABLE_ID                     NOT NULL NUMBER
 KEYROWID                     NOT NULL ROWID
 KEY                          NOT NULL ROWID
 DUMP_TIMESTAMP               NOT NULL DATE
Exemplos de uso:
A “procedure” CHECK_OBJECT verifica o objeto especificado e os
resultados são gravados na tabela REPAIR_TABLE. Opcionalmente pode-se
especificar um intervalo, nome da partição, ou nome subpartição para realizar a
verificação de um objeto. A validação consiste em verificar todos os blocos no
objeto. 
Abaixo um exemplo de execução de
verificação de corrupção, a tabela “DEPT” do esquema “SCOTT”, foi utilizada
neste exemplo.
SET SERVEROUTPUT ON
DECLARE num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT (
     SCHEMA_NAME=> 'SCOTT',
     OBJECT_NAME=> 'DEPT',
     REPAIR_TABLE_NAME=>
'REPAIR_TABLE',
     CORRUPT_COUNT=>  num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));
END;
/
Consultando os resultados da verificação na tabela REPAIR_TABLE.
SELECT OBJECT_NAME, 
       BLOCK_ID, 
       CORRUPT_TYPE, 
       MARKED_CORRUPT,
       CORRUPT_DESCRIPTION, 
       REPAIR_DESCRIPTION
  FROM REPAIR_TABLE;
OBJECT_NAME BLOCK_ID
CORRUPT_TYPE MARKED_COR CORRUPT_DESCRIPTION REPAIR_DESCRIPTION
----------- --------
------------ ---------- ------------------- ------------------
DEPT               3            1 FALSE      kdbchk: row locked  mark block 
                                             by
non-existent     software corrupt 
                                             transaction
                                            
table=0  slot=0
                                            
lockid=32 
                                            
ktbbhitc=1
Para a correção dos blocos identificados como corrompidos, deve-se
utilizar a procedure FIX_CORRUPT_BLOCKS.
SET SERVEROUTPUT ON
DECLARE num_fix INT;
BEGIN 
num_fix := 0;
DBMS_REPAIR.FIX_CORRUPT_BLOCKS (
     SCHEMA_NAME=> 'SCOTT',
     OBJECT_NAME=> 'DEPT',
     OBJECT_TYPE=>
dbms_repair.table_object,
     REPAIR_TABLE_NAME =>
'REPAIR_TABLE',
     FIX_COUNT=> num_fix);
DBMS_OUTPUT.PUT_LINE('num fix: ' || TO_CHAR(num_fix));
END;
/
Para confirmar a correção, deve-se verificar a tabela REPAIR_TABLE,
usar:
SELECT OBJECT_NAME, 
       BLOCK_ID, 
       MARKED_CORRUPT
 FROM REPAIR_TABLE;
OBJECT_NAME BLOCK_ID MARKED_COR
----------- -------- ----------
DEPT              3  TRUE
Existem algumas
limitações e restrições para o pacote DBMS_REPAIR.
-    As
tabelas com tipos de dados LOB, tabelas aninhadas e varrays são suportados, mas
as colunas com esses tipos de dados são ignorados.
- Tabelas
clusterizadas são suportadas para as procedures SKIP_CORRUPT_BLOCKS e
REBUILD_FREELISTS, mas não são suportados para a procedure CHECK_OBJECT.
-      Objetos
index-organized tables e índices LOB não são suportados.
-   A
procedure DUMP_ORPHAN_KEYS não opera com índices bitmaps ou índices baseados em
função (function-based).
-   Os
processos da procedure DUMP_ORPHAN_KEYS não aceitam chaves maiores que 3.950
bytes de comprimento.
MSc.
Rubens Oliveira
DBA Oracle Consultor
olivert.dba@consultant.com