Oracle Data Block Recover

A recuperação de blocos de dados corrompidos no Oracle Database é uma técnica essencial para garantir a integridade dos dados sem a necessidade de restaurar todo o banco de dados. O Oracle fornece uma funcionalidade topzera para corrigir blocos corrompidos individualmente usando o RMAN, e é possível analisar o conteúdo desses blocos através de dumps para examinar registros específicos.

Agora um pouco sobre a arquitetura do data bloco e rowid no Oracle:

Oracle Data Block

Descrição da Estrutura:

  1. Database Block: O bloco de dados é a menor unidade de armazenamento no Oracle. Dentro dele, são armazenados vários pedaços de linha (row pieces), além de informações de controle e metadados que ajudam a gerenciar o armazenamento.
  2. Row Piece: Um pedaço de linha (row piece) é uma parte de uma linha de dados que pode estar completa em um único bloco ou distribuída em vários blocos (chaining ou migration). Ele contém todas as informações relacionadas aos dados da linha.
  3. Row Header: O cabeçalho da linha inclui informações de controle sobre a linha armazenada, como:
    • Row Overhead: Espaço reservado para informações de controle, como status da transação associada à linha e flags de bloqueio.
    • Number of Columns: O número de colunas armazenadas na linha.
  4. Column Data:
    • Cluster Key ID (se for clustered): Identificação da chave de cluster (caso a tabela faça parte de um cluster).
    • ROWID of Chained Row Pieces (se houver): Se a linha estiver fragmentada em vários blocos, o ROWID (localização da linha) dos outros pedaços de linha será armazenado aqui.
    • Column Length: Indica o tamanho de cada coluna.
    • Column Value: O valor real da coluna é armazenado nessa parte, onde cada coluna tem seu comprimento e valor específicos.
Estrutura do ROWID (Representação tosca por AI)
  1. Object ID (OOOOOOO) – Representado em vermelho, com 4 bytes de tamanho. Esta parte identifica o objeto no banco de dados (como uma tabela ou índice).
  2. Datafile Number (OBBOFLEBF) – Representado em azul, com 1,5 bytes de tamanho. Refere-se ao número do arquivo de dados onde o bloco específico reside.
  3. Block Number (BBBBBB) – Representado em verde, com 2,5 bytes de tamanho. Indica o número do bloco dentro do arquivo de dados onde a linha está armazenada.
  4. Row Number (BBBBBBR) – Representado em preto, com 2 bytes de tamanho. Identifica a linha específica dentro do bloco de dados.

1. Identificação de Blocos Corrompidos

Primeiramente, é necessário identificar os blocos corrompidos no banco de dados. O Oracle mantém uma tabela de sistema chamada V$DATABASE_BLOCK_CORRUPTION que lista todos os blocos identificados como corrompidos:

Você pode se atentar ao erro do Oracle:

ORA-01578: ORACLE data block corrupted (file # X, block # Y)

Nessa mensagem de erro podemos notar que existe ali o identificador do datafile e do bloco em questão.

Para checar o datafile use a query:

SELECT file_name
FROM dba_data_files
WHERE file_id = <file#>;

Para checar o bloco corrompido, pode usar:

RMAN> BLOCKRECOVER CORRUPION LIST;
SQL> 
COLUMN owner FORMAT A20
COLUMN segment_name FORMAT A30

SELECT DISTINCT owner, segment_name
FROM   v$database_block_corruption dbc
       JOIN dba_extents e ON dbc.file# = e.file_id AND dbc.block# BETWEEN e.block_id and e.block_id+e.blocks-1
ORDER BY 1,2;

Essa tabela é populada automaticamente após verificações de integridade realizadas por comandos como DBV (Data Block Verifier) ou após erros de leitura durante operações no banco de dados.

Outra forma de verificar corrupção de blocos é através de:

  • Alert Log: mensagens de erro indicando falha de leitura de blocos.
  • DBVERIFY: uma ferramenta externa que faz varreduras em datafiles.
dbv file=/path/to/datafile.dbf blocksize=8192

2. Recuperação de Blocos Corrompidos com RMAN

Após identificar o(s) bloco(s) corrompido(s), podemos usar o RMAN para a recuperação. O processo pode ser feito enquanto o banco de dados está aberto, reduzindo o tempo de inatividade.

Etapas para recuperação:

  1. Conectar ao RMAN:
 rman target /
  1. Executar o comando de recuperação de bloco: Você pode especificar o arquivo de dados e o número de bloco diretamente:
RMAN> BLOCKRECOVER DATAFILE 4 BLOCK 12345;

Para recuperar vários blocos de uma vez:

RMAN> BLOCKRECOVER DATAFILE 4 BLOCK 12345, 12346, 12347;
  1. Verificar se os blocos foram recuperados: Após a execução do comando BLOCKRECOVER, você pode verificar novamente a visão V$DATABASE_BLOCK_CORRUPTION para garantir que os blocos não estão mais corrompidos:
SQL> SELECT * FROM V$DATABASE_BLOCK_CORRUPTION;

3. Examinando o Conteúdo de Blocos de Dados

Para entender o conteúdo de um bloco de dados específico, o Oracle oferece um método de “dumper” de blocos. Esse procedimento pode ser útil para verificar o que está gravado no bloco, como registros de tabelas.

Passos para realizar o dump de um bloco:

  1. Identifique o número do bloco, número do arquivo de dados e objeto onde o registro está armazenado. Você pode usar a query abaixo para localizar o arquivo e o número do bloco de uma linha específica:
SQL> SELECT tablespace_name, segment_type, owner, segment_name
        FROM dba_extents
       WHERE file_id = <file#>
         AND <block#> BETWEEN block_id AND block_id + blocks - 1;

SQL> 
COLUMN ROWID FORMAT A18
COLUMN OB_ID FORMAT 99999
COLUMN FILE_ID FORMAT 9
COLUMN BL_NUM FORMAT 99999
COLUMN ROW_NUM FORMAT 99
COLUMN OWNER FORMAT A2
COLUMN OBJECT_NAME FORMAT A9
COLUMN FILE_NAME FORMAT A71
COLUMN FILE_NAME FORMAT A71
COLUMN TABLESPACE_NAME FORMAT A15
SELECT tr.rowid,
       dbms_rowid.rowid_object(tr.rowid) AS OB_ID,
       dbms_rowid.rowid_relative_fno(tr.rowid) AS FILE_ID,
       dbms_rowid.rowid_block_number(tr.rowid) AS BL_NUM,
       dbms_rowid.rowid_row_number(tr.rowid) AS ROW_NUM,
       ob.owner,
       ob.object_name,
       df.file_name,
       df.tablespace_name
  FROM sys.dba_brabo_tb tr
 INNER JOIN dba_objects ob
    ON ob.object_id = dbms_rowid.rowid_object(tr.rowid)
 INNER JOIN dba_data_files df
    ON df.file_id = dbms_rowid.rowid_relative_fno(tr.rowid)
 WHERE tr.dba_brabo_alunos = 666;
COLUMN file_id          FORMAT 99999                                                       -- Número do arquivo relativo
COLUMN block_id         FORMAT 9999999                                                     -- Número do bloco no arquivo
COLUMN row_number       FORMAT 99999                                                       -- Número da linha no bloco
COLUMN rows_per_block   FORMAT 99999                                                       -- Total de linhas no bloco
COLUMN rowid            FORMAT A18                                                         -- ROWID do registro
COLUMN file_name        FORMAT A50                                                         -- Nome do arquivo de dados
COLUMN block_size_kb    FORMAT 999999                                                      -- Tamanho do bloco em KB
COLUMN total_blocks     FORMAT 999999                                                      -- Total de blocos
COLUMN segment_name     FORMAT A30                                                         -- Nome do segmento
COLUMN total_rows       FORMAT 99999999                                                    -- Total de linhas estimadas
COLUMN avg_row_length   FORMAT 9999                                                        -- Tamanho médio de uma linha

SELECT 
    A.ROWID AS row_id,                                                                     -- ROWID do registro
    DBMS_ROWID.ROWID_RELATIVE_FNO(A.ROWID) AS file_id,                                     -- Número relativo do arquivo
    DBMS_ROWID.ROWID_BLOCK_NUMBER(A.ROWID) AS block_id,                                    -- Número do bloco no arquivo
    DBMS_ROWID.ROWID_ROW_NUMBER(A.ROWID) AS row_number,                                    -- Número da linha dentro do bloco
    COUNT(*) OVER (PARTITION BY DBMS_ROWID.ROWID_BLOCK_NUMBER(A.ROWID)) AS rows_per_block, -- Total de linhas no bloco
    T.FILE_NAME AS file_name,                                                              -- Nome do arquivo de dados correspondente
    T.BYTES/1024 AS block_size_kb,                                                         -- Tamanho do bloco em KB
    T.BLOCKS AS total_blocks,                                                              -- Total de blocos alocados
    B.SEGMENT_NAME AS segment_name,                                                        -- Nome do segmento associado
    S.NUM_ROWS AS total_rows,                                                              -- Total de linhas estimadas na tabela
    S.AVG_ROW_LEN AS avg_row_length                                                        -- Tamanho médio de uma linha na tabela
FROM 
    DBA_BRABO_TB A
LEFT JOIN 
    DBA_DATA_FILES T
ON 
    T.RELATIVE_FNO = DBMS_ROWID.ROWID_RELATIVE_FNO(A.ROWID)                                -- Relaciona arquivo relativo com DBA_DATA_FILES
LEFT JOIN 
    DBA_SEGMENTS B
ON 
    B.SEGMENT_NAME = 'DBA_BRABO_TB' AND B.OWNER = 'SEU_OWNER'                         -- Ajuste o OWNER conforme necessário
LEFT JOIN 
    DBA_TABLES S
ON 
    S.TABLE_NAME = 'DBA_BRABO_TB' AND S.OWNER = 'SEU_OWNER'                           -- Ajuste o OWNER conforme necessário
WHERE 
    ROWNUM <= 1000
ORDER BY 
    file_id, block_id, row_number;
  1. Usar o comando ALTER SYSTEM DUMP para fazer o dump do bloco: Para fazer o dump do bloco, utilize o seguinte comando:

O comando ALTER SYSTEM DUMP DATAFILE é uma instrução no Oracle que permite extrair informações detalhadas sobre um bloco específico dentro de um arquivo de dados. Essa instrução é usada para diagnosticar problemas de corrupção de bloco, entender a estrutura do bloco, ou obter detalhes sobre os dados contidos em um bloco específico no banco de dados.

 SQL> ALTER SYSTEM DUMP DATAFILE 4 BLOCK 12345;

Isso irá gerar um arquivo de dump no diretório de logs do Oracle, geralmente localizado em $ORACLE_HOME/diag.

  1. Analisar o arquivo de dump: O dump contém informações hexadecimais e registros detalhados sobre o conteúdo do bloco. O dump vai incluir cabeçalhos, transações ativas ou inativas, e os dados efetivos gravados nesse bloco.
  2. Isso é coisa antiga, lá pra Oracle 7 e 8, mas ainda funfa.
Dump file /u01/app/oracle/diag/rdbms/dbabrabo/trace/orcl_ora_12345.trc
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1
System name:    Linux
Node name:      dbabrabo01
Release:        4.18.0-80.el8.x86_64
Version:        #1 SMP Wed Apr 24 11:50:52 EDT 2019
Machine:        x86_64
Instance name: dbabrabo01
Redo thread mounted by this instance: 1
Oracle process number: 45
Unix process pid: 12345, image: oracle@dbabrabo01

*** 2024-10-21 14:35:10.123456 +00:00
*** SESSION ID:(12345.6789) 2024-10-21 14:35:10.123456
*** CLIENT ID:() 2024-10-21 14:35:10.123456
*** SERVICE NAME:(SYS$USERS) 2024-10-21 14:35:10.123456
*** MODULE NAME:(sqlplus@dbabrabo01 (TNS V1-V3)) 2024-10-21 14:35:10.123456
*** ACTION NAME:() 2024-10-21 14:35:10.123456

Start dump data blocks tsn: 4 file#: 4 minblk 12345 maxblk 12345
Block dump from cache:
Dump of buffer cache at level 4 for tsn=4 rdba=16777221

buffer tsn: 4 rdba: 0x01003039 (4/12345)
scn: 0x0000.01234567 seq: 0x01 flg: 0x06 tail: 0x567890ab
frmt: 0x02 chkval: 0xa1d7 type: 0x06=trans data

Block header dump:  0x01003039
 Object id on Block? Y
 seg/obj: 0x456789  csc: 0x00.12345678  itc: 3  flg: O-
  brn: 0  bdba: 0x01003038 ver: 0x01 opc: 0
  inc: 0  exflg: 0

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0009.001.00001234 0x01800012.3456789f C---    0 scn 0x0000.01234567
0x02 0x0012.002.00004567 0x01800012.345679ab --U-    2 scn 0x0000.01234568
0x03 0x0034.001.00007890 0x01800012.34567abc ----    3 scn 0x0000.01234569

Data Block:
-----------------------------------------------------------------------------
tsiz: 0x1fa0
flag: 0x2
nrid:  0x01003039
col  0: [ 3]  c1 02 03
col  1: [ 2]  c1 04
col  2: [ 4]  c1 05 c1 06
col  3: [ 8]  c2 01 00 00 00 07 08 09
row#0[8018] flag: C
lock: 2
col  0: [ 2] 80 80
col  1: [ 6] 80 80 81 81 82 82
col  2: [ 1] 80
col  3: [ 3] 00 00 00

Neste exemplo, o dump mostra o cabeçalho do bloco, identificadores de objetos, o estado de transações e registros de mudanças. Isso pode ser útil em casos onde é necessário analisar a causa da corrupção ou o estado de uma transação em andamento.

  • Block header dump: 0x010032a8: O cabeçalho do bloco que está sendo “despejado”. O valor 0x010032a8 é o endereço hexadecimal do bloco.
  • Object id on Block? Y: Indica que existe um ID de objeto associado ao bloco (neste caso, “Y” para “Yes”).
  • seg/obj: 0x19b8: Este é o identificador de segmento ou objeto (ID de objeto 0x19b8).
  • csc: 0x00.2f4c43: Este é o SCN (System Change Number) correspondente ao bloco.
  • itl: 2: Indica o número de interested transaction list (ITL) slots no bloco. Isso significa que até 2 transações podem ser controladas dentro do bloco.
  • Itl Xid Uba Flag Lck Scn/Fsc: Esses são os detalhes das transações ativas no bloco:
  • Xid: Transaction ID (ID da transação).
  • Uba: Undo Block Address.
  • Flag: Flags indicando o status da transação (C indica commit).
  • Lck: Lock.
  • Scn/Fsc: System Change Number ou Free Space Checkpoint.
  • data_block_dump,data header at 0x7f5f332e900: Início do dump dos dados no bloco. O endereço do cabeçalho de dados começa em 0x7f5f332e900.
  • tsiz: 0x1f78: O tamanho do bloco de dados.
  • checksum: 0x39cb: O checksum do bloco, utilizado para garantir a integridade dos dados.

4. Recuperação usando Backup Incremental (Opcional)

Se você não tiver backup de bloco específico ou se o RMAN não conseguir recuperar os blocos por qualquer motivo, você pode usar um backup incremental para recuperar blocos corrompidos:

  1. Faça um backup incremental do banco de dados:
   RMAN> BACKUP INCREMENTAL LEVEL 1 DATABASE;
  1. Execute a recuperação baseada no backup incremental:
   RMAN> RECOVER BLOCK DATAFILE 4 BLOCK 12345;

Essa abordagem aplica blocos saudáveis a partir do backup incremental, corrigindo os blocos corrompidos no banco de dados de produção.

5. Verificando a Correção do Bloco

Após a recuperação, o Oracle realiza automaticamente uma validação para garantir que o bloco foi restaurado corretamente. No entanto, você pode validar manualmente usando o comando:

Versão comum (sem ASM):

dbv file=/path/to/datafile.dbf blocksize=8192
DBVERIFY: Release 19.0.0.0.0 - Production on Mon Oct 21 14:42:33 2024

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

DBVERIFY - Verification starting : FILE = /path/to/datafile.dbf
DBVERIFY - Verification complete

Total Pages Examined         : 64000
Total Pages Processed (Data) : 32000
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 16000
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 16000
Total Pages Processed (Seg)  : 0
Total Pages Empty            : 0
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Highest block SCN            : 1123456789 (0.1123456789)

Versão do ASM:

dbv USERID=SYS/***** file=+DATAC1/datafiles/users01.dbf logfile=/tmp/dbv_dbabrabo.log
DBVERIFY: Release 19.0.0.0.0 - Production on Mon Oct 21 15:35:12 2024

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

DBVERIFY - Verification starting : FILE = +DATAC1/datafiles/users01.dbf
DBVERIFY - Verification complete

Total Pages Examined         : 32000
Total Pages Processed (Data) : 16000
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 8000
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 8000
Total Pages Empty            : 0
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Highest block SCN            : 123456789 (0.123456789)

Isso garantirá que o bloco foi corrigido sem outros erros.

6. Recuperação de Blocos Corrompidos com DBMS_REPAIR

Exemplo oriundos do mestre Tim Hall

O pacote DBMS_REPAIR do Oracle permite identificar e tratar blocos corrompidos no banco de dados. Diferentemente de outros métodos, ele não apenas detecta, mas também permite “marcar” blocos danificados para serem ignorados por operações de DML.

Criação das Tabelas Administrativas

Para gerenciar os blocos corrompidos, duas tabelas administrativas devem ser criadas:: uma para armazenar informações dos blocos corrompidos e outra para guardar chaves órfãs de índices.

BEGIN
  DBMS_REPAIR.admin_tables (
    table_name => 'TBL_CORRUPCAO',
    table_type => DBMS_REPAIR.repair_table,
    action     => DBMS_REPAIR.create_action,
    tablespace => 'USERS');

  DBMS_REPAIR.admin_tables (
    table_name => 'CHAVES_ORFAS',
    table_type => DBMS_REPAIR.orphan_table,
    action     => DBMS_REPAIR.create_action,
    tablespace => 'USERS');
END;
/

Verificação de Corrupção na Tabela

Após a criação das tabelas administrativas, a rotina CHECK_OBJECT pode ser usada para verificar a existência de blocos corrompidos em uma tabela específica.

SET SERVEROUTPUT ON
DECLARE
  v_blocos_corrompidos INT;
BEGIN
  v_blocos_corrompidos := 0;
  DBMS_REPAIR.check_object (
    schema_name       => 'DBABRABO',
    object_name       => 'CLIENTES',
    repair_table_name => 'TBL_CORRUPCAO',
    corrupt_count     => v_blocos_corrompidos);
  DBMS_OUTPUT.put_line('Blocos corrompidos detectados: ' || TO_CHAR(v_blocos_corrompidos));
END;
/

Marcação de Blocos Corrompidos

Se houver blocos corrompidos, eles podem ser “marcados” para serem ignorados durante as operações de DML.

SET SERVEROUTPUT ON
DECLARE
  v_blocos_corrigidos INT;
BEGIN
  v_blocos_corrigidos := 0;
  DBMS_REPAIR.fix_corrupt_blocks (
    schema_name       => 'DBABRABO',
    object_name       => 'CLIENTES',
    object_type       => DBMS_REPAIR.table_object,
    repair_table_name => 'TBL_CORRUPCAO',
    fix_count         => v_blocos_corrigidos);
  DBMS_OUTPUT.put_line('Blocos marcados como corrompidos: ' || TO_CHAR(v_blocos_corrigidos));
END;
/

Identificação de Chaves Órfãs em Índices

Após marcar os blocos corrompidos, os índices associados devem ser verificados para identificar chaves órfãs.

SET SERVEROUTPUT ON
DECLARE
  v_chaves_orfas INT;
BEGIN
  v_chaves_orfas := 0;
  DBMS_REPAIR.dump_orphan_keys (
    schema_name       => 'DBABRABO',
    object_name       => 'IDX_CLIENTES',
    object_type       => DBMS_REPAIR.index_object,
    repair_table_name => 'TBL_CORRUPCAO',
    orphan_table_name => 'CHAVES_ORFAS',
    key_count         => v_chaves_orfas);
  DBMS_OUTPUT.put_line('Chaves órfãs detectadas: ' || TO_CHAR(v_chaves_orfas));
END;
/

Caso existam chaves órfãs, o índice deve ser reconstruído para corrigir o problema.

Reconstrução das Freelists

Os blocos marcados como corrompidos são removidos automaticamente das freelists. Contudo, isso pode causar problemas de acesso aos blocos seguintes, sendo necessário reconstruir as freelists.

BEGIN
  DBMS_REPAIR.rebuild_freelists (
    schema_name => 'DBABRABO',
    object_name => 'CLIENTES',
    object_type => DBMS_REPAIR.table_object);
END;
/

Ignorar Blocos Corrompidos

Para garantir que os blocos corrompidos sejam ignorados durante operações de DML, utilize a rotina SKIP_CORRUPT_BLOCKS.

BEGIN
  DBMS_REPAIR.skip_corrupt_blocks (
    schema_name => 'DBABRABO',
    object_name => 'CLIENTES',
    object_type => DBMS_REPAIR.table_object,
    flags       => DBMS_REPAIR.skip_flag);
END;
/

BONUS- BBED (Para você brincar no seu LAB[APENAS])

                             ______
                          .-"      "-.
                         /            \
             _          |              |          _
            ( \         |,  .-.  .-.  ,|         / )
             > "=._     | )(__/  \__)( |     _.=" <
            (_/"=._"=._ |/     /\     \| _.="_.="\_)
                   "=._ (_     ^^     _)"_.="
                       "=\__|IIIIII|__/="
                      _.="| \IIIIII/ |"=._
            _     _.="_.="\          /"=._"=._     _
           ( \_.="_.="     `--------`     "=._"=._/ )
            > _.="                            "=._ <
           (_/                                    \_)

O utilitário BBED (Block Browser and Editor) é uma ferramenta interna do Oracle que permite visualizar e modificar blocos de dados em nível físico. No entanto, a Oracle não suporta oficialmente o BBED para uso em produção, pois ele pode ser muito perigoso se utilizado incorretamente, uma vez que permite a modificação de blocos no nível mais baixo, o que pode corromper dados se usado de maneira imprudente.

Dito isso, aqui está uma visão geral e exemplos de como você pode usar o BBED para recuperação de blocos corrompidos em Oracle. O BBED não é distribuído por padrão, mas pode ser construído a partir do Oracle Binary. Vou incluir os passos para configurá-lo e alguns exemplos de uso.

1. Preparando o BBED:

  1. Verifique se o BBED está disponível no seu ambiente Oracle. Muitas vezes ele é desabilitado, mas você pode ativá-lo se encontrar o binário.
  • O executável BBED geralmente pode ser encontrado em $ORACLE_HOME/rdbms/admin/bbed.par e $ORACLE_HOME/rdbms/admin/bbedus.msb.
  1. Copiar e compilar o BBED:
  • Copie o arquivo bbed para algum diretório de trabalho.
  • Garanta que os arquivos bbed.par e bbedus.msb estejam no mesmo diretório do binário bbed.
  • Conceda permissões de execução ao binário: chmod +x bbed
  1. Crie um arquivo de parâmetros (bbed.par):
    O arquivo de parâmetros é necessário para fornecer informações sobre o tamanho do bloco, arquivo de dados, e outros detalhes. Exemplo do conteúdo do bbed.par:
   blocksize=8192
   listfile=/tmp/datafiles.lst
   mode=edit
  1. Arquivo de lista (datafiles.lst):
    Crie um arquivo de lista de datafiles que deseja abrir com o BBED.
   /path/to/datafile1.dbf
   /path/to/datafile2.dbf

Agora o BBED está configurado e pronto para ser usado.

2. Comandos básicos de BBED:

Vamos a alguns exemplos de comandos básicos para recuperação de blocos.

2.1. Carregar o BBED e acessar um bloco:

  1. Iniciar o BBED:
   $ bbed parfile=/path/to/bbed.par

Isso carrega o BBED e o arquivo de parâmetros especificado.

  1. Abrir um bloco específico: Para navegar e visualizar um bloco específico no datafile, você precisa acessar o datafile e o número do bloco que deseja inspecionar.
   BBED> set dba 4,12345

Onde 4 é o número do datafile, e 12345 é o número do bloco.

  1. Listar os dados do bloco: Após definir o DBA, você pode visualizar o conteúdo do bloco:
   BBED> map

Esse comando mostra um mapeamento geral do bloco, como o cabeçalho do bloco, as transações em andamento, e outros metadados.

  1. Listar o conteúdo do bloco: Para exibir o conteúdo do bloco em formato hexadecimal, você pode usar o comando dump.
   BBED> dump

Esse comando exibe o conteúdo do bloco como uma lista de dados hexadecimais e ASCII. Você pode usar isso para analisar os dados corrompidos ou entender o estado atual do bloco.

2.2. Exemplo de recuperação de bloco corrompido:

Vamos supor que você tenha identificado que o bloco está corrompido e precise alterá-lo para recuperá-lo.

  1. Identificar a corrupção:
    Ao visualizar o bloco, você pode verificar se há campos corrompidos ou inválidos. Suponhamos que o cabeçalho do bloco esteja corrompido.
  2. Editar o cabeçalho do bloco: O campo do cabeçalho do bloco pode ser editado diretamente. Suponha que você precise ajustar o campo kcbh.seq (sequência do cabeçalho de bloco). Você pode ajustar isso manualmente. Primeiro, localize o deslocamento (offset) do campo kcbh.seq.
   BBED> p kcbh.seq

Isso imprime o valor atual do campo kcbh.seq. Agora, se ele estiver incorreto, você pode corrigir o valor:

   BBED> modify /x 0004 at kcbh.seq

Isso altera o valor do campo para 0004.

  1. Salvar as alterações: Uma vez que você fez a modificação, você pode gravar o bloco de volta no datafile.
   BBED> sum
   BBED> write

O comando sum calcula o checksum do bloco modificado, e write grava o bloco de volta no arquivo de dados.

3. Se liga aqui Zé Ruela:

  • BBED é extremamente perigoso: Uma única modificação incorreta pode corromper permanentemente os dados do seu banco de dados. Sempre faça um backup completo antes de usar esta ferramenta.
  • A ferramenta não é documentada oficialmente: A Oracle não oferece suporte ao BBED, e ele deve ser usado apenas em casos extremos ou em ambientes de teste.

Embora o BBED possa ser uma ferramenta útil para análise em profundidade e modificação de blocos físicos de dados, ele deve ser usado com extremo cuidado e preferencialmente em ambientes de teste. Em produção, a Oracle oferece alternativas mais seguras e suportadas, como o RMAN e o DBMS_REPAIR, para recuperação de blocos corrompidos.

Considerações Finais

A recuperação de blocos de dados do Oracle é uma funcionalidade extremamente útil que evita downtime prolongado e a necessidade de restauração completa. Além disso, a capacidade de fazer dumps de blocos pode ser usada para análise forense, ajudando na resolução de problemas críticos de integridade de dados.

Dicas Importantes:

  • Sempre mantenha backups atualizados.
  • Verifique periodicamente se há corrupção de blocos, utilizando ferramentas como DBVERIFY e RMAN.
  • Sempre utilize procedimentos e padrões com base na documentação, consulte o suporte.
  • Teste e pratique cenários extremos para saber como contornar crises.
  • Automatize a verificação e recuperação de blocos corrompidos com RMAN para minimizar o tempo de inatividade.