User may drop or truncate a table or delete records accidently which need to recover. Even sometimes we may need to recover the data for a table for corrupted data. This is very difficult to restore the full DB if database size is huge like Terabytes. I will demonstrate with this Article how we can recover the single table from backup and archive log up-to point in time or SCN.
Prerequisites:
- Database must be an archive log mode.
- Ensure you have a valid backup of the database that includes the tablespace with all datafiles of the Table which want to recover.
- We need space on filesystem for SYSTEM, SYSAUX, UNDO and target table tablespace where Auxiliary DB files will create.
- Auxiliary Instance will create on server during the recover process and will automatically drop including newly created datafiles once recover is done. No Impact on Target database.
Note: Auxiliary Instance will create on server during the recover process and will automatically drop the Instance including newly created datafiles once recover is done. No much Impacted on target database but Auxiliary DB will consume few GB RAM from server.
Environment Setup:
SQL> archive log list Database log mode Archive Mode Automatic archival Enabled Archive destination USE_DB_RECOVERY_FILE_DEST Oldest online log sequence 5 Next log sequence to archive 7 Current log sequence 7 SQL> create user user_app identified by user_app; User created. SQL> create tablespace tbs_test datafile '/u01/oradata/ORCL/tbstest01.dbf' size 200M; Tablespace created. SQL> create tablespace tbs_apps datafile '/u01/oradata/ORCL/tbsapp01.dbf' size 20M; Tablespace created. SQL> select name from v$tablespace; NAME ------------------------------ SYSAUX SYSTEM UNDOTBS1 USERS TEMP TBS_TEST TBS_APPS 7 rows selected. SQL> select name from v$datafile; NAME -------------------------------------------------------------------------------- /u01/oradata/ORCL/system01.dbf /u01/oradata/ORCL/tbsapp01.dbf /u01/oradata/ORCL/sysaux01.dbf /u01/oradata/ORCL/undotbs01.dbf /u01/oradata/ORCL/tbstest01.dbf /u01/oradata/ORCL/users01.dbf 6 rows selected. SQL> alter user user_app default tablespace tbs_test; User altered. SQL> alter user user_app temporary tablespace temp; User altered. SQL> alter user user_app quota unlimited on tbs_test; User altered. SQL> create table user_app.test as select * from dba_objects; Table created.
Database Backup: (Assumed Production Database has daily backup)
run {
allocate channel c1 type disk format '/u01/backup/c1_%p_%s_%c.rman';
allocate channel c2 type disk format '/u01/backup/c2_%p_%s_%c.rman';
allocate channel c3 type disk format '/u01/backup/c3_%p_%s_%c.rman';
allocate channel c4 type disk format '/u01/backup/c4_%p_%s_%c.rman';
Backup database plus archivelog;
}
Create Table:
SQL> create table user_app.employees as select * from hr.employees;
Table created.
SQL> select count(*) from user_app.employees;
COUNT(*)
----------
107
SQL> select to_char(current_scn) from v$database;
TO_CHAR(CURRENT_SCN)
----------------------------------------
2206889
SQL> select to_char(sysdate, 'MM-DD-YYYY HH24:MI:SS') "DATE" from dual;
DATE
-------------------
10-26-2023 14:03:17
SQL> create table user_app.departments as select * from hr.departments;
Table created.
SQL> select count(*) from user_app.departments;
COUNT(*)
----------
27
SQL> drop table user_app.employees;
Table dropped.
SQL> select count(*) from user_app.employees;
select count(*) from user_app.employees
*
ERROR at line 1:
ORA-00942: table or view does not exist
Recover Table and Import to Database:
The RECOVER TABLE command with AUXILIARY DESTINATION location for the auxiliary database. The point in time can be specified using UNTIL SCN, UNTIL TIME or UNTIL SEQUENCE. In this case, we need to find the time or SCN before dropped or truncated of the table.
Using the REMAP TABLE clause is included to give the recovered table a new name so we can review before finalized the original table. In this example, I recovered using SCN from below command.
[oracle@orcl19c ~]$ cat emp_tbl_restore.sh #!/bin/ksh export ORACLE_SID=ORCL export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 export PATH=$PATH:$ORACLE_HOME/bin rman target / msglog /home/oracle/employees_table_restore.log cmdfile=/home/oracle/emp_table_recover.cmd #Until SCN [oracle@orcl19c ~]$ cat emp_table_recover.cmd recover table user_app.employees until scn 2206889 auxiliary destination '/u01/recover' remap table user_app.employees:emp_prev;
Other Options: using time
# Until Time
[oracle@orcl19c ~]$ cat emp_table_recover.cmd
recover table user_app.employees
until time "to_date('10-26-2023 14:03:17','mm-dd-yyyy:hh24:mi:ss')"
auxiliary destination '/u01/recover'
remap table user_app.employees:emp_prev;
# recover table to dump file
recover table user_app.employees
until scn 2206889
auxiliary destination '/u01/recover'
datapump destination '/u01/export'
dump file 'test_t1_prev.dmp'
notableimport;
Recover script execute:
[oracle@orcl19c ~]$ nohup ./emp_tbl_restore.sh & [1] 6145 [oracle@orcl19c ~]$ nohup: ignoring input and appending output to ânohup.out
Temporary Auxiliary Database Created:
[oracle@orcl19c ~]$ ps -ef | grep smon oracle 3865 1 0 13:42 ? 00:00:00 ora_smon_orcl oracle 6391 3439 0 14:57 pts/1 00:00:00 grep --color=auto smon [oracle@orcl19c ~]$ ps -ef | grep smon oracle 3865 1 0 13:42 ? 00:00:00 ora_smon_orcl oracle 6437 1 0 14:57 ? 00:00:00 ora_smon_saBE oracle 6459 3439 0 14:57 pts/1 00:00:00 grep --color=auto smon [oracle@orcl19c ORCL]$ pwd /u01/recover [oracle@orcl19c recover]$ cd ORCL [oracle@orcl19c ORCL]$ ls controlfile datafile onlinelog
Recovery LOG:
[oracle@orcl19c datafile]$ cat /home/oracle/employees_table_restore.log
Recovery Manager: Release 19.0.0.0.0 - Production on Thu Oct 26 14:56:05 2023
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
connected to target database: ORCL (DBID=1678862077)
RMAN> recover table user_app.employees
2> until scn 2206889
3> auxiliary destination '/u01/recover'
4> remap table user_app.employees:emp_prev;
5>
Starting recover at 26-OCT-23
using target database control file instead of recovery catalog
current log archived
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=82 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='saBE'
initialization parameters used for automatic instance:
db_name=ORCL
db_unique_name=saBE_pitr_ORCL
compatible=19.0.0
db_block_size=8192
db_files=200
diagnostic_dest=/u01/app/oracle
_system_trig_enabled=FALSE
sga_target=3040M
processes=200
db_create_file_dest=/u01/recover
log_archive_dest_1='location=/u01/recover'
#No auxiliary parameter file used
starting up automatic instance ORCL
Oracle instance started
Total System Global Area 3187667928 bytes
Fixed Size 8901592 bytes
Variable Size 637534208 bytes
Database Buffers 2533359616 bytes
Redo Buffers 7872512 bytes
Automatic instance created
contents of Memory Script:
{
# set requested point in time
set until scn 2206889;
# 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 26-OCT-23
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 /u01/app/oracle/recovery_area/ORCL/autobackup/2023_10_26/o1_mf_s_1151243216_lmof10o5_.bkp
channel ORA_AUX_DISK_1: piece handle=/u01/app/oracle/recovery_area/ORCL/autobackup/2023_10_26/o1_mf_s_1151243216_lmof10o5_.bkp tag=TAG20231026T134656
channel ORA_AUX_DISK_1: restored backup piece 1
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:01
output file name=/u01/recover/ORCL/controlfile/o1_mf_lmok3319_.ctl
Finished restore at 26-OCT-23
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 scn 2206889;
# 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 /u01/recover/ORCL/datafile/o1_mf_temp_%u_.tmp in control file
Starting restore at 26-OCT-23
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 00004 to /u01/recover/ORCL/datafile/o1_mf_undotbs1_%u_.dbf
channel ORA_AUX_DISK_1: reading from backup piece /u01/backup/c3_1_4_1.rman
channel ORA_AUX_DISK_1: piece handle=/u01/backup/c3_1_4_1.rman tag=TAG20231026T134639
channel ORA_AUX_DISK_1: restored backup piece 1
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:03
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 /u01/recover/ORCL/datafile/o1_mf_sysaux_%u_.dbf
channel ORA_AUX_DISK_1: reading from backup piece /u01/backup/c2_1_3_1.rman
channel ORA_AUX_DISK_1: piece handle=/u01/backup/c2_1_3_1.rman tag=TAG20231026T134639
channel ORA_AUX_DISK_1: restored backup piece 1
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:07
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 /u01/recover/ORCL/datafile/o1_mf_system_%u_.dbf
channel ORA_AUX_DISK_1: reading from backup piece /u01/backup/c1_1_2_1.rman
channel ORA_AUX_DISK_1: piece handle=/u01/backup/c1_1_2_1.rman tag=TAG20231026T134639
channel ORA_AUX_DISK_1: restored backup piece 1
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:15
Finished restore at 26-OCT-23
datafile 1 switched to datafile copy
input datafile copy RECID=4 STAMP=1151247410 file name=/u01/recover/ORCL/datafile/o1_mf_system_lmok3lz3_.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=5 STAMP=1151247410 file name=/u01/recover/ORCL/datafile/o1_mf_undotbs1_lmok38th_.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=6 STAMP=1151247410 file name=/u01/recover/ORCL/datafile/o1_mf_sysaux_lmok3cwn_.dbf
contents of Memory Script:
{
# set requested point in time
set until scn 2206889;
# 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 26-OCT-23
using channel ORA_AUX_DISK_1
starting media recovery
archived log for thread 1 with sequence 8 is already on disk as file /u01/app/oracle/recovery_area/ORCL/archivelog/2023_10_26/o1_mf_1_8_lmof0z3s_.arc
archived log for thread 1 with sequence 9 is already on disk as file /u01/app/oracle/recovery_area/ORCL/archivelog/2023_10_26/o1_mf_1_9_lmok2q6g_.arc
archived log file name=/u01/app/oracle/recovery_area/ORCL/archivelog/2023_10_26/o1_mf_1_8_lmof0z3s_.arc thread=1 sequence=8
archived log file name=/u01/app/oracle/recovery_area/ORCL/archivelog/2023_10_26/o1_mf_1_9_lmok2q6g_.arc thread=1 sequence=9
media recovery complete, elapsed time: 00:00:01
Finished recover at 26-OCT-23
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 =
''/u01/recover/ORCL/controlfile/o1_mf_lmok3319_.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 3187667928 bytes
Fixed Size 8901592 bytes
Variable Size 637534208 bytes
Database Buffers 2533359616 bytes
Redo Buffers 7872512 bytes
sql statement: alter system set control_files = ''/u01/recover/ORCL/controlfile/o1_mf_lmok3319_.ctl'' comment= ''RMAN set'' scope=spfile
Oracle instance shut down
connected to auxiliary database (not started)
Oracle instance started
Total System Global Area 3187667928 bytes
Fixed Size 8901592 bytes
Variable Size 637534208 bytes
Database Buffers 2533359616 bytes
Redo Buffers 7872512 bytes
sql statement: alter database mount clone database
contents of Memory Script:
{
# set requested point in time
set until scn 2206889;
# set destinations for recovery set and auxiliary set datafiles
set newname for datafile 5 to new;
# restore the tablespaces in the recovery set and the auxiliary set
restore clone datafile 5;
switch clone datafile all;
}
executing Memory Script
executing command: SET until clause
executing command: SET NEWNAME
Starting restore at 26-OCT-23
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: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00005 to /u01/recover/SABE_PITR_ORCL/datafile/o1_mf_tbs_test_%u_.dbf
channel ORA_AUX_DISK_1: reading from backup piece /u01/backup/c3_1_4_1.rman
channel ORA_AUX_DISK_1: piece handle=/u01/backup/c3_1_4_1.rman tag=TAG20231026T134639
channel ORA_AUX_DISK_1: restored backup piece 1
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:03
Finished restore at 26-OCT-23
datafile 5 switched to datafile copy
input datafile copy RECID=8 STAMP=1151247477 file name=/u01/recover/SABE_PITR_ORCL/datafile/o1_mf_tbs_test_lmok62l0_.dbf
contents of Memory Script:
{
# set requested point in time
set until scn 2206889;
# online the datafiles restored or switched
sql clone "alter database datafile 5 online";
# recover and open resetlogs
recover clone database tablespace "TBS_TEST", "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
Starting recover at 26-OCT-23
using channel ORA_AUX_DISK_1
starting media recovery
archived log for thread 1 with sequence 8 is already on disk as file /u01/app/oracle/recovery_area/ORCL/archivelog/2023_10_26/o1_mf_1_8_lmof0z3s_.arc
archived log for thread 1 with sequence 9 is already on disk as file /u01/app/oracle/recovery_area/ORCL/archivelog/2023_10_26/o1_mf_1_9_lmok2q6g_.arc
archived log file name=/u01/app/oracle/recovery_area/ORCL/archivelog/2023_10_26/o1_mf_1_8_lmof0z3s_.arc thread=1 sequence=8
archived log file name=/u01/app/oracle/recovery_area/ORCL/archivelog/2023_10_26/o1_mf_1_9_lmok2q6g_.arc thread=1 sequence=9
media recovery complete, elapsed time: 00:00:00
Finished recover at 26-OCT-23
database opened
contents of Memory Script:
{
# create directory for datapump import
sql "create or replace directory TSPITR_DIROBJ_DPDIR as ''
/u01/recover''";
# create directory for datapump export
sql clone "create or replace directory TSPITR_DIROBJ_DPDIR as ''
/u01/recover''";
}
executing Memory Script
sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''/u01/recover''
sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''/u01/recover''
Performing export of tables...
EXPDP> Starting "SYS"."TSPITR_EXP_saBE_uqhv":
EXPDP> Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
EXPDP> Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
EXPDP> Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
EXPDP> Processing object type TABLE_EXPORT/TABLE/TABLE
EXPDP> . . exported "USER_APP"."EMPLOYEES" 17.09 KB 107 rows
EXPDP> Master table "SYS"."TSPITR_EXP_saBE_uqhv" successfully loaded/unloaded
EXPDP> ******************************************************************************
EXPDP> Dump file set for SYS.TSPITR_EXP_saBE_uqhv is:
EXPDP> /u01/recover/tspitr_saBE_58687.dmp
EXPDP> Job "SYS"."TSPITR_EXP_saBE_uqhv" successfully completed at Thu Oct 26 14:58:29 2023 elapsed 0 00:00:18
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_saBE_czvw" successfully loaded/unloaded
IMPDP> Starting "SYS"."TSPITR_IMP_saBE_czvw":
IMPDP> Processing object type TABLE_EXPORT/TABLE/TABLE
IMPDP> Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
IMPDP> . . imported "USER_APP"."EMP_PREV" 17.09 KB 107 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_saBE_czvw" successfully completed at Thu Oct 26 14:58:49 2023 elapsed 0 00:00:15
Import completed
Removing automatic instance
Automatic instance removed
auxiliary instance file /u01/recover/ORCL/datafile/o1_mf_temp_lmok43l2_.tmp deleted
auxiliary instance file /u01/recover/SABE_PITR_ORCL/onlinelog/o1_mf_3_lmok67ov_.log deleted
auxiliary instance file /u01/recover/SABE_PITR_ORCL/onlinelog/o1_mf_2_lmok66j3_.log deleted
auxiliary instance file /u01/recover/SABE_PITR_ORCL/onlinelog/o1_mf_1_lmok66hd_.log deleted
auxiliary instance file /u01/recover/SABE_PITR_ORCL/datafile/o1_mf_tbs_test_lmok62l0_.dbf deleted
auxiliary instance file /u01/recover/ORCL/datafile/o1_mf_sysaux_lmok3cwn_.dbf deleted
auxiliary instance file /u01/recover/ORCL/datafile/o1_mf_undotbs1_lmok38th_.dbf deleted
auxiliary instance file /u01/recover/ORCL/datafile/o1_mf_system_lmok3lz3_.dbf deleted
auxiliary instance file /u01/recover/ORCL/controlfile/o1_mf_lmok3319_.ctl deleted
auxiliary instance file tspitr_saBE_58687.dmp deleted
Finished recover at 26-OCT-23
Recovery Manager complete.
SQL> select count(*) from user_app.emp_prev;
COUNT(*)
----------
107
SQL> select count(*) from user_app.departments;
COUNT(*)
----------
27
SQL> create table user_app.employees as select * from user_app.emp_prev;
Table created.
SQL> select count(*) from user_app.employees;
COUNT(*)
----------
107

