Primeiro
vamos aos conceitos:
O que é uma corrupção física?
Um bloco pode estar corrompido se o “CHECKSUM”
estiver inválido. E quando isso pode ocorrer?
Quando o cabeçalho do bloco estiver inválido
- ocorre início do bloco está corrompido com valores inválidos.
Quando o bloco estiver incompleto
– ocorre quando as informações do cabeçalho do bloco não correspondem com o
restante do bloco (conhecido também como cauda de bloco).
Quando CHECKSUM estiver inválido
– o (CHECKSUM) é calculado pelo processo
(DBWR) ou pelo processo (direct loader) antes de gravar o bloco do disco e
armazenar o cabeçalho do bloco.
Blocos deslocados
– ocorrec quando o banco de dados Oracle detecta que o conteúdo do bloco a ser
lido pertence a um bloco diferente e o CHECKSUM é válido. A corrupção de blocos
físicos, normalmente são relatados como erros ORA-1578 e a descrição detalhada
da corrupção é gravada no arquivo do “alert.log”.
O
que é uma corrupção lógica?
Quando o bloco contém a verificação do
CHECKSUM válida e a estruturado início do bloco está corrompida (o conteúdo do
bloco está corrompido).
Corrupções lógicas não são normalmente
gravadas no alert.log. O utilitário DBVerify apresenta os blocos que estão logicamente
danificados no bloco.
Quando o parâmetro DB_BLOCK_CHECKING está
habilitado, ele grava o erro interno ORA-600 [kddummy_blkchk].
Se o parâmetro DB_BLOCK_CHECKING estiver habilitado
e o bloco já estiver logicamente corrompido no disco, a próxima atualização do
bloco irá marcar o bloco como “Soft Corrupt” e futuras leituras deste bloco
irão produzir o erro ORA-1578. Nesse caso o utilitário DBVerify apresenta a
corrupção com o erro "DBV-200: Block, dba, already marked corrupted".
Como
identificar os segmentos corrompidos no banco de dados?
Para
identificar tanto o dano físico como lógico pode usar:
1.
Utilitário RMAN (Recovery Manager) ou;
2.
Utilitário DB Verify – DBV
§ Utilizando
o RMAN o paralelismo torna a validação mais rápida, porque utiliza vários
canais.
§ Por
“default” os backups via RMAN (não possuem a opção de verificação lógica) só existe
a detecção de corrupções de bloco físico.
Abaixo
é apresentado o comando que verifica o banco de dados completo para ambas
corrupções (lógica ou física) sem realmente executar uma cópia de segurança
RMAN> configure device type disk
parallelism 4;
RMAN> backup validate check logical
database;
ou
RMAN> run {
allocate
channel diskl1 type disk;
allocate
channel disk2 type disk;
allocate
channel disk3 type disk;
allocate
channel disk4 type disk;
backup
validate check logical database;
}
Como
identificar corrupção física ou lógica utilizando o utilitário DBVerify?
O utilitário DBVERIFY identifica corrupções
físicas e lógicas, porém esse utilitário não pode ser executado no banco de
dados inteiro utilizando somente um único comando. Para executá-lo não é
necessário conexão com o banco de dados.
Deve-se indicar cada “datafile”, como no
exemplo abaixo:
$ dbv file=[caminho+nome_do_datafile]
blocksize = [tamanho_do_bloco_do_banco_de_dados]
- O RMAN pode ser executado com a opção de paralelismo, tornando-o mais rápido que o DBV que não pode ser executado em paralelo.
- O DBV verifica a existência de blocos vazios. Então levará mais tempo para fazer a varredura de arquivo de dados inteiro.
- Na versão do Oracle 10g o RMAN não pode marcar blocos com extensões livres quando estejam configuradas em LMT (Locally Managed Tablespaces).
- Na versão do Oracle 11g o RMAN verifica as extensões usadas e livres.
DBV> start=10 end=100
- O RMAN mantém as informações de corrupção no arquivo de control file (nas visões: v$ database_block_corruption e v$ backup_corruption). O DBV não grava as informações de corrupção. As informações podem ser vistas utilizando a consulta abaixo.
- O RMAN não grava detalhes de corrupção como o que exatamente está corrompido em um bloco relatado como uma lógica bloco corrompido.O DBV relata os detalhes de corrupção na tela ou em um arquivo de log.
- O DBV pode digitalizar blocos com um SCN mais elevado do que um determinado SCN.
- O DBV não precisa de uma conexão com o banco de dados.
select * from dba_extents
where
file_id = &DATA_FILE_ID
and
&CORRUPTED_BLOCK_ID
between block_id AND block_id + blocks - 1;
ou
SELECT e.owner, e.segment_type,
e.segment_name, e.partition_name, c.file#
,
greatest(e.block_id, c.block#) corr_start_block#
,
least(e.block_id+e.blocks-1, c.block#+c.blocks-1) corr_end_block#
,
least(e.block_id+e.blocks-1, c.block#+c.blocks-1)
- greatest(e.block_id,
c.block#) + 1 blocks_corrupted
, null
description
FROM dba_extents e,
v$database_block_corruption c
WHERE e.file_id = c.file#
AND e.block_id <= c.block#
+ c.blocks - 1
AND e.block_id + e.blocks - 1
>= c.block#
UNION
SELECT s.owner, s.segment_type,
s.segment_name, s.partition_name, c.file#
, header_block
corr_start_block#
, header_block
corr_end_block#
, 1
blocks_corrupted
, 'Segment
Header' description
FROM dba_segments s,
v$database_block_corruption c
WHERE s.header_file = c.file#
AND s.header_block between
c.block# and c.block# + c.blocks - 1
UNION
SELECT null owner, null segment_type, null
segment_name, null partition_name, c.file#
,
greatest(f.block_id, c.block#) corr_start_block#
, least(f.block_id+f.blocks-1,
c.block#+c.blocks-1) corr_end_block#
,
least(f.block_id+f.blocks-1, c.block#+c.blocks-1)
-
greatest(f.block_id, c.block#) + 1 blocks_corrupted
, 'Free Block'
description
FROM dba_free_space f, v$database_block_corruption
c
WHERE f.file_id = c.file#
AND f.block_id <= c.block#
+ c.blocks - 1
AND f.block_id + f.blocks - 1
>= c.block#
order by file#, corr_start_block#;
Rubens Oliveira
DBA Oracle Consultor
olivert.dba@consultant.com