O recurso de TSPITR é ideal para os casos onde precisamos recuperar uma ou mais tablespaces em um ponto no tempo sem afetar o funcionamento do resto do banco de dados (logicamente para user tablespaces). A execução do processo é simples, mas nos bastidores temos as seguintes etapas sendo realizadas pelo RMAN:
- A tablespace é alterada para o modo OFFLINE;
- Uma instância auxiliar é criada automaticamente, e um controlfile é restaurado para o ambiente temporário;
- Temos o restore das tablespaces desejadas e também das tablespaces SYSTEM,SYSAUX, além da criação da UNDO e TEMP;
- Temos o recover das tablespaces;
- Abertura do banco de dados auxiliar usando a opção NORESETLOGS;
- É realizado um export (via Data Pump) da tablespace do banco auxiliar;
- No ambiente original, o processo de Data Pump lê o arquivo dump gerado, pluga a tablespace recuperada no banco de dados, deixa-a em modo READ/WRITE e em seguida no modo OFFLINE;
- A instância auxiliar e todos os seus componentes (lógicos e físicos) são descartados
O processo em si tem os modos Fully Automated (padrão), Autometed e Non-Autometed. Neste artigo vamos explorar o primeiro cenário.
Vamos realizar o reconhecimento ao nosso ambiente laboratório:
[oracle@oel8 ~]$ rman target /
Recovery Manager: Release 18.0.0.0.0 - Production on Mon Aug 9 20:04:15 2021
Version 18.13.0.0.0
Copyright (c) 1982, 2018, Oracle and/or its affiliates. All rights reserved.
connected to target database: RMANDB (DBID=3825250984)
RMAN> SELECT NAME,OPEN_MODE,LOG_MODE FROM V$DATABASE;
using target database control file instead of recovery catalog
NAME OPEN_MODE LOG_MODE
--------- -------------------- ------------
RMANDB READ WRITE ARCHIVELOG
RMAN> REPORT SCHEMA;
Report of database schema for database with db_unique_name RMANDB
List of Permanent Datafiles
===========================
File Size(MB) Tablespace RB segs Datafile Name
---- -------- -------------------- ------- ------------------------
1 880 SYSTEM YES /oracle/dados/RMANDB/datafile/o1_mf_system_h8nynqfx_.dbf
2 120 TS_HIPO_CATALOG NO /oracle/dados/RMANDB/datafile/ts_hipo_catalog.dbf
3 730 SYSAUX NO /oracle/dados/RMANDB/datafile/o1_mf_sysaux_h8nyq35q_.dbf
4 305 UNDOTBS1 YES /oracle/dados/RMANDB/datafile/o1_mf_undotbs1_h8nyrjdr_.dbf
5 200 TS_CORTEX_CATALOG NO /oracle/dados/RMANDB/datafile/ts_cortex_catalog.dbf
7 16 USERS NO /oracle/dados/RMANDB/datafile/o1_mf_users_h8nyrkn7_.dbf
List of Temporary Files
=======================
File Size(MB) Tablespace Maxsize(MB) Tempfile Name
---- -------- -------------------- ----------- --------------------
1 69 TEMP 32767 /oracle/dados/RMANDB/datafile/o1_mf_temp_h8nyvt1f_.tmp
Realizando um backup do banco de dados:
RMAN> BACKUP DATABASE;
Starting backup at 2021-08-09:20:06:17
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=59 device type=DISK
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=/oracle/dados/RMANDB/datafile/o1_mf_system_h8nynqfx_.dbf
input datafile file number=00003 name=/oracle/dados/RMANDB/datafile/o1_mf_sysaux_h8nyq35q_.dbf
input datafile file number=00004 name=/oracle/dados/RMANDB/datafile/o1_mf_undotbs1_h8nyrjdr_.dbf
input datafile file number=00005 name=/oracle/dados/RMANDB/datafile/ts_cortex_catalog.dbf
input datafile file number=00002 name=/oracle/dados/RMANDB/datafile/ts_hipo_catalog.dbf
input datafile file number=00007 name=/oracle/dados/RMANDB/datafile/o1_mf_users_h8nyrkn7_.dbf
channel ORA_DISK_1: starting piece 1 at 2021-08-09:20:06:18
channel ORA_DISK_1: finished piece 1 at 2021-08-09:20:08:03
piece handle=/oracle/fra/RMANDB/backupset/2021_08_09/o1_mf_nnndf_TAG20210809T200618_jk3f7fbd_.bkp tag=TAG20210809T200618 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:01:45
Finished backup at 2021-08-09:20:08:03
Starting Control File and SPFILE Autobackup at 2021-08-09:20:08:03
piece handle=/oracle/fra/RMANDB/autobackup/2021_08_09/o1_mf_s_1080158883_jk3fbn9x_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 2021-08-09:20:08:06
A tabela que usaremos como referência está hospedada na tablespace USERS, conforme é demonstrado:
RMAN> ALTER SYSTEM SWITCH LOGFILE;
Statement processed
RMAN> SELECT * FROM BSS.PITR;
DESCRICAO
--------------------------------------------------
PITR DO BRUNO
RMAN> SELECT DISTINCT(TABLESPACE_NAME) FROM DBA_SEGMENTS WHERE SEGMENT_NAME='PITR';
TABLESPACE_NAME
------------------------------
USERS
Coletando o horário que usaremos em nossa recuperação:
RMAN> SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD:HH24:MI:SS') FROM DUAL;
TO_CHAR(SYSDATE,'YY
-------------------
2021-08-09:20:11:06
Vamos dropar a nossa tabela para simular o evento gatilho da recuperação:
RMAN> ALTER SYSTEM SWITCH LOGFILE;
Statement processed
RMAN> DROP TABLE BSS.PITR;
Statement processed
RMAN> ALTER SYSTEM SWITCH LOGFILE;
Statement processed
Para demonstrarmos uma situação específica, vamos criar outra tabela após o “incidente”:
RMAN> CREATE TABLE BSS.BRUNO AS SELECT * FROM DBA_USERS;
Statement processed
Nesse ponto, podemos iniciar o processo de recuperação em si. Como identificamos que a tablespace afetada é a USERS, devemos nos certificar que a mesma é classificada como “self-contained”, ou seja, que não tenha dependência de outras tablespaces em seus objetos. Para isso, rodamos o comando abaixo:
[oracle@oel8 ~]$ sqlplus / as sysdba
SQL*Plus: Release 18.0.0.0.0 - Production on Mon Aug 9 20:17:49 2021
Version 18.13.0.0.0
Copyright (c) 1982, 2018, Oracle. All rights reserved.
Connected to:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.13.0.0.0
SQL> exec DBMS_TTS.TRANSPORT_SET_CHECK('USERS', TRUE,TRUE);
PL/SQL procedure successfully completed.
Se algo não estiver conforme o esperado, será reportado na consulta abaixo:
SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected
Com a consulta abaixo, podemos ver todos os objetos criados após o incidente, ou seja, que não serão contemplados na recuperação. Caso esses objetos sejam importantes, devemos realizar o backup dos mesmos (com o Data Pump, por exemplo), e após o TSPITR, importá-los. Como o intuito aqui é apenas didático, o simples fato de este item ser exposto já vale. Não precisarei deste objeto:
SQL> col OWNER for a10
col NAME for a10
col TABLESPACE_NAME for a10
SELECT OWNER, NAME, TABLESPACE_NAME FROM TS_PITR_OBJECTS_TO_BE_DROPPED WHERE TABLESPACE_NAME IN ('USERS') AND CREATION_TIME > TO_DATE('2021-08-09:20:11:06','YYYY-MM-DD:HH24:MI:SS') ORDER BY 1,2;SQL> SQL> SQL>
OWNER NAME TABLESPACE
---------- ---------- ----------
BSS BRUNO USERS
Agora vamos criar um diretório específico que será usado por nossa instância auxiliar:
[oracle@oel8 oracle]$ pwd
/oracle
[oracle@oel8 oracle]$ mkdir TSPITR
[oracle@oel8 oracle]$ cd TSPITR/
[oracle@oel8 TSPITR]$ pwd
/oracle/TSPITR
Como o modo escolhido é o totalmente automático, para iniciarmos o processo de recuperação, basta rodarmos uma única linha de código, conforme exemplo e log abaixo:
[oracle@oel8 TSPITR]$ rman target /
Recovery Manager: Release 18.0.0.0.0 - Production on Mon Aug 9 20:40:06 2021
Version 18.13.0.0.0
Copyright (c) 1982, 2018, Oracle and/or its affiliates. All rights reserved.
connected to target database: RMANDB (DBID=3825250984)
RMAN> RECOVER TABLESPACE USERS UNTIL TIME "to_date('2021-08-09:20:11:06','YYYY-MM-DD:HH24:MI:SS')" AUXILIARY DESTINATION '/oracle/TSPITR';
Starting recover at 2021-08-09:20:40:18
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=106 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='veas'
initialization parameters used for automatic instance:
db_name=RMANDB
db_unique_name=veas_pitr_RMANDB
compatible=18.0.0
db_block_size=8192
db_files=200
diagnostic_dest=/oracle/18.0.0/base
_system_trig_enabled=FALSE
sga_target=1536M
processes=200
db_create_file_dest=/oracle/TSPITR
log_archive_dest_1='location=/oracle/TSPITR'
#No auxiliary parameter file used
starting up automatic instance RMANDB
Oracle instance started
Total System Global Area 1610612016 bytes
Fixed Size 8658224 bytes
Variable Size 402653184 bytes
Database Buffers 1191182336 bytes
Redo Buffers 8118272 bytes
Automatic instance created
Running TRANSPORT_SET_CHECK on recovery set tablespaces
TRANSPORT_SET_CHECK completed successfully
contents of Memory Script:
{
# set requested point in time
set until time "to_date('2021-08-09:20:11:06','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';
# avoid unnecessary autobackups for structural changes during TSPITR
sql 'begin dbms_backup_restore.AutoBackupFlag(FALSE); end;';
}
executing Memory Script
executing command: SET until clause
Starting restore at 2021-08-09:20:40:36
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=34 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 /oracle/fra/RMANDB/autobackup/2021_08_09/o1_mf_s_1080158883_jk3fbn9x_.bkp
channel ORA_AUX_DISK_1: piece handle=/oracle/fra/RMANDB/autobackup/2021_08_09/o1_mf_s_1080158883_jk3fbn9x_.bkp tag=TAG20210809T200803
channel ORA_AUX_DISK_1: restored backup piece 1
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:01
output file name=/oracle/TSPITR/RMANDB/controlfile/o1_mf_jk3h7o4v_.ctl
Finished restore at 2021-08-09:20:40:38
sql statement: alter database mount clone database
sql statement: alter system archive log current
sql statement: begin dbms_backup_restore.AutoBackupFlag(FALSE); end;
contents of Memory Script:
{
# set requested point in time
set until time "to_date('2021-08-09:20:11:06','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;
set newname for datafile 7 to
"/oracle/dados/RMANDB/datafile/o1_mf_users_h8nyrkn7_.dbf";
# switch all tempfiles
switch clone tempfile all;
# restore the tablespaces in the recovery set and the auxiliary set
restore clone datafile 1, 4, 3, 7;
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
executing command: SET NEWNAME
renamed tempfile 1 to /oracle/TSPITR/RMANDB/datafile/o1_mf_temp_%u_.tmp in control file
Starting restore at 2021-08-09:20:40:43
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 00001 to /oracle/TSPITR/RMANDB/datafile/o1_mf_system_%u_.dbf
channel ORA_AUX_DISK_1: restoring datafile 00004 to /oracle/TSPITR/RMANDB/datafile/o1_mf_undotbs1_%u_.dbf
channel ORA_AUX_DISK_1: restoring datafile 00003 to /oracle/TSPITR/RMANDB/datafile/o1_mf_sysaux_%u_.dbf
channel ORA_AUX_DISK_1: restoring datafile 00007 to /oracle/dados/RMANDB/datafile/o1_mf_users_h8nyrkn7_.dbf
channel ORA_AUX_DISK_1: reading from backup piece /oracle/fra/RMANDB/backupset/2021_08_09/o1_mf_nnndf_TAG20210809T200618_jk3f7fbd_.bkp
channel ORA_AUX_DISK_1: piece handle=/oracle/fra/RMANDB/backupset/2021_08_09/o1_mf_nnndf_TAG20210809T200618_jk3f7fbd_.bkp tag=TAG20210809T200618
channel ORA_AUX_DISK_1: restored backup piece 1
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:02:45
Finished restore at 2021-08-09:20:43:28
datafile 1 switched to datafile copy
input datafile copy RECID=49 STAMP=1080161008 file name=/oracle/TSPITR/RMANDB/datafile/o1_mf_system_jk3h7vm3_.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=50 STAMP=1080161008 file name=/oracle/TSPITR/RMANDB/datafile/o1_mf_undotbs1_jk3h7vos_.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=51 STAMP=1080161008 file name=/oracle/TSPITR/RMANDB/datafile/o1_mf_sysaux_jk3h7vop_.dbf
contents of Memory Script:
{
# set requested point in time
set until time "to_date('2021-08-09:20:11:06','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";
sql clone "alter database datafile 7 online";
# recover and open resetlogs
recover clone database tablespace "USERS", "SYSTEM", "UNDOTBS1", "SYSAUX" delete archivelog;
alter clone database open resetlogs;
}
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
sql statement: alter database datafile 7 online
Starting recover at 2021-08-09:20:43:29
using channel ORA_AUX_DISK_1
starting media recovery
archived log for thread 1 with sequence 1 is already on disk as file /oracle/archives/1_1_1079643731.dbf
archived log for thread 1 with sequence 2 is already on disk as file /oracle/archives/1_2_1079643731.dbf
archived log file name=/oracle/archives/1_1_1079643731.dbf thread=1 sequence=1
archived log file name=/oracle/archives/1_2_1079643731.dbf thread=1 sequence=2
media recovery complete, elapsed time: 00:00:00
Finished recover at 2021-08-09:20:43:31
database opened
contents of Memory Script:
{
# make read only the tablespace that will be exported
sql clone 'alter tablespace USERS read only';
# create directory for datapump import
sql "create or replace directory TSPITR_DIROBJ_DPDIR as ''
/oracle/TSPITR''";
# create directory for datapump export
sql clone "create or replace directory TSPITR_DIROBJ_DPDIR as ''
/oracle/TSPITR''";
}
executing Memory Script
sql statement: alter tablespace USERS read only
sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''/oracle/TSPITR''
sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''/oracle/TSPITR''
Performing export of metadata...
EXPDP> Starting "SYS"."TSPITR_EXP_veas_Fofq":
EXPDP> Processing object type TRANSPORTABLE_EXPORT/INDEX/STATISTICS/INDEX_STATISTICS
EXPDP> Processing object type TRANSPORTABLE_EXPORT/STATISTICS/TABLE_STATISTICS
EXPDP> Processing object type TRANSPORTABLE_EXPORT/STATISTICS/MARKER
EXPDP> Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
EXPDP> Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
EXPDP> Processing object type TRANSPORTABLE_EXPORT/TABLE
EXPDP> Processing object type TRANSPORTABLE_EXPORT/INDEX/INDEX
EXPDP> Processing object type TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINT
EXPDP> Processing object type TRANSPORTABLE_EXPORT/COMMENT
EXPDP> Processing object type TRANSPORTABLE_EXPORT/CONSTRAINT/REF_CONSTRAINT
EXPDP> Processing object type TRANSPORTABLE_EXPORT/TRIGGER
EXPDP> Master table "SYS"."TSPITR_EXP_veas_Fofq" successfully loaded/unloaded
EXPDP> ******************************************************************************
EXPDP> Dump file set for SYS.TSPITR_EXP_veas_Fofq is:
EXPDP> /oracle/TSPITR/tspitr_veas_10076.dmp
EXPDP> ******************************************************************************
EXPDP> Datafiles required for transportable tablespace USERS:
EXPDP> /oracle/dados/RMANDB/datafile/o1_mf_users_h8nyrkn7_.dbf
EXPDP> Job "SYS"."TSPITR_EXP_veas_Fofq" successfully completed at Mon Aug 9 20:44:40 2021 elapsed 0 00:00:46
Export completed
contents of Memory Script:
{
# shutdown clone before import
shutdown clone abort
# drop target tablespaces before importing them back
sql 'drop tablespace USERS including contents keep datafiles cascade constraints';
}
executing Memory Script
Oracle instance shut down
sql statement: drop tablespace USERS including contents keep datafiles cascade constraints
Performing import of metadata...
IMPDP> Master table "SYS"."TSPITR_IMP_veas_qlri" successfully loaded/unloaded
IMPDP> Starting "SYS"."TSPITR_IMP_veas_qlri":
IMPDP> Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
IMPDP> Processing object type TRANSPORTABLE_EXPORT/TABLE
IMPDP> Processing object type TRANSPORTABLE_EXPORT/INDEX/INDEX
IMPDP> Processing object type TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINT
IMPDP> Processing object type TRANSPORTABLE_EXPORT/INDEX/STATISTICS/INDEX_STATISTICS
IMPDP> Processing object type TRANSPORTABLE_EXPORT/COMMENT
IMPDP> Processing object type TRANSPORTABLE_EXPORT/CONSTRAINT/REF_CONSTRAINT
IMPDP> Processing object type TRANSPORTABLE_EXPORT/TRIGGER
IMPDP> Processing object type TRANSPORTABLE_EXPORT/STATISTICS/TABLE_STATISTICS
IMPDP> Processing object type TRANSPORTABLE_EXPORT/STATISTICS/MARKER
IMPDP> Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
IMPDP> Job "SYS"."TSPITR_IMP_veas_qlri" successfully completed at Mon Aug 9 20:45:20 2021 elapsed 0 00:00:23
Import completed
contents of Memory Script:
{
# make read write and offline the imported tablespaces
sql 'alter tablespace USERS read write';
sql 'alter tablespace USERS offline';
# enable autobackups after TSPITR is finished
sql 'begin dbms_backup_restore.AutoBackupFlag(TRUE); end;';
}
executing Memory Script
sql statement: alter tablespace USERS read write
sql statement: alter tablespace USERS offline
sql statement: begin dbms_backup_restore.AutoBackupFlag(TRUE); end;
Removing automatic instance
Automatic instance removed
auxiliary instance file /oracle/TSPITR/RMANDB/datafile/o1_mf_temp_jk3hfms7_.tmp deleted
auxiliary instance file /oracle/TSPITR/RMANDB/onlinelog/o1_mf_3_jk3hfcxs_.log deleted
auxiliary instance file /oracle/TSPITR/RMANDB/onlinelog/o1_mf_2_jk3hf3qn_.log deleted
auxiliary instance file /oracle/TSPITR/RMANDB/onlinelog/o1_mf_1_jk3hf3q1_.log deleted
auxiliary instance file /oracle/TSPITR/RMANDB/datafile/o1_mf_sysaux_jk3h7vop_.dbf deleted
auxiliary instance file /oracle/TSPITR/RMANDB/datafile/o1_mf_undotbs1_jk3h7vos_.dbf deleted
auxiliary instance file /oracle/TSPITR/RMANDB/datafile/o1_mf_system_jk3h7vm3_.dbf deleted
auxiliary instance file /oracle/TSPITR/RMANDB/controlfile/o1_mf_jk3h7o4v_.ctl deleted
auxiliary instance file tspitr_veas_10076.dmp deleted
Finished recover at 2021-08-09:20:45:23
RMAN>
Como podemos ver, a tablespace recuperado está OFFLINE. Isso acontece pois, como é recomendação da própria Oracle, é mister realizarmos um backup mínimo na estrutura recém-recuperada:
RMAN> SELECT TABLESPACE_NAME,STATUS FROM DBA_TABLESPACES WHERE TABLESPACE_NAME='USERS';
TABLESPACE_NAME STATUS
------------------------------ ---------
USERS OFFLINE
Por isso vou realizar um backup simples da tablespace:
RMAN> BACKUP TABLESPACE USERS;
Starting backup at 2021-08-09:20:49:05
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=00007 name=/oracle/dados/RMANDB/datafile/o1_mf_users_h8nyrkn7_.dbf
channel ORA_DISK_1: starting piece 1 at 2021-08-09:20:49:05
channel ORA_DISK_1: finished piece 1 at 2021-08-09:20:49:08
piece handle=/oracle/fra/RMANDB/backupset/2021_08_09/o1_mf_nnndf_TAG20210809T204905_jk3hql56_.bkp tag=TAG20210809T204905 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
Finished backup at 2021-08-09:20:49:08
Starting Control File and SPFILE Autobackup at 2021-08-09:20:49:08
piece handle=/oracle/fra/RMANDB/autobackup/2021_08_09/o1_mf_s_1080161348_jk3hqp3z_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 2021-08-09:20:49:11
Deixando a tablespace ONLINE:
RMAN> ALTER TABLESPACE USERS ONLINE;
Statement processed
Validando que nossa tabela está devidamente recuperada:
RMAN> SELECT * FROM BSS.PITR;
DESCRICAO
--------------------------------------------------
PITR DO BRUNO
Obs: Este procedimento foi criado pelo senhor Ahmed Baraka (www.ahmedbaraka.com) e foi apenas reproduzido por mim em um laboratório pessoal para fins de aprendizado.