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