Aplicando arquivos de redo log arquivados em um cold backup

Por Eduardo Legatti
Postado en fevereiro 2013

Não é raro vermos em fóruns ou grupos de discussões, questões ou dúvidas relacionadas à aplicação de arquivos de redo log arquivados (archive redo log files) em backups frios (cold backups) de banco de dados Oracle. Apenas para relembrar, um "cold backup" gerenciado por usuário é uma opção de backup na qual o mesmo é realizado no nível de arquivo, onde todos os arquivos de dados, arquivos de controle e opcionalmente os arquivos de redo log on-line são copiados através de comandos do sistema operacional. Nas plataformas Unix/Linux, comandos tais como cp ou tar, normalmente são usados para fazer o backup dos arquivos para um local seguro.

Esta operação de cópia dos arquivos de banco de dados é realizada enquanto o banco de dados está fechado. Por outro lado, para quem utiliza a estratégia de backup gerenciada pelo servidor RMAN, um cold backup para ser realizado necessita que o banco de dados esteja no estado montado (MOUNT), mas não aberto.

"No caso de backups gerenciados pelo usuário, um dos erros mais comuns quando se usa o cold backup é não fechar o banco de dados normalmente com as opções NORMAL, IMMEDIATE ou TRANSACTIONAL do comando SHUTDOWN. Os colds backups executados com o banco de dados aberto ou após ele ter sido fechado de modo anormal são completamente inúteis. Essa situação potencialmente perigosa pode ocorrer quando são usados scripts automatizados que não contêm uma lógica para verificar se o banco de dados foi realmente fechado normalmente antes do início do backup."

Dependendo da política de backup implementada e do tipo de desastre ocorrido no servidor do banco de dados, talvez sempre existirá a possibilidade de contar com pelo menos um "cold backup" do banco de dados e um backup de todos os arquivos de redo log gerados após a realização do cold backup.

No mais, neste artigo irei simular a aplicação de todos os arquivos de redo log arquivados criados após a realização de um cold backup, nos arquivos de banco de dados restaurados do próprio cold backup. Não precisa nem dizer que o banco de dados deverá estar configurado para operar no modo de arquivamento (ARCHIVELOG) ...

[oracle@linux1 oracle]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Qua Abr 15 13:28:52 2009

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Conectado a uma instância inativa.

SQL> startup
Instância ORACLE iniciada.

Total System Global Area  155189248 bytes
Fixed Size                  1266320 bytes
Variable Size             100666736 bytes
Database Buffers           50331648 bytes
Redo Buffers                2924544 bytes
Banco de dados montado.
Banco de dados aberto.

-- Confirmando o formato dos archive logs
SQL> show parameter log_archive_format

NAME                     TYPE        VALUE
------------------------ ----------- ------------------------------
log_archive_format       string      %t_%s_%r.dbf

-- Confirmando o destino para os archive redo logs gerados
SQL> show parameter log_archive_dest_1

NAME                  TYPE        VALUE
--------------------- ----------- ---------------------------------------
log_archive_dest_1    string      LOCATION=/u01/archive/ MANDATORY REOPEN

-- Confirmando que o banco de dados está no modo de arquivamento
SQL> archive log list
Modo log de banco de dados     Modo de Arquivamento
Arquivamento automático        Ativado
Destino de arquivamento        /u01/archive/
A seqüência de log on-line mais antiga 1
Próxima seqüência de log a arquivar    1
Seqüência de log atual                 1

-- Confirmando a seqüencia do arquivo de redo log-online corrente
SQL> select group#,thread#,sequence#,bytes,members,archived,status from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ----------------
         1          1          1    4194304          1 NO  CURRENT
         2          1          0    4194304          1 YES UNUSED
         3          1          0    4194304          1 YES UNUSED

-- Fechando o banco de dados
SQL> shutdown immediate
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.

SQL> exit

Desconectado de Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Irei abaixo realizar uma cópia de todos os arquivos de banco de dados para um outro local.

[oracle@linux1 oracle]$ cp -a /u01/app/oracle/oradata /backup

Após a realização do cold backup, irei reiniciar o banco de dados para simular algumas transações.

[oracle@linux1 oracle]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Qua Abr 15 13:28:52 2009

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Conectado a uma instância inativa.

SQL> startup
Instância ORACLE iniciada.

Total System Global Area  155189248 bytes
Fixed Size                  1266320 bytes
Variable Size             100666736 bytes
Database Buffers           50331648 bytes
Redo Buffers                2924544 bytes
Banco de dados montado.
Banco de dados aberto.

-- Criando um usuário de teste
SQL> create user scott identified by tiger default tablespace users;

Usuário criado.

-- Concedendo atribuições padrão
SQL> grant connect,resource to scott;

Concessão bem-sucedida.

-- Conectando com o usuário SCOTT
SQL> connect scott/tiger
Conectado.

-- Criando uma tabela de teste
SCOTT> create table t1 (id number);

Tabela criada.

Realizado a etapa acima, abaixo irei simular algumas operações DML no banco de dados de forma a gerar registros de redo suficientes para a criação de arquivos de redo log arquivados:

SCOTT> insert into t1 select level from dual connect by level <= 100000;

100000 linhas criadas.

SCOTT> commit;

Commit concluído.

SCOTT> update t1 set id=1000;

100000 linhas atualizadas.

SCOTT> rollback;

Rollback concluído.

SCOTT> drop table t1 purge;

Tabela eliminada.

SCOTT> create table t2 (data timestamp);

Tabela criada.

-- Inserindo a data e horário atual
SCOTT> insert into t2 select localtimestamp from dual;

1 linha criada.

SCOTT> commit;

Commit concluído.

SCOTT> select * from t2;

DATA
--------------------------
15/04/2009 13:34:36,883986

SQL> connect / as sysdba;
Conectado.

-- Forçando o arquivamento do arquivo de redo log on-line corrente
SQL> alter system archive log current;

Sistema alterado.

Após a simulação das operações acima, podemos ver abaixo que foram gerados 12 arquivos de redo log arquivados.

SQL> select recid,name from v$archived_log;

     RECID NAME
---------- -----------------------------------------
         1 /u01/archive/1_1_684148997.dbf
         2 /u01/archive/1_2_684148997.dbf
         3 /u01/archive/1_3_684148997.dbf
         4 /u01/archive/1_4_684148997.dbf
         5 /u01/archive/1_5_684148997.dbf
         6 /u01/archive/1_6_684148997.dbf
         7 /u01/archive/1_7_684148997.dbf
         8 /u01/archive/1_8_684148997.dbf
         9 /u01/archive/1_9_684148997.dbf
        10 /u01/archive/1_10_684148997.dbf
        11 /u01/archive/1_11_684148997.dbf
        12 /u01/archive/1_12_684148997.dbf

12 linhas selecionadas.

-- Fechando o banco de dados
SQL> shutdown immediate
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.

SQL> exit
Desconectado de Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

-- Confirmando os registros de redo log criados no destino de arquivamento
[oracle@linux1 archive]$ ls -lhatr
total 46M
drwxrwxr-x 4 oracle dba      4,0K Abr 15 13:31 ..
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_1_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_2_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_3_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_4_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_5_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_6_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_7_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_8_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_9_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_10_684148997.dbf
-rw-r----- 1 oracle oinstall 4,0M Abr 15 13:34 1_11_684148997.dbf
-rw-r----- 1 oracle oinstall 1,5M Abr 15 13:35 1_12_684148997.dbf
drwxr-xr-x 2 oracle oinstall  20K Abr 15 13:35 .


-- Simulando a perda de todos os arquivos de banco de dados
[oracle@linux1 oracle]$ rm -rf /u01/app/oracle/oradata

-- Restaurando o cold backup para o local de origem
[oracle@linux1 oracle]$ cp -a /backup/oradata /u01/app/oracle/oradata

[oracle@linux1 oracle]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Qua Abr 15 13:47:19 2009

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Conectado a uma instância inativa.

SQL> startup mount
Instância ORACLE iniciada.

Total System Global Area  155189248 bytes
Fixed Size                  1266320 bytes
Variable Size             100666736 bytes
Database Buffers           50331648 bytes
Redo Buffers                2924544 bytes
Banco de dados montado.

SQL> recover database;
ORA-00283: sessão de recuperação cancelada devido a erros
ORA-00264: nenhuma recuperação necessária

Apenas para validar o cold backup, podemos perceber acima como era de se esperar, que o comando RECOVER DATABASE falhou, pelo fato de os arquivos de banco de dados já estarem consistentes e, portanto, não haveria nenhuma necessidade de qualquer tipo de recuperação.

Como poderemos então aplicar os arquivos de redo log arquivados sobre este banco de dados de modo a reconstruir todas as transações realizadas anteriormente? A chave para isso é utilizar o comando RECOVER DATABASE em conjunto com a cláusula USING BACKUP CONTROLFILE sendo que, a cláusula UNTIL CANCEL poderá ser utilizada agora ou depois, como demonstrarei mais a frente. Neste caso, podemos dizer que os arquivos de controle restaurados, na verdade, são realmente backups dos arquivos de controle. Selecionarei a opção AUTO para que eu não precise confirmar os arquivos de redo log arquivados um a um.

SQL> recover database using backup controlfile;
ORA-00279: alterar 187046 gerado em 04/15/2009 13:31:13 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_1_684148997.dbf
ORA-00280: alterar 187046 para o thread 1 está na seqüência  #1

Especificar log: {=nome de arquivo | sugerido | AUTO | CANCEL}
AUTO
ORA-00279: alterar 187315 gerado em 04/15/2009 13:34:12 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_2_684148997.dbf
ORA-00280: alterar 187315 para o thread 1 está na seqüência  #2
ORA-00278: o arquivo de log '/u01/archive/1_1_684148997.dbf' não é mais 
necessário para esta recuperação

ORA-00279: alterar 187390 gerado em 04/15/2009 13:34:13 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_3_684148997.dbf
ORA-00280: alterar 187390 para o thread 1 está na seqüência  #3
ORA-00278: o arquivo de log '/u01/archive/1_2_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187467 gerado em 04/15/2009 13:34:15 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_4_684148997.dbf
ORA-00280: alterar 187467 para o thread 1 está na seqüência  #4
ORA-00278: o arquivo de log '/u01/archive/1_3_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187541 gerado em 04/15/2009 13:34:16 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_5_684148997.dbf
ORA-00280: alterar 187541 para o thread 1 está na seqüência  #5
ORA-00278: o arquivo de log '/u01/archive/1_4_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187617 gerado em 04/15/2009 13:34:20 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_6_684148997.dbf
ORA-00280: alterar 187617 para o thread 1 está na seqüência  #6
ORA-00278: o arquivo de log '/u01/archive/1_5_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187693 gerado em 04/15/2009 13:34:21 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_7_684148997.dbf
ORA-00280: alterar 187693 para o thread 1 está na seqüência  #7
ORA-00278: o arquivo de log '/u01/archive/1_6_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187769 gerado em 04/15/2009 13:34:22 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_8_684148997.dbf
ORA-00280: alterar 187769 para o thread 1 está na seqüência  #8
ORA-00278: o arquivo de log '/u01/archive/1_7_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187909 gerado em 04/15/2009 13:34:26 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_9_684148997.dbf
ORA-00280: alterar 187909 para o thread 1 está na seqüência  #9
ORA-00278: o arquivo de log '/u01/archive/1_8_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 187982 gerado em 04/15/2009 13:34:27 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_10_684148997.dbf
ORA-00280: alterar 187982 para o thread 1 está na seqüência  #10
ORA-00278: o arquivo de log '/u01/archive/1_9_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 188055 gerado em 04/15/2009 13:34:28 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_11_684148997.dbf
ORA-00280: alterar 188055 para o thread 1 está na seqüência  #11
ORA-00278: o arquivo de log '/u01/archive/1_10_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 188127 gerado em 04/15/2009 13:34:32 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_12_684148997.dbf
ORA-00280: alterar 188127 para o thread 1 está na seqüência  #12
ORA-00278: o arquivo de log '/u01/archive/1_11_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00279: alterar 188197 gerado em 04/15/2009 13:35:05 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_13_684148997.dbf
ORA-00280: alterar 188197 para o thread 1 está na seqüência  #13
ORA-00278: o arquivo de log '/u01/archive/1_12_684148997.dbf' não é mais
necessário para esta recuperação

ORA-00308: não é possível abrir o log '/u01/archive/1_13_684148997.dbf arquivado'
ORA-27037: não é possível obter status do arquivo
Linux Error: 2: No such file or directory
Additional information: 3

Agora a pergunta que não quer calar: Como é possível o arquivo de controle saber da existência dos arquivos de redo log arquivados sendo que os mesmos não foram gerados anteriormente (antes do cold backup)? Na verdade, ele não sabe e nem teria como saber, então podemos chegar a conclusão de que este é um comportamento padrão quando utilizamos a cláusula USING BACKUP CONTROLFILE do comando RECOVER DATABASE, ou seja, o processo de recuperação irá perguntar automaticamente e de forma seqüencial por arquivos de redo log arquivados e, caso o processo localize o arquivo de redo log arquivado, o mesmo será fornecido como opção para ser aplicado até o momento em que desejarmos cancelar a operação (CANCEL).

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERRO na linha 1:
ORA-01113: o arquivo 1 precisa da recuperação de mídia
ORA-01110: 1 do arquivo de dados: '/u01/app/oracle/oradata/BD01/system01.dbf'

Podemos ver acima que após a aplicação de todos os arquivos de redo log arquivados possíveis (logs de 1 até 12), mesmo assim ainda não foi possível abrir o banco de dados, isso porque será necessário sinalizar o final do processo de recuperação utilizando a cláusula UNTIL CANCEL, pois o arquivo de redo log arquivado 1_13_684148997.dbf apesar de não existir, realmente não seria necessário como demonstrado abaixo:

SQL> recover database using backup controlfile until cancel;
ORA-00279: alterar 188197 gerado em 04/15/2009 13:35:05 necessário para o thread 1
ORA-00289: sugestão : /u01/archive/1_13_684148997.dbf
ORA-00280: alterar 188197 para o thread 1 está na seqüência  #13

Especificar log: {=nome de arquivo | sugerido | AUTO | CANCEL}
CANCEL

recuperação de mídia cancelada.

Pronto. Após aplicados todos os arquivos de redo log arquivados possíveis, poderemos então abrir o banco de dados com a opção RESETLOGS.

SQL> alter database open resetlogs;

Banco de dados alterado.

Apenas para certificar que o banco de dados foi realmente recuperado até a última transação, selecionarei o registro da tabela SCOTT.T2 criada antes da realização do cold backup, para verificar se o registro inserido foi recuperado com sucesso.

SQL> connect scott/tiger
Conectado.

SQL> select * from t2;

DATA
--------------------------
15/04/2009 13:34:36,883986


Eduardo Legatti é Analista de Sistemas e DBA Oracle. É pós graduado em Gerência da Tecnologia da Informação, possui as certificações OCA 9i - OCP 9i/10g/11g – OCE, e vem trabalhando como DBA Oracle desde a versão 8.0.5. Freqüentemente posta artigos em http://eduardolegatti.blogspot.com