quinta-feira, 9 de agosto de 2012

Package - DBMS_REPAIR


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 /

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