Pular para o conteúdo

Recuperação Pontual de Dados: Point-In-Time Recovery (DBPITR) e Tablespace Point-in-Time Recovery (TSPITR)

Database Point-In-Time Recovery (DBPITR) e Tablespace Point-in-Time Recovery (TSPITR)

Olá,

Neste artigo irei abordar um pouco da técnica de recuperação pontual de dados já bem conhecida entre os DBAs Oracle chamada de Tablespace Point-in-Time Recovery (TSPITR) disponível desde a versão do Oracle 8 e também uma outra técnica chamada Database Point-in-Time Recovery (DBPITR).

Basicamente o TSPITR (Recuperação Pontual de Tablespace) é uma funcionalidade que fornece ao DBA a opção de recuperar um conjunto de dados em um ponto específico no tempo sem afetar o restante do banco de dados. Por isso a importância de separar aplicações distintas em tablespaces separados, no qual acredito ser uma boa prática. Em um primeiro momento esta técnica é útil para recuperar dados que foram erroneamente afetados por alguma operação DML ou até mesmo DDL (insert, delete, update, drop, truncate, etc…). A vantagem de utilizar esta técnica é a possibilidade que o DBA tem de “voltar no tempo” os dados de uma determinada aplicação deixando outras aplicações e o restante do banco de dados intacto, ou seja, “no tempo atual” e acessível aos usuários.

Já o DBPITR possibilita um banco de dados inteiro “voltar no tempo” da mesma forma que o recurso Flashback Database (10g) possibilita. A diferença é que este último possibilita uma operação muito mais prática e significativamente mais rápida, conforme estudo realizado e apresentado no fim deste artigo. Portanto, é necessário que o DBA saiba analisar cuidadosamente o impacto desta ação no banco de dados ao escolher cada uma das duas técnicas (DBPITR vs TSPITR) para que, assim, o mesmo possa decidir qual e quando usar uma ou outra abordagem.

Os conceitos por trás do TSPITR requer alguns conhecimentos como Incomplete Recovery, TTS (Transport Tablespaces), DBPITR, banco de dados auxiliar, que, se realizado manualmente, com certeza daria muito mais trabalho. Felizmente, o utilitário RMAN (Recovery Manager) consegue automatizar toda esta tarefa com apenas alguns comandos.

No mais, neste artigo irei simular através do RMAN uma operação de DBPITR e outra de TSPITR de forma a demonstrar o conceito por trás de cada abordagem. Ao final, poderemos verificar a vantagem do uso de ambas as técnicas.

Para realizar a simulação, utilizarei o Oracle 11g R2 instalado e configurado em uma máquina virtual usando o sistema operacional Linux – Centos 5.2 como poderemos ver logo abaixo:

[oracle@linux1 ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Sex Mar 5 14:44:22 2010

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

Conectado a:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

Vale a pena salientar que é de fundamental importância que o banco de dados esteja operando no modo de arquivamento (ARCHIVELOG) e que os backups físicos do mesmo estejam consistentes e disponíveis para uso.

-- Verificando o modo de operação do banco de dados

SQL> archive log list

Modo log de banco de dados     Modo de Arquivamento

Arquivamento automático        Ativado

Destino de arquivamento        USE_DB_RECOVERY_FILE_DEST

A sequência de log on-line mais antiga     60

Próxima sequência de log a arquivar   62

Sequência de log atual           62

Irei criar abaixo dois tablespaces de forma a simular duas aplicações distintas em uso no banco de dados. Irei supor que o tablespace TBS_01 possui objetos (segmentos) referente aos dados de uma aplicação de Recursos Humanos, e que o tablespace TBS_02 possui objetos (segmentos) referente aos dados de uma aplicação de Vendas.

SQL> create tablespace tbs_01 datafile '/u01/app/oracle/oradata/BD01/tbs01.dbf' size 5m;

Tablespace criado.

SQL> create tablespace tbs_02 datafile '/u01/app/oracle/oradata/BD01/tbs02.dbf' size 5m;

Tablespace criado.

Agora irei criar dois usuários de banco de dados, cada um associado ao seu tablespace, de forma a simular as aplicações distintas em uso no banco de dados. Irei supor que o usuário USUARIO_01 associado ao tablespace TBS_01, possui objetos referentes aos dados da aplicação de Recursos Humanos, e que o usuário USUARIO_02 associado ao tablespace TBS_02 possui objetos referente aos dados de uma aplicação de Vendas.

SQL> create user usuario_01 identified by senha default tablespace tbs_01;

Usuário criado.

SQL> create user usuario_02 identified by senha default tablespace tbs_02;

Usuário criado.

SQL> grant connect,resource to usuario_01,usuario_02;

Concessão bem-sucedida.

Por fim, irei criar uma tabela em cada usuário e popular as mesmas com 10 registros cada uma como demonstrado abaixo:

SQL> create table usuario_01.tabela_01 (id number);

Tabela criada.

SQL> insert into usuario_01.tabela_01 select rownum id from dual connect by level <=10;

10 linhas criadas.

SQL> create table usuario_02.tabela_02 (id number);

Tabela criada.

SQL> insert into usuario_02.tabela_02 select rownum id from dual connect by level <=10;

10 linhas criadas.

SQL> commit;

Commit concluído.

Ao final da execução dos procedimentos acima podemos visualizar abaixo o esquema do banco de dados gerado, supondo que o usuário USUARIO_01 é o proprietário da tabela do sistema de Recursos Humanos e o usuário USUARIO_02 o proprietário da tabela do sistema de Vendas:

SQL> select owner,table_name,tablespace_name
  2  from dba_tables
  3  where owner in ('USUARIO_01','USUARIO_02');

OWNER                        TABLE_NAME                   TABLESPACE_NAME
---------------------------- ---------------------------- ----------------------------
USUARIO_01                   TABELA_01                    TBS_01
USUARIO_02                   TABELA_02                    TBS_02
SQL> exit

Desconectado de Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

Como parte da demonstração da simulação, irei realizar um backup do banco de dados utilizando o RMAN.

[oracle@linux1 ~]$ rman target /

Gerenciador de Recuperação: Release 11.2.0.1.0 - Production on Sex Mar 5 15:02:15 2010

 Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

conectado ao banco de dados de destino: BD01 (DBID=2967836454)

RMAN> backup database;

Iniciando backup em 05/03/2010

usar o arquivo de controle do banco de dados de destino em vez do catálogo de recuperação

canal alocado: ORA_DISK_1

canal ORA_DISK_1: SID=16 tipo de dispositivo=DISK

canal ORA_DISK_1: iniciando conjunto de backup completo de arquivo de dados

canal ORA_DISK_1: especificando arquivo[s] de dados no conjunto de backups

número do arquivo=00001 nome=/u01/app/oracle/oradata/BD01/system01.db

número do arquivo=00003 nome=/u01/app/oracle/oradata/BD01/sysaux01.dbf

número do arquivo=00002 nome=/u01/app/oracle/oradata/BD01/undotbs01.dbf

número do arquivo=00004 nome=/u01/app/oracle/oradata/BD01/users01.dbf

número do arquivo=00005 nome=/u01/app/oracle/oradata/BD01/tbs01.dbf

número do arquivo=00006 nome=/u01/app/oracle/oradata/BD01/tbs02.dbf

canal ORA_DISK_1: iniciando o componente 1 em 05/03/2010

canal ORA_DISK_1: componente 1 finalizado em 05/03/2010

handle de componente=/u01/app/oracle/flash_recovery_area/BD01/backupset/2010_03_05/

o1_mf_nnndf_TAG20100305T150232_5q8g1cv5_.bkp tag=TAG20100305T150232 comentário=NONE

canal ORA_DISK_1: conjunto de backups concluído, tempo decorrido: 00:01:57

canal ORA_DISK_1: iniciando conjunto de backup completo de arquivo de dados

canal ORA_DISK_1: especificando arquivo[s] de dados no conjunto de backups

incluindo arquivo de controle atual no conjunto de backups

incluindo SPFILE atual do conjunto de backups

canal ORA_DISK_1: iniciando o componente 1 em 05/03/2010

canal ORA_DISK_1: componente 1 finalizado em 05/03/2010

handle de componente=/u01/app/oracle/flash_recovery_area/BD01/backupset/2010_03_05/

o1_mf_ncsnf_TAG20100305T150232_5q8g52yc_.bkp tag=TAG20100305T150232 comentário=NONE

canal ORA_DISK_1: conjunto de backups concluído, tempo decorrido: 00:00:01

Finalizado backup em 05/03/2010

RMAN> exit

Recovery Manager completo.

Após a realização do backup físico do banco de dados, irei simular um erro ocasionado por um comando DDL emitido no schema de banco de dados do sistema de Recursos Humanos (USUARIO_01), onde inadvertidamente a tabela TABELA_01 foi dropada utilizando a cláusula PURGE, ou seja, sem chance de a mesma ser recuperada da lixeira (recyclebin).

oracle@linux1 ~]$ sqlplus usuario_01/senha

SQL*Plus: Release 11.2.0.1.0 Production on Sex Mar 5 15:21:13 2010
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
Conectado a:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

SQL> select * from tabela_01;

       ID
----------
        1
        2
        3
        4
        5
        6
        7
        8
        9
       10

10 linhas selecionadas.

SQL> select systimestamp from dual;

SYSTIMESTAMP
-------------------------------
05/03/10 15:21:45,423501 -03:00

SQL> drop table tabela_01 purge;

Tabela eliminada.

Apenas para fins didáticos, antes de ter dropado a tabela TABELA_01 (do sistema de Recursos Humanos), eu consultei a data e hora atual para sinalizar um momento no tempo em que a tabela existia. Este horário será útil logo mais a frente. Agora irei simular abaixo uma atualização na tabela TABELA_02 (do sistema de Vendas).

SQL> connect usuario_02/senha;

Conectado.

SQL> select * from tabela_02;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

SQL> update tabela_02 set id=id*100;

10 linhas atualizadas.

SQL> commit;

Commit concluído.

SQL> select * from tabela_02;

        ID
----------
       100
       200
       300
       400
       500
       600
       700
       800
       900
      1000

10 linhas selecionadas.

SQL> select systimestamp from dual;

SYSTIMESTAMP

-------------------------------

05/03/10 15:25:31,423501 -03:00

Pronto. O cenário está montado. Uma tabela importante do sistema de Recursos Humanos foi dropada acidentalmente e uma operação importante foi realizada na tabela do sistema de Vendas. Note que todas as linhas da tabela TABELA_02 do sistema de Vendas foram atualizadas tendo o valor da coluna ID multiplicada por 100.

Se eu utilizar a técnica DBPITR para restaurar a tabela TABELA_01 do usuário USUARIO_01 (sistema Recursos Humanos), vejamos o que acontece.

Após realizar o shutdown do banco de dados, irei realizar uma conexão através do RMAN, montar o banco de dados e iniciar o processo de DBPITR conforme demonstração abaixo:

Database Point-In-Time Recovery (DBPITR)

[oracle@linux1 ~]$ export NLS_DATE_FORMAT='dd/mm/yyyy hh24:mi:ss'

[oracle@linux1 ~]$ rman target /

Gerenciador de Recuperação: Release 11.2.0.1.0 - Production on Sex Mar 5 16:51:43 2010

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

conectado ao banco de dados de destino (não iniciado)

RMAN> startup mount

instância Oracle iniciada

banco de dados montado

Total da Área Global do Sistema     133906432 bytes

Fixed Size                     1335024 bytes

Variable Size                113246480 bytes

Database Buffers              16777216 bytes

Redo Buffers                   2547712 bytes

Sabendo-se que a tabela TABELA_01 não fora dropada antes das 05/03/2010 15:21:45, utilizarei este horário para “voltar o banco neste tempo”. O processo de DBPITR se resume aos comandos a seguir:

RMAN> run {set until time '05/03/2010 15:21:45';

2> restore database;

3> recover database;

4> alter database open resetlogs;}

executando comando: SET until clause

Iniciando restore em 05/03/2010 16:52:41

usar o arquivo de controle do banco de dados de destino em vez do catálogo de recuperação

canal alocado: ORA_DISK_1

canal ORA_DISK_1: SID=18 tipo de dispositivo=DISK

canal ORA_DISK_1: iniciando restauração de conjunto de backups de arquivo de dados

canal ORA_DISK_1: especificando arquivo(s) de dados para restauração a partir do conjunto

                  de backups

canal ORA_DISK_1: restaurando o arquivo de dados 00001 em /u01/app/oracle/oradata/BD01/

                  system01.dbf

canal ORA_DISK_1: restaurando o arquivo de dados 00002 em /u01/app/oracle/oradata/BD01/

                  undotbs01.dbf

canal ORA_DISK_1: restaurando o arquivo de dados 00003 em /u01/app/oracle/oradata/BD01/

                  sysaux01.dbf

canal ORA_DISK_1: restaurando o arquivo de dados 00004 em /u01/app/oracle/oradata/BD01/

                  users01.dbf

canal ORA_DISK_1: restaurando o arquivo de dados 00005 em /u01/app/oracle/oradata/BD01/

                  tbs01.dbf

canal ORA_DISK_1: restaurando o arquivo de dados 00006 em /u01/app/oracle/oradata/BD01/

                  tbs02.dbf

canal ORA_DISK_1: lendo da parte de backup /u01/app/oracle/flash_recovery_area/BD01/

                  backupset/2010_03_05/o1_mf_nnndf_TAG20100305T150232_5q8g1cv5_.bkp

canal ORA_DISK_1: handle de componente=/u01/app/oracle/flash_recovery_area/BD01/

                  backupset/2010_03_05/o1_mf_nnndf_TAG20100305T150232_5q8g1cv5_.bkp

                  tag=TAG20100305T150232

canal ORA_DISK_1: restaurada a parte de backup 1

canal ORA_DISK_1: restauração concluída, tempo decorrido: 00:02:17

Finalizado restore em 05/03/2010 16:55:01

Iniciando recover em 05/03/2010 16:55:01

utilizando o canal ORA_DISK_1

iniciar recuperação de mídia

recuperação da mídia concluída, tempo decorrido: 00:00:15

Finalizado recover em 05/03/2010 16:55:19

banco de dados aberto

RMAN> exit

Recovery Manager completo.

Após finalizado o processo de recuperação, irei conectar com o usuário USUARIO_01 para verificar se a tabela TABELA_01 foi restaurada.

[oracle@linux1 ~]$ sqlplus usuario_01/senha

SQL*Plus: Release 11.2.0.1.0 Production on Sex Mar 5 17:01:07 2010

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

Conectado a:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

SQL> select * from tabela_01;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

Perfeito. A tabela foi restaurada exatamente como estava às 05/03/2010 15:21:45. Mas, e quanto aos dados da tabela TABELA_02 do sistema de Vendas? Vejamos abaixo:

SQL> connect usuario_02/senha

Conectado.

SQL> select * from tabela_02;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

Hum… podemos perceber que a atualização realizada na tabela TABELA_02 às 05/03/2010 15:25:31 onde multiplicamos o valor da coluna ID por 100 foi perdida. Isto aconteceu porque o processo de recuperação restaurou e recuperou os dados até às 05/03/2010 15:21:45 como solicitado e, neste horário, os dados da tabela TABELA_02 não tinham ainda sido atualizados. Em resumo, realizar o DBPITR não seria a melhor solução para este cenário pois a solução de um problema ocasionou o aparecimento de outro problema, ou seja, os usuários do sistema de Recursos Humanos ficariam super satisfeitos, enquanto os usuários do sistema de Vendas ficariam totalmente insatisfeitos, inclusive exigindo mil e uma explicações sobre o que teria provocado a perda de informações no sistema e o porquê. Daí a importância de o DBA saber analisar cuidadosamente o impacto de qualquer opção de recuperação antes de qualquer coisa.

Bom, este foi o cenário onde realizei o DBPITR. E quanto ao TSPITR? Esta técnica será demonstrada abaixo onde o cenário é igual ao que foi demonstrado acima. Após a realização do backup físico do banco de dados, novamente irei realizar as mesmas operações nas tabelas envolvidas nos dois sistemas, ou seja, irei dropar a tabela TABELA_01 de propriedade do usuário USUARIO_01 (sistema de Recursos Humanos) e realizar a alteração na tabela TABELA_02 (sistema de Venda) com o comando UPDATE que realiza a multiplicação do valor da coluna ID por 100.

Tablespace Point-in-Time Recovery (TSPITR)

SQL> connect usuario_01/senha

Conectado.

SQL> select * from tabela_01;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

SQL> select systimestamp from dual;

SYSTIMESTAMP
-------------------------------
06/03/10 10:26:34,707082 -03:00

SQL> drop table tabela_01 purge;

Tabela eliminada.

SQL> connect usuario_02/senha;

Conectado.

SQL> select * from tabela_02;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

SQL> update tabela_02 set id=id*100;

10 linhas atualizadas.

SQL> commit;

Commit concluído.

SQL> select * from tabela_02;

        ID
----------
       100
       200
       300
       400
       500
       600
       700
       800
       900
      1000

10 linhas selecionadas.

SQL> select systimestamp from dual;

SYSTIMESTAMP
-------------------------------
06/03/10 10:30:43,707082 -03:00

Bom, sabemos que a tabela TABELA_01 foi dropada às 06/03/2010 10:26:34, enquanto os dados da tabela TABELA_02 foi atualizada às 06/03/2010 10:30:43. O objetivo então será restaurar a tabela TABELA_01 de propriedade do usuário USUARIO_01 e pertencente ao tablespace TBS_01, sem afetar o resto do banco de dados, ou seja, sem afetar os dados do sistema de Vendas de propriedade do usuário USUARIO_02 no tablespace TBS_02.

Para que o processo de recuperação utilizando a técnica TSPITR seja possível, será necessário criar um diretório de sistema operacional que será utilizado para a realização do processo de recuperação.

[oracle@linux1 /]$ mkdir /u01/aux_dest

No caso do TSPITR, o banco de dados precisa estar aberto (no estado OPEN). Apenas para fins de demonstração, se eu tentar realizar o TSPITR (Recuperação Pontual de Tablespace) com o banco de dados montado, a mensagem abaixo será emitida:

[oracle@linux1 u01]$ rman target /

Gerenciador de Recuperação: Release 11.2.0.1.0 - Production on Sab Mar 6 10:28:27 2010

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

conectado ao banco de dados de destino: BD01 (DBID=2967836454, não aberto)

RMAN> recover tablespace tbs_01

2> until time "to_date('06/03/2010 10:26:34','dd/mm/yyyy hh24:mi:ss')"

3> auxiliary destination '/u01/aux_dest';

Iniciando recover em 06/03/2010 10:28:52

usar o arquivo de controle do banco de dados de destino em vez do catálogo de recuperação

canal alocado: ORA_DISK_1

canal ORA_DISK_1: SID=18 tipo de dispositivo=DISK

RMAN-00571: ===========================================================

RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============

RMAN-00571: ===========================================================

RMAN-03002: falha do comando recover em 06/03/2010 10:28:54

RMAN-05010: banco de dados de destino deve ser aberto no modo READ WRITE para Recuperação

           Pontual de Tablespace

Com o banco de dados aberto, irei realizar uma conexão através do RMAN, e iniciar o processo de TSPITR conforme demonstração abaixo:

[oracle@linux1 /]$ rman target /

Gerenciador de Recuperação: Release 11.2.0.1.0 - Production on Sab Mar 6 10:28:27 2010

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

conectado ao banco de dados de destino: BD01 (DBID=2967836454)

RMAN> recover tablespace tbs_01

2> until time "to_date('06/03/2010 10:26:34','dd/mm/yyyy hh24:mi:ss')"

3> auxiliary destination '/u01/aux_dest';

Após a execução do comando acima, o RMAN fará todo o trabalho de recuperação pontual do tablespace TBS_01 sem qualquer intervenção minha. Portanto, abaixo todos os comandos são executados e emitidos pelo RMAN:

Iniciando recover em 06/03/2010 10:28:52

usar o arquivo de controle do banco de dados de destino em vez do catálogo de recuperação

canal alocado: ORA_DISK_1

canal ORA_DISK_1: SID=30 tipo de dispositivo=DISK

RMAN-05026: ADVERTÊNCIA: pressupõe-se que o conjunto de tablespaces a seguir se aplica a

                         um ponto específico no tempo

Espera-se que a lista de tablespaces tenha segmentos UNDO

Tablespace SYSTEM

Tablespace UNDOTBS1

Criando uma instância automática, com SID='alhg'

parâmetros de inicialização usados para instância automática:

db_name=BD01

db_unique_name=alhg_tspitr_BD01

compatible=10.2.0.1.0

db_block_size=8192

db_files=200

sga_target=280M

processes=50

db_create_file_dest=/u01/aux_dest

log_archive_dest_1='location=/u01/aux_dest'

#No auxiliary parameter file used

inicializando instância automática BD01

instância Oracle iniciada

Total da Área Global do Sistema     292933632 bytes

Fixed Size                     1336092 bytes

Variable Size                100666596 bytes

Database Buffers             184549376 bytes

Redo Buffers                   6381568 bytes

Instância automática criada

Executando TRANSPORT_SET_CHECK nos tablespaces do conjunto de recuperação

TRANSPORT_SET_CHECK concluído com sucesso

conteúdo do Script de Memória:

{

# set requested point in time

set until  time "to_date('06/03/2010 10:26:34','dd/mm/yyyy hh24:mi:ss')";

# restore the controlfile

restore clone controlfile;

# mount the controlfile

sql clone 'alter database mount clone database';

# archive current online log

sql 'alter system archive log current';

# avoid unnecessary autobackups for structural changes during TSPITR

sql 'begin dbms_backup_restore.AutoBackupFlag(FALSE); end;';

}

executando Script de Memória

executando comando: SET until clause

Iniciando restore em 06/03/2010 10:29:47

canal alocado: ORA_AUX_DISK_1

canal ORA_AUX_DISK_1: SID=19 tipo de dispositivo=DISK

canal ORA_AUX_DISK_1: iniciando restauração de conjunto de backups de arquivo de dados

canal ORA_AUX_DISK_1: restaurando arquivo de controle

canal ORA_AUX_DISK_1: lendo da parte de backup /u01/app/oracle/flash_recovery_area/BD01/

                      autobackup/2010_03_06/o1_mf_s_710763266_5qbkk4m7_.bkp

canal ORA_AUX_DISK_1: handle de componente=/u01/app/oracle/flash_recovery_area/

                      BD01/autobackup/2010_03_06/o1_mf_s_710763266_5qbkk4m7_.bkp

                      tag=TAG20100306T101426

canal ORA_AUX_DISK_1: restaurada a parte de backup 1

canal ORA_AUX_DISK_1: restauração concluída, tempo decorrido: 00:00:04

nome do arquivo de saída=/u01/aux_dest/BD01/controlfile/o1_mf_5qblg0ld_.ctl

Finalizado restore em 06/03/2010 10:29:55

instrução sql: alter database mount clone database

instrução sql: alter system archive log current

instrução sql: begin dbms_backup_restore.AutoBackupFlag(FALSE); end;

conteúdo do Script de Memória:

{

# set requested point in time

set until  time "to_date('06/03/2010 10:26:34','dd/mm/yyyy hh24:mi:ss')";

plsql <<<-- tspitr_2

declare

  sqlstatement       varchar2(512);

  offline_not_needed exception;

  pragma exception_init(offline_not_needed, -01539);

begin

  sqlstatement := 'alter tablespace '||  'TBS_01' ||' offline immediate';

  krmicd.writeMsg(6162, sqlstatement);

  krmicd.execSql(sqlstatement);

exception

  when offline_not_needed then

    null;

end; >>>;

# set destinations for recovery set and auxiliary set datafiles

set newname for clone datafile  1 to new;

set newname for clone datafile  2 to new;

set newname for clone datafile  3 to new;

set newname for clone tempfile  1 to new;

set newname for datafile  5 to

 "/u01/app/oracle/oradata/BD01/tbs01.dbf";

# switch all tempfiles

switch clone tempfile all;

# restore the tablespaces in the recovery set and the auxiliary set

restore clone datafile  1, 2, 3, 5;

switch clone datafile all;

}

executando Script de Memória

executando comando: SET until clause

instrução sql: alter tablespace TBS_01 offline immediate

executando comando: SET NEWNAME

executando comando: SET NEWNAME

executando comando: SET NEWNAME

executando comando: SET NEWNAME

executando comando: SET NEWNAME

arquivo temporário renomeado 1 para /u01/aux_dest/BD01/datafile/o1_mf_temp_%u_.tmp

Iniciando restore em 06/03/2010 10:30:13

utilizando o canal ORA_AUX_DISK_1

canal ORA_AUX_DISK_1: iniciando restauração de conjunto de backups de arquivo de dados

canal ORA_AUX_DISK_1: especificando arquivo(s) de dados para restauração a partir do

                      conjunto de backups

canal ORA_AUX_DISK_1: restaurando o arquivo de dados 00001 em /u01/aux_dest/BD01/datafile/

                      o1_mf_system_%u_.dbf

canal ORA_AUX_DISK_1: restaurando o arquivo de dados 00002 em /u01/aux_dest/BD01/datafile/

                      o1_mf_undotbs1_%u_.dbf

canal ORA_AUX_DISK_1: restaurando o arquivo de dados 00003 em /u01/aux_dest/BD01/datafile/

                      o1_mf_sysaux_%u_.dbf

canal ORA_AUX_DISK_1: restaurando o arquivo de dados 00005 em /u01/app/oracle/oradata/

                      BD01/tbs01.dbf

canal ORA_AUX_DISK_1: lendo da parte de backup /u01/app/oracle/flash_recovery_area/BD01/

                      backupset/2010_03_06/o1_mf_nnndf_TAG20100306T101155_5qbkdd9g_.bkp

canal ORA_AUX_DISK_1: handle de componente=/u01/app/oracle/flash_recovery_area/BD01/

                      backupset/2010_03_06/o1_mf_nnndf_TAG20100306T101155_5qbkdd9g_.bkp

                      tag=TAG20100306T101155

canal ORA_AUX_DISK_1: restaurada a parte de backup 1

canal ORA_AUX_DISK_1: restauração concluída, tempo decorrido: 00:01:46

Finalizado restore em 06/03/2010 10:32:00

arquivo de dados 1 alternado para a cópia do arquivo de dados

cópia do arquivo de dados de entrada RECID=4 STAMP=710764321 file name=/u01/aux_dest/BD01/

                                                       datafile/o1_mf_system_5qblgq4w_.dbf

arquivo de dados 2 alternado para a cópia do arquivo de dados

cópia do arquivo de dados de entrada RECID=5 STAMP=710764321 file name=/u01/aux_dest/BD01/

                                                     datafile/o1_mf_undotbs1_5qblgq6p_.dbf

arquivo de dados 3 alternado para a cópia do arquivo de dados

cópia do arquivo de dados de entrada RECID=6 STAMP=710764321 file name=/u01/aux_dest/BD01/

                                                       datafile/o1_mf_sysaux_5qblgq6d_.dbf

conteúdo do Script de Memória:

{

# set requested point in time

set until  time "to_date('06/03/2010 10:26:34','dd/mm/yyyy hh24:mi:ss')";

# online the datafiles restored or switched

sql clone "alter database datafile  1 online";

sql clone "alter database datafile  2 online";

sql clone "alter database datafile  3 online";

sql clone "alter database datafile  5 online";

# recover and open resetlogs

recover clone database tablespace "TBS_01","SYSTEM","UNDOTBS1","SYSAUX" delete archivelog;

alter clone database open resetlogs;

}

executando Script de Memória

executando comando: SET until clause

instrução sql: alter database datafile  1 online

instrução sql: alter database datafile  2 online

instrução sql: alter database datafile  3 online

instrução sql: alter database datafile  5 online

Iniciando recover em 06/03/2010 10:32:02

utilizando o canal ORA_AUX_DISK_1

iniciar recuperação de mídia

o log arquivado para thread 1 com sequência 63 já está no disco como arquivo /u01/app/

oracle/flash_recovery_area/BD01/archivelog/2010_03_06/o1_mf_1_63_5qblg9mk_.arc

nome do arquivo de log arquivado=/u01/app/oracle/flash_recovery_area/BD01/archivelog/

2010_03_06/o1_mf_1_63_5qblg9mk_.arc thread=1 sequência=63

recuperação da mídia concluída, tempo decorrido: 00:00:04

Finalizado recover em 06/03/2010 10:32:10

banco de dados aberto

conteúdo do Script de Memória:

{

# make read only the tablespace that will be exported

sql clone 'alter tablespace  TBS_01 read only';

# create directory for datapump import

sql "create or replace directory TSPITR_DIROBJ_DPDIR as ''

/u01/aux_dest''";

# create directory for datapump export

sql clone "create or replace directory TSPITR_DIROBJ_DPDIR as ''

/u01/aux_dest''";

}

executando Script de Memória

instrução sql: alter tablespace  TBS_01 read only

instrução sql: create or replace directory TSPITR_DIROBJ_DPDIR as ''/u01/aux_dest''

instrução sql: create or replace directory TSPITR_DIROBJ_DPDIR as ''/u01/aux_dest''

Exportando metadados...

   EXPDP> Iniciando "SYS"."TSPITR_EXP_liyq":

   EXPDP> Processando o tipo de objeto TRANSPORTABLE_EXPORT/PLUGTS_BLK

   EXPDP> Processando o tipo de objeto TRANSPORTABLE_EXPORT/TABLE

   EXPDP> Processando o tipo de objeto TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK

   EXPDP> Tabela-mestre "SYS"."TSPITR_EXP_liyq" carregada/descarregada com sucesso

   EXPDP> ******************************************************************************

   EXPDP> Conjunto de arquivos de dump para SYS.TSPITR_EXP_liyq é:

   EXPDP>   /u01/aux_dest/tspitr_liyq_47871.dmp

   EXPDP> ******************************************************************************

   EXPDP> Os arquivos de dados necessários para o tablespace transportável TBS_01:

   EXPDP>   /u01/app/oracle/oradata/BD01/tbs01.dbf

   EXPDP> O job "SYS"."TSPITR_EXP_liyq" foi concluído com sucesso em 10:34:53

Exportação concluída

conteúdo do Script de Memória:

{

# shutdown clone before import

shutdown clone immediate

# drop target tablespaces before importing them back

sql 'drop tablespace  TBS_01 including contents keep datafiles';

}

executando Script de Memória

banco de dados fechado

banco de dados desmontado

encerramento de instância Oracle

instrução sql: drop tablespace  TBS_01 including contents keep datafiles

Importando metadados...

   IMPDP> Tabela-mestre "SYS"."TSPITR_IMP_liyq" carregada/descarregada com sucesso

   IMPDP> Iniciando "SYS"."TSPITR_IMP_liyq":

   IMPDP> Processando o tipo de objeto TRANSPORTABLE_EXPORT/PLUGTS_BLK

   IMPDP> Processando o tipo de objeto TRANSPORTABLE_EXPORT/TABLE

   IMPDP> Processando o tipo de objeto TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK

   IMPDP> O job "SYS"."TSPITR_IMP_liyq" foi concluído com sucesso em 10:36:35

Importação concluída

conteúdo do Script de Memória:

{

# make read write and offline the imported tablespaces

sql 'alter tablespace  TBS_01 read write';

sql 'alter tablespace  TBS_01 offline';

# enable autobackups after TSPITR is finished

sql 'begin dbms_backup_restore.AutoBackupFlag(TRUE); end;';

}

executando Script de Memória

instrução sql: alter tablespace  TBS_01 read write

instrução sql: alter tablespace  TBS_01 offline

instrução sql: begin dbms_backup_restore.AutoBackupFlag(TRUE); end;

Removendo instância automática

Instância automática removida

arquivo auxiliar /u01/aux_dest/BD01/datafile/o1_mf_temp_5qblm062_.tmp deletado

arquivo auxiliar /u01/aux_dest/BD01/onlinelog/o1_mf_3_5qbllp52_.log deletado

arquivo auxiliar /u01/aux_dest/BD01/onlinelog/o1_mf_2_5qbllko0_.log deletado

arquivo auxiliar /u01/aux_dest/BD01/onlinelog/o1_mf_1_5qbllc1f_.log deletado

arquivo auxiliar /u01/aux_dest/BD01/datafile/o1_mf_sysaux_5qblgq6d_.dbf deletado

arquivo auxiliar /u01/aux_dest/BD01/datafile/o1_mf_undotbs1_5qblgq6p_.dbf deletado

arquivo auxiliar /u01/aux_dest/BD01/datafile/o1_mf_system_5qblgq4w_.dbf deletado

arquivo auxiliar /u01/aux_dest/BD01/controlfile/o1_mf_5qblg0ld_.ctl deletado

Finalizado recover em 06/03/2010 10:36:47


RMAN> exit

Recovery Manager completo.

Pronto. O processo de recuperação foi finalizado. Vejamos os resultados … Bom, após a tentativa mal sucedida de selecionar o dados da tabela TABELA_01, percebi que tanto o arquivo de dados associado ao tablespapce TBS_01 como o próprio tablespace TBS_01 estavam OFFLINE.

[oracle@linux1 /]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Sab Mar 6 10:42:46 2010

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

Conectado a:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

SQL> select file#,name,status from v$datafile;

    FILE# NAME                                                       STATUS
---------- ---------------------------------------------------------- -------
        1 /u01/app/oracle/oradata/BD01/system01.dbf                  SYSTEM
        2 /u01/app/oracle/oradata/BD01/undotbs01.dbf                 ONLINE
        3 /u01/app/oracle/oradata/BD01/sysaux01.dbf                  ONLINE
        4 /u01/app/oracle/oradata/BD01/users01.dbf                   ONLINE
        5 /u01/app/oracle/oradata/BD01/tbs01.dbf                     OFFLINE
        6 /u01/app/oracle/oradata/BD01/tbs02.dbf                     ONLINE

6 linhas selecionadas.

SQL> select tablespace_name,status from dba_tablespaces where tablespace_name='TBS_01';

TABLESPACE_NAME                STATUS
------------------------------ ---------
TBS_01                         OFFLINE

Agora irei alterar o status do arquivo de dados e do tablespace TBS_01 para ONLINE conforme a execução dos comandos abaixo:

SQL> alter database datafile 5 online;

Banco de dados alterado.

SQL> alter tablespace tbs_01 online;

 Tablespace alterado.


Vejamos novamente o resultado da operação ...


SQL> connect usuario_01/senha

Conectado.

SQL> select * from tabela_01;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 linhas selecionadas.

Pronto. A tabela TABELA_01 foi restaurada com sucesso. Os usuários do sistema de Recursos Humanos estão satisfeitos. Irei agora realizar uma consulta na tabela do sistema de Vendas:

SQL> connect usuario_02/senha

Conectado.

SQL> select * from tabela_02;

        ID
----------
       100
       200
       300
       400
       500
       600
       700
       800
       900
      1000

10 linhas selecionadas.

Perfeito. Os dados da tabela TABELA_02 estão como deveriam estar, ou seja, os mesmos não foram tocados durante o processo de TSPITR. Em resumo, para este cenário com certeza a melhor solução seria a execução da técnica TSPITR, embora, um backup lógico (se disponível) para restaurar a tabela TABELA_01 não seria nada ruim. Por isso, acho extremamente interessante que uma estratégia de backup inclua tanto backups físicos quanto backups lógicos.

Abaixo está uma figura que demonstra alguns dos passos realizados pelo RMAN ao realizar uma recuperação pontual de tablespace.

Point-In-Time Recovery

Como mencionado no início do artigo, em muitos casos uma falha lógica causada por erro humano pode facilmente ser resolvida através da técnica DBPITR. Antes do Oracle 10g, o único jeito de realizar tal operação era fazendo uma recuperação incompleta de media. (Media Incomplete Recovery) em que, dependendo do caso, poderia consumir muito tempo. Por outro lado, fazendo uso do Flashback Database à partir do Oracle 10g, uma operação de DBPITR pode ser executada de forma bastante rápida: 25 a 105 vezes mais rápida do que uma operação de recuperação incompleta, segundo o artigo publicado por Ron Weiss. Como resultado, o tempo de inatividade do banco de dados durante o processo de recuperação, será significativamente menor como mostra a figura abaixo:

http://4.bp.blogspot.com/_0YJ39t-zN8U/S5KkaeFaocI/AAAAAAAAAjk/T523CZRFssM/s1600/fbd_vs_traditional.gif

Para finalizar, não custa nada dizer como é bom saber que a Oracle forneceu uma solução rápida de recovery onde tablespaces individuais possam ser recuperados para um tempo específico no passado, enquanto o restante do banco de dados ainda continua acessível aos usuários!

Eduardo Legatti

Eduardo Legatti

Eduardo Legatti é Analista de Sistemas e Administrador de banco de dados. É pós graduado em Gerência da Tecnologia da Informação, possui as certificações OCA 9i - OCP 9i/10g/11g – OCE SQL Expert, e vem trabalhando como DBA Oracle desde a versão 8.0.5. Se interessa particularmente em planejar estratégias de backup/recovery, performance tuning e projetos de bancos de dados (modelagem física e lógica) atuando como consultor. Como Oracle ACE, ele tem o hábito de disseminar seu conhecimento através de artigos, grupos de discussão (Oracle OTN Forums) e dedica-se a compartilhar informações de forma a motivar novos DBAs.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress