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;
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
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 /
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:
a) Restauração dos datafiles para pastas com o mesmo nome da origem:
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;
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'))
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) || ';';
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_tempb) Efetuando 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_PK, D.COL1, D.COL2)
VALUES (O.COL_PK, O.COL1, O.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
[]s
Referências:
- Restore RMAN backup to another server for testing disaster recovery procedures as well as for cloning
Excelente trabalho Fábio, muito legal, parabéns.
ResponderExcluirObrigado pelo feedback Moisés!
ExcluirFabio bom dia, tenho um duvida sobre a restauração de backup.
ResponderExcluirTenho 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.
Você descreveu o problema, mas não escreveu qual é a dúvida.
ExcluirBoa tarde Fabio,
ExcluirA 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.
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:
ExcluirPeç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?