Recover de tabela a partir de backup RMAN em Oracle 12C

Cheap Tramadol Online Cod 12 MHG quadra thiago morgado2 Recover de tabela a partir de backup RMAN em Oracle 12CUma das features mais aguardadas da versão 12C do Oracle era justamente a possibilidade de fazer um recover de tabela a partir do backup de RMAN. Neste artigo, vamos demonstrar o funcionamento do processo, bem como todas as implicações e requisitos necessários para o sucesso do procedimento.
Até agora, sempre que fosse necessário realizar um recover de uma ou mais tabelas, mas não de toda a base, seria necessário utilizar o backup lógico (exp ou datapump) para essa atividade. Esse procedimento possui a limitação de somente ser possível restaurar a tabela no ponto em que foi realizado o backup da mesma. Se o backup foi realizado durante a madrugada, mas um registro foi indevidamente alterado às 10h00 por exemplo, um recover dessa tabela só traria os registros, obviamente, até a madrugada, excluindo tudo que foi feito durante o período até às 10h00.
Outra possibilidade era restaurar o backup físico, mas isso implica em voltar toda a base, incluindo todos os schemas existentes, e não somente a tabela que se deseja restaurar.
Uma terceira possibilidade era o de duplicar o banco a partir do backup físico, realizar um export lógico da tabela, e restaurá-la na base de produção, ou importar numa base de testes para comparação.
O que a nova feature de recover de tabelas via RMAN, no Oracle 12C faz, é automatizar essa última opção em um processo único e totalmente gerenciado pelo RMAN. O processo é exatamente esse; 1)Faz um duplicate a partir do backup físico; 2) Exporta a tabela ou conjunto de tabelas via datapump; 3) Importa a(s) tabela(s) na base, podendo realizar um remap_table; 4) Exclui a instância clonada, datafiles, controlfiles, arquivos de parâmetro e o dump gerado no processo.
Confesso que quando entendi como o processo funcionava, fiquei um pouco decepcionado. Esperava que, ao realizar um processo de restore da tabela, a “mágica” ocorresse diretamente nos blocos do backup, e não um conjunto de ações que, em seu núcleo de execução, não altera em nada a arquitetura do RMAN como a conhecemos hoje. No entanto, ao executar o processo em meus testes, verifiquei que o processo é bem interessante, e realmente agiliza e facilita muito o trabalho, tirando várias preocupações que o DBA teria ao realizar manualmente todas as etapas mencionadas.
Mas deixemos de conversa de “grupinho de DBA na hora do café”, e vamos demonstrar como a coisa toda funciona.

go Em uma instância Oracle 12C Enterprise, tenho uma tablespace chamada TESTE_DATA, que foi criada com 4 datafiles. Tenho um owner chamado TESTE, que possui privilégio de armazenamento ilimitado nesta tablespace. Criei uma tabela para esse owner chamada TABELA_TESTE, fazendo um “CREATE TABLE ….. AS SELECT *” da view DBA_OBJECTS, do SYS. Queria que a tabela tivesse um volume de dados suficiente para que as extensões da tabela ocupassem mais do que 1 datafile, mas não todos. O motivo desta particularidade, compartilharei mais para frente. Como podemos ver a seguir, a tabela se extendeu por 3 dos 4 datafiles da tablespace TESTE_DATA. Mais especificamente nos datafiles de ID 5,7 e 8:

Tramadol 50Mg Buy Online SQL> SELECT distinct(FILE_ID), SEGMENT_NAME, TABLESPACE_NAME from dba_extents where owner='TESTE'; FILE_ID SEGMENT_NAME TABLESPACE_NAME ---------- -------------------- ------------------------------ 5 TABELA_TESTE TESTE_DATA 7 TABELA_TESTE TESTE_DATA 8 TABELA_TESTE TESTE_DATA

https://ict-pulse.com/2024/07/8gltp4fu9uy Para fins de demonstração e análise do processo, criei uma nova tablespace, que chamei de CONTROLE_DATA, com 1 datafile:

source url SQL> create tablespace CONTROLE_DATA datafile '+DGDATA' size 100m; Tablespace created.

https://www.techonicsltd.com/uncategorized/qzbyyfm9lq O próximo passo é fazer um backup do banco via RMAN, pois no meu caso, por se tratar de uma instância que utilizo para testes, não possuo nenhuma rotina de backup físico, e portanto, nenhum conjunto de backups.

follow site RMAN> backup database; Starting backup at 20-FEB-14 using channel ORA_DISK_1 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set input datafile file number=00001 name=+DGDATA/DBPROD/DATAFILE/system.271.839926541 input datafile file number=00003 name=+DGDATA/DBPROD/DATAFILE/sysaux.270.839926235 input datafile file number=00009 name=+DGDATA/DBPROD/DATAFILE/controle_data.293.840013943 input datafile file number=00004 name=+DGDATA/DBPROD/DATAFILE/undotbs1.273.839926845 input datafile file number=00002 name=+DGDATA/DBPROD/DATAFILE/teste.287.839954981 input datafile file number=00005 name=+DGDATA/DBPROD/DATAFILE/teste_data.288.840013323 input datafile file number=00007 name=+DGDATA/DBPROD/DATAFILE/teste_data.291.840013325 input datafile file number=00008 name=+DGDATA/DBPROD/DATAFILE/teste_data.292.840013327 input datafile file number=00010 name=+DGDATA/DBPROD/DATAFILE/teste_data.285.840020271 input datafile file number=00006 name=+DGDATA/DBPROD/DATAFILE/users.272.839926837 channel ORA_DISK_1: starting piece 1 at 20-FEB-14 channel ORA_DISK_1: finished piece 1 at 20-FEB-14 piece handle=+DGDATA/DBPROD/BACKUPSET/2014_02_20/nnndf0_tag20140220t105806_0.284.840020291 tag=TAG20140220T105806 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:01:25 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set including current control file in backup set including current SPFILE in backup set channel ORA_DISK_1: starting piece 1 at 20-FEB-14 channel ORA_DISK_1: finished piece 1 at 20-FEB-14 piece handle=+DGDATA/DBPROD/BACKUPSET/2014_02_20/ncsnf0_tag20140220t105806_0.296.840020379 tag=TAG20140220T105806 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:07 Finished backup at 20-FEB-14

Buying Tramadol From Mexico De volta à instância, habilitei o time para melhor entendimento do processo. Fiz um “select count” na tabela, seguido da exclusão de mais da metade dos registros da mesma, simulando um erro, acidental ou não, que demande um recover desta tabela para um momento antes da exclusão dos registros:

go 11:00:08 SQL> select count(1) from TESTE.TABELA_TESTE; COUNT(1) ---------- 90829 11:00:43 SQL> DELETE from TESTE.TABELA_TESTE where OWNER='SYS'; 41785 rows deleted. 11:00:52 SQL> commit; Commit complete. 11:00:56 SQL> select count(1) from TESTE.TABELA_TESTE; COUNT(1) ---------- 49044

enter Conectado ao RMAN, emito o comando RECOVER TABLE, informando no parâmetro UNTIL TIME o momento exato em que desejo que a tabela seja recuperada. Informo na string a área que o RMAN utilizará para criação da instância temporária, e também a área de geração do arquivo de exportação do datapump:

see url [oracle@orazety12c ~]$ rman target / Recovery Manager: Release 12.1.0.1.0 - Production on Thu Feb 20 11:02:13 2014 Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved. connected to target database: DBPROD (DBID=939006448) RMAN> RECOVER TABLE TESTE.tabela_teste UNTIL TIME "to_date('2014-02-20:11:00:00', 'yyyy-mm-dd:hh24:mi:ss')" AUXILIARY DESTINATION '/orateste/oradata' DATAPUMP DESTINATION '/orateste/oradata' DUMP FILE 'TABELAS_RECOVER.dat'; Starting recover at 20-FEB-14 using target database control file instead of recovery catalog current log archived RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =========================================================== RMAN-03002: failure of recover command at 02/20/2014 11:02:25 RMAN-05063: Cannot recover specified tables RMAN-05112: table "TESTE"."TABELA_TESTE" already exists RMAN>

https://gsaudemarketing.com.br/gsxdmapl Opa, erro de tabela existente. Sim, o RMAN não exclui a tabela para substituí-la pelo recover. Se o DBA deseja recuperar a tabela diretamente na produção, deve excluí-la antes do processo:

https://thefooduntold.com/food-science/y7glcw7oz99 SQL> DROP table TESTE.TABELA_TESTE; Table dropped.

https://living4youboutique.com/thqsnhfk2s Agora sim, podemos executar o procedimento no RMAN com sucesso:

RMAN> RECOVER TABLE TESTE.tabela_teste UNTIL TIME "to_date('2014-02-20:11:00:00', 'yyyy-mm-dd:hh24:mi:ss')" AUXILIARY DESTINATION '/orateste/oradata' DATAPUMP DESTINATION '/orateste/oradata' DUMP FILE 'TABELAS_RECOVER.dat'; Starting recover at 20-FEB-14 using target database control file instead of recovery catalog allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=66 device type=DISK RMAN-05026: WARNING: presuming following set of tablespaces applies to specified Point-in-Time List of tablespaces expected to have UNDO segments Tablespace SYSTEM Tablespace UNDOTBS1 Creating automatic instance, with SID='yvDv' initialization parameters used for automatic instance: db_name=DBPROD db_unique_name=yvDv_pitr_DBPROD compatible=12.1.0.0.0 db_block_size=8192 db_files=200 sga_target=1G processes=80 diagnostic_dest=/u01/app/oracle db_create_file_dest=/orateste/oradata log_archive_dest_1='location=/orateste/oradata' #No auxiliary parameter file used starting up automatic instance DBPROD Oracle instance started Total System Global Area 1068937216 bytes Fixed Size 2296576 bytes Variable Size 281019648 bytes Database Buffers 780140544 bytes Redo Buffers 5480448 bytes Automatic instance created contents of Memory Script: { # set requested point in time set until time "to_date('2014-02-20:11:00:00', 'yyyy-mm-dd: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'; } executing Memory Script executing command: SET until clause Starting restore at 20-FEB-14 allocated channel: ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: SID=7 device type=DISK channel ORA_AUX_DISK_1: starting datafile backup set restore channel ORA_AUX_DISK_1: restoring control file channel ORA_AUX_DISK_1: reading from backup piece +DGDATA/DBPROD/BACKUPSET/2014_02_20/ncsnf0_tag20140220t105806_0.296.840020379 channel ORA_AUX_DISK_1: piece handle=+DGDATA/DBPROD/BACKUPSET/2014_02_20/ncsnf0_tag20140220t105806_0.296.840020379 tag=TAG20140220T105806 channel ORA_AUX_DISK_1: restored backup piece 1 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:08 output file name=/orateste/oradata/DBPROD/controlfile/o1_mf_9jd390ph_.ctl Finished restore at 20-FEB-14 sql statement: alter database mount clone database sql statement: alter system archive log current contents of Memory Script: { # set requested point in time set until time "to_date('2014-02-20:11:00:00', 'yyyy-mm-dd:hh24:mi:ss')"; # set destinations for recovery set and auxiliary set datafiles set newname for clone datafile 1 to new; set newname for clone datafile 4 to new; set newname for clone datafile 3 to new; set newname for clone tempfile 1 to new; # switch all tempfiles switch clone tempfile all; # restore the tablespaces in the recovery set and the auxiliary set restore clone datafile 1, 4, 3; switch clone datafile all; } executing Memory Script executing command: SET until clause executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME renamed tempfile 1 to /orateste/oradata/DBPROD/datafile/o1_mf_temp_%u_.tmp in control file Starting restore at 20-FEB-14 using channel ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: starting datafile backup set restore channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set channel ORA_AUX_DISK_1: restoring datafile 00003 to /orateste/oradata/DBPROD/datafile/o1_mf_sysaux_%u_.dbf channel ORA_AUX_DISK_1: reading from backup piece +DGDATA/DBPROD/BACKUPSET/2014_02_20/nnndf0_tag20140220t091315_0.294.840014001 channel ORA_AUX_DISK_1: piece handle=+DGDATA/DBPROD/BACKUPSET/2014_02_20/nnndf0_tag20140220t091315_0.294.840014001 tag=TAG20140220T091315 channel ORA_AUX_DISK_1: restored backup piece 1 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:46 channel ORA_AUX_DISK_1: starting datafile backup set restore channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set channel ORA_AUX_DISK_1: restoring datafile 00001 to /orateste/oradata/DBPROD/datafile/o1_mf_system_%u_.dbf channel ORA_AUX_DISK_1: restoring datafile 00004 to /orateste/oradata/DBPROD/datafile/o1_mf_undotbs1_%u_.dbf channel ORA_AUX_DISK_1: reading from backup piece +DGDATA/DBPROD/BACKUPSET/2014_02_20/nnndf0_tag20140220t105806_0.284.840020291 channel ORA_AUX_DISK_1: piece handle=+DGDATA/DBPROD/BACKUPSET/2014_02_20/nnndf0_tag20140220t105806_0.284.840020291 tag=TAG20140220T105806 channel ORA_AUX_DISK_1: restored backup piece 1 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:46 Finished restore at 20-FEB-14 datafile 1 switched to datafile copy input datafile copy RECID=4 STAMP=840021208 file name=/orateste/oradata/DBPROD/datafile/o1_mf_system_9jd3bvjj_.dbf datafile 4 switched to datafile copy input datafile copy RECID=5 STAMP=840021208 file name=/orateste/oradata/DBPROD/datafile/o1_mf_undotbs1_9jd3bvjo_.dbf datafile 3 switched to datafile copy input datafile copy RECID=6 STAMP=840021208 file name=/orateste/oradata/DBPROD/datafile/o1_mf_sysaux_9jd39f2q_.dbf contents of Memory Script: { # set requested point in time set until time "to_date('2014-02-20:11:00:00', 'yyyy-mm-dd:hh24:mi:ss')"; # online the datafiles restored or switched sql clone "alter database datafile 1 online"; sql clone "alter database datafile 4 online"; sql clone "alter database datafile 3 online"; # recover and open database read only recover clone database tablespace "SYSTEM", "UNDOTBS1", "SYSAUX"; sql clone 'alter database open read only'; } executing Memory Script executing command: SET until clause sql statement: alter database datafile 1 online sql statement: alter database datafile 4 online sql statement: alter database datafile 3 online Starting recover at 20-FEB-14 using channel ORA_AUX_DISK_1 starting media recovery archived log for thread 1 with sequence 12 is already on disk as file /orateste/oradata/arch_1_12_839926904.arc archived log for thread 1 with sequence 13 is already on disk as file /orateste/oradata/arch_1_13_839926904.arc archived log for thread 1 with sequence 14 is already on disk as file /orateste/oradata/arch_1_14_839926904.arc archived log file name=/orateste/oradata/arch_1_12_839926904.arc thread=1 sequence=12 archived log file name=/orateste/oradata/arch_1_13_839926904.arc thread=1 sequence=13 archived log file name=/orateste/oradata/arch_1_14_839926904.arc thread=1 sequence=14 media recovery complete, elapsed time: 00:00:04 Finished recover at 20-FEB-14 sql statement: alter database open read only contents of Memory Script: { sql clone "create spfile from memory"; shutdown clone immediate; startup clone nomount; sql clone "alter system set control_files = ''/orateste/oradata/DBPROD/controlfile/o1_mf_9jd390ph_.ctl'' comment= ''RMAN set'' scope=spfile"; shutdown clone immediate; startup clone nomount; # mount database sql clone 'alter database mount clone database'; } executing Memory Script sql statement: create spfile from memory database closed database dismounted Oracle instance shut down connected to auxiliary database (not started) Oracle instance started Total System Global Area 1068937216 bytes Fixed Size 2296576 bytes Variable Size 285213952 bytes Database Buffers 775946240 bytes Redo Buffers 5480448 bytes sql statement: alter system set control_files = ''/orateste/oradata/DBPROD/controlfile/o1_mf_9jd390ph_.ctl'' comment= ''RMAN set'' scope=spfile Oracle instance shut down connected to auxiliary database (not started) Oracle instance started Total System Global Area 1068937216 bytes Fixed Size 2296576 bytes Variable Size 285213952 bytes Database Buffers 775946240 bytes Redo Buffers 5480448 bytes sql statement: alter database mount clone database contents of Memory Script: { # set requested point in time set until time "to_date('2014-02-20:11:00:00', 'yyyy-mm-dd:hh24:mi:ss')"; # set destinations for recovery set and auxiliary set datafiles set newname for datafile 5 to new; set newname for datafile 7 to new; set newname for datafile 8 to new; set newname for datafile 10 to new; # restore the tablespaces in the recovery set and the auxiliary set restore clone datafile 5, 7, 8, 10; switch clone datafile all; } executing Memory Script executing command: SET until clause executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME Starting restore at 20-FEB-14 allocated channel: ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: SID=27 device type=DISK channel ORA_AUX_DISK_1: starting datafile backup set restore channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set channel ORA_AUX_DISK_1: restoring datafile 00005 to /orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_%u_.dbf channel ORA_AUX_DISK_1: restoring datafile 00007 to /orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_%u_.dbf channel ORA_AUX_DISK_1: restoring datafile 00008 to /orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_%u_.dbf channel ORA_AUX_DISK_1: restoring datafile 00010 to /orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_%u_.dbf channel ORA_AUX_DISK_1: reading from backup piece +DGDATA/DBPROD/BACKUPSET/2014_02_20/nnndf0_tag20140220t105806_0.284.840020291 channel ORA_AUX_DISK_1: piece handle=+DGDATA/DBPROD/BACKUPSET/2014_02_20/nnndf0_tag20140220t105806_0.284.840020291 tag=TAG20140220T105806 channel ORA_AUX_DISK_1: restored backup piece 1 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:03 Finished restore at 20-FEB-14 datafile 5 switched to datafile copy input datafile copy RECID=11 STAMP=840021295 file name=/orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_9jd3gw5x_.dbf datafile 7 switched to datafile copy input datafile copy RECID=12 STAMP=840021295 file name=/orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_9jd3gw67_.dbf datafile 8 switched to datafile copy input datafile copy RECID=13 STAMP=840021295 file name=/orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_9jd3gw6l_.dbf datafile 10 switched to datafile copy input datafile copy RECID=14 STAMP=840021295 file name=/orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_9jd3gw8y_.dbf contents of Memory Script: { # set requested point in time set until time "to_date('2014-02-20:11:00:00', 'yyyy-mm-dd:hh24:mi:ss')"; # online the datafiles restored or switched sql clone "alter database datafile 5 online"; sql clone "alter database datafile 7 online"; sql clone "alter database datafile 8 online"; sql clone "alter database datafile 10 online"; # recover and open resetlogs recover clone database tablespace "TESTE_DATA", "SYSTEM", "UNDOTBS1", "SYSAUX" delete archivelog; alter clone database open resetlogs; } executing Memory Script executing command: SET until clause sql statement: alter database datafile 5 online sql statement: alter database datafile 7 online sql statement: alter database datafile 8 online sql statement: alter database datafile 10 online Starting recover at 20-FEB-14 using channel ORA_AUX_DISK_1 starting media recovery archived log for thread 1 with sequence 14 is already on disk as file /orateste/oradata/arch_1_14_839926904.arc archived log file name=/orateste/oradata/arch_1_14_839926904.arc thread=1 sequence=14 media recovery complete, elapsed time: 00:00:01 Finished recover at 20-FEB-14 database opened contents of Memory Script: { # create directory for datapump import sql "create or replace directory TSPITR_DIROBJ_DPDIR as '' /orateste/oradata''"; # create directory for datapump export sql clone "create or replace directory TSPITR_DIROBJ_DPDIR as '' /orateste/oradata''"; } executing Memory Script sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''/orateste/oradata'' sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''/orateste/oradata'' Performing export of tables... EXPDP> Starting "SYS"."TSPITR_EXP_yvDv_wCFg": EXPDP> Estimate in progress using BLOCKS method... EXPDP> Processing object type TABLE_EXPORT/TABLE/TABLE_DATA EXPDP> Total estimation using BLOCKS method: 13 MB EXPDP> Processing object type TABLE_EXPORT/TABLE/TABLE EXPDP> Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS EXPDP> Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER EXPDP> . . exported "TESTE"."TABELA_TESTE" 10.36 MB 90829 rows EXPDP> Master table "SYS"."TSPITR_EXP_yvDv_wCFg" successfully loaded/unloaded EXPDP> ****************************************************************************** EXPDP> Dump file set for SYS.TSPITR_EXP_yvDv_wCFg is: EXPDP> /orateste/oradata/TABELAS_RECOVER.dat EXPDP> Job "SYS"."TSPITR_EXP_yvDv_wCFg" successfully completed at Thu Feb 20 11:18:19 2014 elapsed 0 00:02:01 Export completed contents of Memory Script: { # shutdown clone before import shutdown clone abort } executing Memory Script Oracle instance shut down Performing import of tables... IMPDP> Master table "SYS"."TSPITR_IMP_yvDv_jrcp" successfully loaded/unloaded IMPDP> Starting "SYS"."TSPITR_IMP_yvDv_jrcp": IMPDP> Processing object type TABLE_EXPORT/TABLE/TABLE IMPDP> Processing object type TABLE_EXPORT/TABLE/TABLE_DATA IMPDP> . . imported "TESTE"."TABELA_TESTE" 10.36 MB 90829 rows IMPDP> Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS IMPDP> Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER IMPDP> Job "SYS"."TSPITR_IMP_yvDv_jrcp" successfully completed at Thu Feb 20 11:20:33 2014 elapsed 0 00:01:47 Import completed Removing automatic instance Automatic instance removed auxiliary instance file /orateste/oradata/DBPROD/datafile/o1_mf_temp_9jd3dqym_.tmp deleted auxiliary instance file /orateste/oradata/YVDV_PITR_DBPROD/onlinelog/o1_mf_3_9jd3hdz0_.log deleted auxiliary instance file /orateste/oradata/YVDV_PITR_DBPROD/onlinelog/o1_mf_2_9jd3hb34_.log deleted auxiliary instance file /orateste/oradata/YVDV_PITR_DBPROD/onlinelog/o1_mf_1_9jd3h6l9_.log deleted auxiliary instance file /orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_9jd3gw8y_.dbf deleted auxiliary instance file /orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_9jd3gw6l_.dbf deleted auxiliary instance file /orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_9jd3gw67_.dbf deleted auxiliary instance file /orateste/oradata/YVDV_PITR_DBPROD/datafile/o1_mf_teste_da_9jd3gw5x_.dbf deleted auxiliary instance file /orateste/oradata/DBPROD/datafile/o1_mf_sysaux_9jd39f2q_.dbf deleted auxiliary instance file /orateste/oradata/DBPROD/datafile/o1_mf_undotbs1_9jd3bvjo_.dbf deleted auxiliary instance file /orateste/oradata/DBPROD/datafile/o1_mf_system_9jd3bvjj_.dbf deleted auxiliary instance file /orateste/oradata/DBPROD/controlfile/o1_mf_9jd390ph_.ctl deleted auxiliary instance file TABELAS_RECOVER.dat deleted Finished recover at 20-FEB-14

Veja na leitura deste extenso log, todas as etapas que mencionei no inicio deste artigo, totalmente evidenciadas. Perceba que o RMAN cria uma instância DUMMY utilizando apenas os datafiles da SYSTEM, SYSAUX, UNDO e os datafiles da tablespace TESTE_DATA, além de criar uma tablespace temporária. Aqui eu chamo atenção para o fato dos 4 datafiles da tablespace TESTE_DATA, que foram recuperados na base, mesmo a tabela só ocupando 3 deles. Outro detalhe é a tablespace CONTROLE_DATA e USERS. Nenhum datafile dessas tablespaces foi recuperado, poupando espaço utilizado no processo. Destas 2 constatações, tiramos 2 lições importantes na utilização deste recurso; A primeira é o fato de que, como o duplicate é realizado apenas da tablespace envolvida mais as de sistema, o espaço demandado é otimizado, evitando que,por exemplo, em uma instância com 10 tablespaces de 1TB no total, precisemos alocar 1TB de espaço apenas para recuperar 1 tabela. A segunda questão é que, apesar de só duplicar as tablespaces de sistema mais a tablespace da tabela, o processo recupera toda a tablespace. Isso quer dizer que, se a tabela possui 5mb, mas a tablespace possui 100GB, teremos que disponibilizar esse tamanho, mais o espaço utilizado para as tablespaces de sistema, a tablespace temporária e área para os archivelogs utilizados. Essa questão é muito importante, e deve ser levada em conta no processo de recover da tabela.
Ao final do processo, no qual o RMAN duplicou a base, acionou o DATAPUMP para exportar a tabela e depois para importar na instância, os arquivos utilizados são excluídos.
Antes do processo ser executado, monitorei os processos de pmon no servidor, e a área do disco /orateste, que utilizei para ser realizada a duplicação e exportação:

oracle    1318  1315  0 11:23 pts/0    00:00:00 grep ora_pm
oracle    3390     1  0 08:44 ?        00:00:04 ora_pmon_dbprod
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                       25G   17G  7.5G  69% /
/dev/sda1              99M   24M   71M  25% /boot
tmpfs                 1.3G  626M  619M  51% /dev/shm
/dev/sdb1              22G  265M   21G   2% /orateste

Durante o processo, o cenário era o seguinte:

oracle     376   372  0 11:15 pts/0    00:00:00 grep ora_pm
oracle    3390     1  0 08:44 ?        00:00:04 ora_pmon_dbprod
oracle   32307     1  0 11:14 ?        00:00:00 ora_pmon_yvDv
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                       25G   17G  7.5G  69% /
/dev/sda1              99M   24M   71M  25% /boot
tmpfs                 1.3G  626M  619M  51% /dev/shm
/dev/sdb1              22G  2.0G   19G  10% /orateste

Veja a instância yvDv criada com o duplicate, e 2gb utilizados no processo.
De volta à instância DBPROD, verificamos se a tabela foi recuperada para a quantidade de registros existentes antes doa exclusão acidental:

11:24:23 SQL> SELECT count(1) from TESTE.TABELA_TESTE;

  COUNT(1)
----------
     90829

Um detalhe importante que o DBA deve ficar atento; Após o processo, a instância dummy é eliminada, os datafiles, controlfile e dump são excluídos, mas a estrutura de pastas e archives utilizados no duplicate não! Veja abaixo que, todos os testes anteriores, mais este que realizei para este artigo, geraram estruturas nesta área que não foram eliminadas pelo processo. Perceba também que cada estrutura recebe um nome atribuído pelo RMAN á instância criada, e este sempre é diferente:

[oracle@orazety12c oradata]$ pwd
/orateste/oradata
[oracle@orazety12c oradata]$ ls -ltr
total 94980
-rw-r----- 1 oracle asmadmin  5948416 Feb 19 16:09 arch_1_6_839926904.arc
-rw-r----- 1 oracle asmadmin   877056 Feb 19 16:34 arch_1_7_839926904.arc
-rw-r----- 1 oracle asmadmin    17920 Feb 19 16:36 arch_1_8_839926904.arc
drwxr-x--- 5 oracle asmadmin     4096 Feb 19 16:36 DBPROD
drwxr-x--- 4 oracle asmadmin     4096 Feb 19 16:39 GAMH_PITR_DBPROD
-rw-r----- 1 oracle asmadmin  5312000 Feb 19 16:53 arch_1_9_839926904.arc
-rw-r----- 1 oracle asmadmin   442368 Feb 19 16:54 arch_1_10_839926904.arc
drwxr-x--- 4 oracle asmadmin     4096 Feb 19 16:57 RIUS_PITR_DBPROD
-rw-r----- 1 oracle asmadmin  6773248 Feb 20 08:44 arch_1_11_839926904.arc
-rw-r----- 1 oracle asmadmin 35577344 Feb 20 09:23 arch_1_12_839926904.arc
-rw-r----- 1 oracle asmadmin    86016 Feb 20 09:26 arch_1_13_839926904.arc
drwxr-x--- 4 oracle asmadmin     4096 Feb 20 09:29 SEKV_PITR_DBPROD
-rw-r----- 1 oracle asmadmin 41875968 Feb 20 11:02 arch_1_14_839926904.arc
-rw-r----- 1 oracle asmadmin   173056 Feb 20 11:11 arch_1_15_839926904.arc
drwxr-x--- 4 oracle asmadmin     4096 Feb 20 11:15 YVDV_PITR_DBPROD

E assim chegamos ao fim deste artigo, com essa simples demonstração de uma funcionalidade bem interessante da versão 12C. Vale registrar que apenas a versão Enterprise fornece suporte à esta operação. Temos algumas outras opções para este processo, como apenas gerar o dump (sem exlusão do mesmo ao final do procedimento) e recuperar todo um schema.
Veja que, quando existe o espaço suficiente para a duplicação da base e geração do dump, em apenas 1 único comando (RECOVER TABLE …), o DBA tem todos os 4 processos mencionados no início do artigo, realizados e gerenciados pelo RMAN.
Para mais detalhes destas operações, recomendo a leitura da documentação oficial da Oracle sobre este tema.

Abraços e até mais

%name Recover de tabela a partir de backup RMAN em Oracle 12C

Autor: Bruno Zehetmeyr bruno.zehe

Bacharel em Ciência da Computação pela UNORP-SP, Pós-graduado em Administração de Sistemas de Informação pela UFLA-MG e pós-graduado em Administração de Banco de Dados Oracle pela VERIS-SP. Analista DBA na Teiko Soluções em TI e professor universitário no Centro Universitário de Brusque – UBIFEBE. Certificado OCP 10g e OCP 11g, OCE Linux. Residente em Blumenau-SC.