Páginas

19 de set. de 2014

Restauração de tabelas com o RMAN até o Oracle 11G

   

Olá pessoal,
 
     No artigo de hoje vou mostrar como recuperar dados de uma ou mais tabelas de um Banco de Dados Oracle, com o RMAN, sem tirá-lo do ar. Este processo de recuperação é simples no Oracle 12c, mas dá bastante trabalho no Oracle até a versão 11G! Como ainda administro BDs na versão 11G e precisei fazer uma recuperação com essas características recentemente, aproveito para compartilhar o roteiro aqui no blog.
     
     Para seguir o roteiro que vou explicar adiante é necessário ter conhecimentos básicos de Administração de BD e RMAN.  Faremos a simulação de uma restauração de 2 tabelas de um BD de Produção, que possuem relacionamento (1 tabela pai e 1 tabelas filha) e que foram alteradas erroneamente por um usuário do BD. O processo de restauração será executado por meio do RMAN a partir de backups preexistentes. Iremos restaurar as tabelas com nomes TAB1 e TAB2 do schema RH, com os dados de um momento anterior ao momento em que o usuário fez as alterações erradas. Para facilitar a compreensão do roteiro, o horário em que o usuário fez as alterações indevidas foi aprox. 17h do dia 18/09/2014, portanto, precisamos restaurar os dados com um horário anterior, que neste caso será 16:50h do dia 18/09/2014.

Obs.: É importante ressaltar que a restauração de um backup físico deve ser a última solução que devemos recorrer. Primeiramente, por questões de facilidade e agilidade, prefira restaurar os dados da(s) tabela(s) (quando possível) através de métodos de recuperação lógicos, tais como: Flashback Table, Flashback Versions ou Importação de um dump. 


PRÉ-REQUISITOS
    
1- Ter uma máquina separada (pode ser uma VM), que chamaremos de máquina de laboratório ou simplesmente LAB, disponível para criar uma nova instância "temporária" e fazer a restauração dos dados (ver Imagem 01). Essa instância temporária (também conhecida como instância auxiliar) irá formar um "clone" parcial do BD de produção;

Imagem 01: Backup baseado em duplicação
Fonte: Oracle Corporation

2- Ter backups do BD de produção, incluindo backup atualizado do Control File e de todos os Archive Logs (se existirem) que foram gerados desde o último backup até o momento da recuperação dos dados.


ROTEIRO DE RECUPERAÇÃO DE TABELAS COM O RMAN
     
1- Criando a instância temporária:
     Para minimizar riscos e não ter que parar o BD de Produção para efetuar a restauração, crie no LAB uma nova instância "temporária", com o mesmo nome e versão do SGBD da instância de produção, e copie os backups e archive logs para uma pasta dessa máquina.

2- Preparando a instância temporária:
     Como iremos efetuar no próximo passo a restauração de um Control File de Produção na instância "temporária", crie no LAB diretórios correspondentes aos locais de gravação de todos os arquivos do BD de Produção, como por exemplo, os diretórios do(s) Control File(s), Redo Logs, Archive Logs, Datafiles etc.;

3- Restaurando o Control File de Produção na instância temporária:
     Agora iremos nos conectar na instância temporária para fazer a restauração do Control File do BD de Produção, criando deste modo, um BD clone do BD de Produção (para posteriormente restaurar nele os dados das tabelas desejadas). Em seguida, registraremos o diretório em que os backups foram copiados, para permitir no próximo passo, a restauração deles.
     Seguem abaixo em azul, os comandos que devem ser executados, e ao lado, comentários em cinza que devem ser avaliados antes ou depois da execução dos comandos:

     $> export ORACLE_SID=prod -- substituir valor em vermelho por nome do bd temporario (que foi configurado igual ao nome do BD de produção)
     $> rman target /
     RMAN> shutdown immediate; 
     RMAN> startup nomount;
     RMAN> restore controlfile from '/tmp/backup/snapcf_prod.f' -- substituir valor em vermelho por caminho da pasta no LAB em que estão localizados os backups;
     RMAN> alter database mount;
     RMAN> exit
     $> sqlplus / as sysdba
     SQL> alter database flashback off;   -- Se o BD de Produção tinha Flashback Database habilitado, desabilite-o através deste comando 
     SQL> exit
     $> rman target /
     RMAN> catalog start with '/tmp/backup'; - substituir valor em vermelho por caminho da pasta no LAB em que estão localizados os backups;

4- Restaurando backups no BD temporário:
     Este é um dos passos principais do roteiro, onde iremos efetuar a restauração dos datafiles do backup para posteriormente recuperar as tabelas desejadas. O que é necessário entender neste passo é que não precisamos restaurar todos os datafiles do BD de Produção. Para ganhar tempo e até mesmo economizar espaço em disco, devemos restaurar apenas o básico para que o BD clone funcione. Neste caso, iremos restaurar os datafiles dos tablespaces SYSTEM, SYSAUX, UNDOTBS e o tablespace RH. Este último, contém as tabelas desejadas. Poderíamos optar por não restaurar o tablespace de UNDO, mas isso iria demandar passos extras para criar um novo, que acabariam aumentando a complexidade do processo.
     Antes de fazer a restauração, execute o script abaixo no BD de produção para descobrir o file_id dos datafiles que precisamos restaurar:
            select file_id, file_name, 
                   tablespace_name 
            from   dba_data_files 
            where tablespace_name in ('SYSTEM','SYSAUX','UNDOTBS','RH')
            union all
            SELECT file_id, file_name, tablespace_name
            from   dba_temp_files;

     Com "ile_id dos datafiles desejados, execute 1 dos roteiros abaixo, que contém em azul os comandos que irão fazer a restauração, e ao lado, comentários em cinza, que devem ser avaliados antes ou depois da execução deles:
       
              a) Restauração dos datafiles para pastas com o mesmo nome da origem:
       RMAN> run {
            restore datafile 1, 2, 3, 191, 84;
            sql "alter database datafile 1 online"; -- substituir valor em vermelho pelo id do datafile do tablespace system
            sql "alter database datafile 2 online"; -- substituir valor em vermelho pelo id do datafile do tablespace sysaux
            sql "alter database datafile 3 online"; -- substituir valor em vermelho pelo id do datafile do tablespace de UNDO
            sql "alter database datafile 343 online"; -- substituir valor em vermelho pelo id do datafile do tablespace RH
        }
 
              a) Restauração dos datafiles para pastas diferentes:
       RMAN> run {
            set newname for datafile 1 to "/oradata/lab/system01.dbf";
            set newname for datafile 2 to "/oradata/lab/sysaux.dbf";
            set newname for datafile 3 to "/oradata/lab/undotbs.dbf";
            set newname for datafile 343 to "/oradata/lab/rh.dbf";
            sql "alter database rename file ''/oradata/prod/system01.dbf'' to ''/oradata/lab/rh.dbf''";
            sql "alter database rename file ''/oradata/prod/sysaux.dbf'' to ''/oradata/lab/rh.dbf''";            
            sql "alter database rename file ''/oradata/prod/undotbs.dbf'' to ''/oradata/lab/rh.dbf''";
            sql "alter database rename file ''/oradata/prod/rh.dbf'' to ''/oradata/lab/rh.dbf''";
            switch tempfile all;
            restore datafile 1, 2, 3, 343;
            switch datafile all;
            sql "alter database datafile 1 online";
            sql "alter database datafile 2 online";
            sql "alter database datafile 3 online";
            sql "alter database datafile 343 online";
        }

5- Recuperando backups no BD temporário:
     Neste passo iremos recuperar nos datafiles restaurados no passo anterior os dados dos Archive Logs da data/hora desejada. Antes disso, porém, é necessário gerar uma lista contendo o nome de todos os datafiles que não nos interessa recuperar, incluindo no comando RECOVER a instrução SKIP para ignorá-los. Para  alcançar este resultado execute o SQL abaixo:

       SQL> -- recupera nomes de tablespaces a pular
            SET SERVEROUTPUT ON
            DECLARE
              V_SQL VARCHAR2(32767);
            BEGIN
              FOR LINHA IN  (select TABLESPACE_NAME 
                             from dba_data_files 
                             where tablespace_name NOT in
                                   ('UNDOTBS','RH',','SYSAUX','SYSTEM'))
              LOOP
                  v_SQL := v_SQL || LINHA.TABLESPACE_NAME || ', ';
              END LOOP;
              
              -- monta comando RECOVER, substituindo ultimo caractere "," por ";"
              v_SQL := 'RECOVER DATABASE SKIP FOREVER TABLESPACE ' ||           
                          SUBSTR(v_SQL, 1, LENGTH(V_SQL)- 2) || ';';
              dbms_output.put_line(V_SQL);
            END;       

     Pegue o resultado do script acima, substitua-o na linha em laranja do script abaixo e execute o script final no RMAN:
        
       RMAN> run {
                  set until time "to_date('18/09/2014 16:50:00','dd/mm/yyyy hh24:mi:ss')";            
                  RECOVER DATABASE SKIP FOREVER TABLESPACE TBS1, TBS2, TB3;
                  alter database open resetlogs;
                 }


6- Corrigindo possíveis problemas:
      Se a abertura do BD falhar no passo anterior, investigue e corrija o que está diferente nas configurações atuais do BD clone. Talvez não existam no LAB as pastas correspondentes às da máquina de Produção para gravação dos Redo Logs, Archives, Flashback Database ou Auditoria etc. Soluções possíveis para resolver este problema é criar as pastas correspondentes ou desabilitar os recursos correspondentes (que não são necessários no BD clone). Após corrigir o problema, tente novamente abrir o BD com o comando abaixo:
       SQL> alter database open resetlogs;

7- Exportando dados do BD clone:
     Agora que o BD clone já está no ar, gere um dump com as tabelas que você deseja recuperar, utilizando o export convencional, como no exemplo abaixo:
       $> exp userid=usuario/senha file=rh.dmp log=rh.log tables=rh.tab1, rh.tab2 -- substituir valores em vermelho pelos seus respectivos valores 

8- Copiando o dump para a máquina de Produção:
     Neste passo copie o dump gerado no passo anterior para uma pasta qualquer da máquina de Produção, como no exemplo abaixo (que simula a operação em SO Linux):
       $> scp rh.dmp host_producao:/oratmp  -- substituir valores em vermelho pelos seus respectivos valores 

9- Importando o dump na máquina de Produção:
     Este é o passo final onde iremos importar os dados desejados no BD de Produção. Por questões de segurança, recomendo não fazer a importação diretamente no schema do sistema relacionado, neste caso, o sistema de RH. Importe os dados em um schema temporário preexistente e faça um MERGE nos dados das respectivas tabelas, começando pela tabela pai, como no exemplo abaixo:
    
           a) Importando os dados no schema temporário:
       $> imp userid=usuario/senha file=rh.dmp log=rh.log fromuser=rh touser=rh_temp

           bEfetuando um MERGE para "combinar" os dados recuperados com os dados de produção:  
       SQL> MERGE INTO rh.tab1 d  -- tab1 é a tabela pai do sistema de producao
      USING ( SELECT  *
              FROM    rhtemp.tab1) O
      ON    (D.COL_PK = O.COL_PK)
  WHEN  MATCHED THEN  
      UPDATE  
      SET       D.COL1 = O.COL1,
                D.COL2 = O.COL2                
  WHEN NOT MATCHED THEN
      INSERT (D.COL_PK, D.COL1, D.COL2)
      VALUES (O.COL_PK, O.COL1, O.COL2);


       SQL> MERGE INTO rh.tab2 d  -- tab2 é a tabela filha do sistema de producao
      USING ( SELECT  *
              FROM    rhtemp.tab1) O
      ON    (D.COL_PK = O.COL_PK)
  WHEN  MATCHED THEN  
      UPDATE  
      SET       D.COL1 = O.COL1,
                D.COL2 = O.COL2                
  WHEN NOT MATCHED THEN
      INSERT (D.COL_PKD.COL1D.COL2)
      VALUES (O.COL_PKO.COL1O.COL2);
  COMMIT;
   

     Pronto! Agora é só conferir os dados nas tabelas originais do BD de Produção. Infelizmente é bem trabalhoso fazer este tipo de recuperação até o Oracle Database 11G. A boa notícia é que no 12C o processo está bem mais fácil!
   
     Qualquer dúvida ou problema ao executar este roteiro, deixe um comentário!
 
[]s
 
Referências:
   - Restore RMAN backup to another server for testing disaster recovery procedures as well as for cloning
   

6 comentários:

  1. Excelente trabalho Fábio, muito legal, parabéns.

    ResponderExcluir
  2. Fabio bom dia, tenho um duvida sobre a restauração de backup.
    Tenho uma base de teste onde sao criadas tabelas novas pela area de desenvolvimento e quando o pessoal que administra o banco faz restore de backup nesta base teste , perdemos estas tabelas pois ao restaurar o backup estas tabelas nao existe na base de produção.
    De que forma posso pedir para o pessoal do banco realizar o restore na base teste sem a estas tabelas sejam apagadas.

    Agradeço desde ja se puder me ajudar.

    ResponderExcluir
    Respostas
    1. Você descreveu o problema, mas não escreveu qual é a dúvida.

      Excluir
    2. Boa tarde Fabio,

      A duvida e de como devo pedir para o pessoal Adm do Banco faça o restore do BKP da base prod na base teste, sem apagar as tabelas que so existem na base teste. Da forma que eles estao realizando o restore as tabelas da base teste sao apagadas.

      Excluir
    3. Agora percebi que vc havia feito a pergunta já no primeiro contato, mas não havia colocado o devido ponto de interrogação (?) na frase. Isso dificultou o entendimento. Agora entendi e segue abaixo a resposta:

      Peça para eles fazerem um export das tabelas que você não pode perder no ambiente de teste (informando schema e nome dos objetos), para posterior recuperação via impdp após efetuarem a restauração do backup, ok?

      Excluir