Oracle Database: Recuperação Incompleta com o Comando Recover Database Until Cancel

Este artigo explora o processo de recuperação incompleta de banco de dados Oracle, focando no comando recover database until cancel executado na linha de comando SQL. A recuperação incompleta, ou Point-in-Time Recovery (PITR), é utilizada para restaurar o banco de dados para um estado anterior a um ponto específico no tempo.

Conceitos de Subcláusulas "Until"

A palavra-chave until especifica o ponto final da recuperação, indicando que se trata de uma recuperação incompleta. Existem três categorias principais:

  • Baseada em Tempo ou SCN (RMAN): Utiliza comandos como SET UNTIL TIME 'data' ou SET UNTIL SCN número dentro de um bloco RUN no RMAN.
  • Baseada em Cancelamento (SQL*Plus): Utiliza o comando recover database until cancel. O DBA controla a aplicação dos logs, fornecendo os nomes dos arquivos manualmente ou optando por AUTO ou CANCEL quando solicitado.
  • Baseada em Tempo ou Mudança (SQL*Plus): Utiliza until time 'data' ou until change scn diretamente no comendo recover.

O comando recover database until cancel no SQL*Plus aplica apenas logs de arquivamento, diferentemente do recover database padrão, que aplica automaticamente todos os logs de arquivamento e on line disponíveis.

Cenário Experimental

O cenário simula a perda de todos os arquivos de dados, com logs de arquivamento incompletos mas logs online intactos. O processo envolve:

  1. Realizar um backup completo do banco de dados.
  2. Criar dados de teste, garantindo que parte esteja nos logs de arquivamento e parte no log online atual.
  3. Excluir fisicamente todos os arquivos de dados.
  4. Corromper a sequência de logs de arquivamento, tornando-a descontínua.
  5. Restaurar os arquivos de dados a partir do backup.
  6. Executar a recuperação incompleta usando recover database until cancel.

Procedimento Passo a Passo

1. Backup e Preparação dos Dados

Inicie realizando um backup comprimido completo do banco de dados CDB (Container Database) via RMAN.

RMAN> backup as compressed backupset database format '/backupdir/full_%d_%s_%U.bkp' tag 'BACKUP_COMPLETO';

Conecte-se ao PDB (Pluggable Database) desejado e crie uma tabela de teste.

-- Conectar ao PDB e criar dados SQL> ALTER SESSION SET CONTAINER=pdb_alvo; SQL> CREATE TABLE tabela_teste (cod NUMBER); SQL> INSERT INTO tabela_teste VALUES (101); SQL> INSERT INTO tabela_teste VALUES (102); SQL> COMMIT;


<p>Forçar um switch de log e checkpoint para arquivar os dados recém-inseridos.</p>
<code>-- Voltar para a raiz do CDB
SQL> ALTER SESSION SET CONTAINER=cdb$root;
SQL> ALTER SYSTEM ARCHIVE LOG CURRENT;
SQL> ALTER SYSTEM CHECKPOINT;</code>

<p>Inserir mais dados no PDB, que permanecerão no log online atual (sequência N) após um novo switch de log.</p>
<code>-- Inserir dados adicionais que ficarão no próximo log
SQL> ALTER SESSION SET CONTAINER=pdb_alvo;
SQL> INSERT INTO tabela_teste VALUES (201);
SQL> INSERT INTO tabela_teste VALUES (202);
SQL> COMMIT;

-- Realizar novo switch para mover o log anterior para o status de arquivado
SQL> ALTER SESSION SET CONTAINER=cdb$root;
SQL> ALTER SYSTEM ARCHIVE LOG CURRENT;
SQL> ALTER SYSTEM CHECKPOINT;</code>

<p>Por fim, insira um último conjunto de dados que ficará estritamente no log online atual (sequência N+1).</p>
<code>-- Dados finais que ficarão no log online corrente
SQL> ALTER SESSION SET CONTAINER=pdb_alvo;
SQL> INSERT INTO tabela_teste VALUES (301);
SQL> INSERT INTO tabela_teste VALUES (302);
SQL> COMMIT;</code>

<h4>2. Simulação da Falha</h4>
<p>Identifique e exclua todos os arquivos de dados do banco de dados.</p>
<code>-- Listar os caminhos dos arquivos de dados
SQL> SELECT file_name FROM dba_data_files;

-- Exemplo de comando de exclusão (via shell do sistema operacional)
-- !rm -f /oradata/CDB/datafile1.dbf
-- !rm -f /oradata/CDB/pdb_alvo/*</code>

<p>Identifique um log de arquivamento específico que contenha os dados do primeiro insert (101, 102) e renomeie-o para simular corrupção ou perda, quebrando a sequência contínua.</p>
<code>-- Listar logs arquivados
SQL> SELECT name FROM v$archived_log;

-- Renomear o arquivo (exemplo via shell)
-- !mv /fra/CDB/archivelog/2024_01_01/o1_mf_1_SEQNUM_.arc /fra/CDB/archivelog/2024_01_01/o1_mf_1_SEQNUM_.arc.bak</code>

<h4>3. Restauração e Recuperação</h4>
<p>Encerre e reinicie a instância no modo <code>MOUNT</code>.</p>
<code>SQL> SHUTDOWN ABORT;
SQL> STARTUP MOUNT;</code>

<p>Utilize o RMAN para restaurar os arquivos de dados a partir do backup completo.</p>
<code>RMAN> RESTORE DATABASE FROM TAG 'BACKUP_COMPLETO';</code>

<p>Com o banco de dados ainda montado, inicie a recuperação incompleta no SQL*Plus.</p>
<code>SQL> RECOVER DATABASE UNTIL CANCEL;</code>

<p>O Oracle solicitará a aplicação do primeiro log de arquivamento necessário. Você pode fornecer o nome do arquivo, digitar <code>AUTO</code> para que ele aplique logs sequencialmente até falhar, ou <code>CANCEL</code> para parar imediatamente.</p>
<code>ORA-00279: mudança XXXX gerada em DD/MM/AAAA HH24:MI:SS necessária para thread 1
ORA-00289: sugestão : /caminho/para/archivelog_0001.arc
ORA-00280: mudança XXXX para thread 1 está na sequência #1

Especifique log: {<RET>=sugerido | nome_arquivo | AUTO | CANCEL}
/caminho/para/archivelog_0001.arc  -- Forneça o nome do arquivo sugerido</code>

<p>O processo continuará pedindo logs subsequentes. Quando chegar ao log que foi renomeado/corrompido, a solicitação falhará. Neste ponto, se os logs online estiverem intactos, você pode tentar fornecer o caminho para o log online atual para tentar uma recuperação completa, caso contrário, digite <code>CANCEL</code>.</p>
<code>ORA-00279: mudança YYYY gerada em DD/MM/AAAA HH24:MI:SS necessária para thread 1
ORA-00289: sugestão : /caminho/para/archivelog_0005.arc  -- Este arquivo está "perdido"
ORA-00280: mudança YYYY para thread 1 está na sequência #5

Especifique log: {<RET>=sugerido | nome_arquivo | AUTO | CANCEL}
CANCEL  -- Cancelando devido à lacuna nos logs de arquivamento
Recuperação de mídia cancelada.</code>

<h4>4. Abertura Final do Banco de Dados</h4>
<p>Uma vez que a recuperação incompleta foi concluída (ou cancelada), o banco de dados deve ser aberto com a opção <code>RESETLOGS</code>. Isso cria uma nova encarnação do banco de dados e reinicializa a sequência dos logs online.</p>
<code>SQL> ALTER DATABASE OPEN RESETLOGS;</code>

<p>Após a abertura, conecte-se ao PDB e verifique os dados da tabela. Apenas os dados gravados em logs de arquivamento que puderam ser aplicados antes do ponto de corte estarão presentes.</p>
<code>SQL> ALTER SESSION SET CONTAINER=pdb_alvo;
SQL> SELECT * FROM tabela_teste;

-- A saída mostrará apenas: 101, 102 (dados do primeiro lote aplicado)
-- Os dados 201, 202 e 301, 302 foram perdidos pois seus logs (arquivado e online)
-- não puderam ser aplicados de forma contínua até o ponto de parada.</code>

Tags: Oracle Database RMAN Backup e Recuperação Recuperação Incompleta recover database until cancel

Publicado em 6-13 23:56 por Thomas