In this scenario I will perform a SCN-based incomplete recovery after I have used the Oracle LogMiner utility to retrieve a useful SCN where to stop my recovery process.
Before starting the recovery process I want to be sure a valid backup is available.
[oracle@localhost ~]$ rman target / Recovery Manager: Release 11.2.0.2.0 - Production on Tue Apr 23 07:42:39 2013 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. connected to target database: ORCL (DBID=1229390655) RMAN> list backup summary; using target database control file instead of recovery catalog List of Backups =============== Key TY LV S Device Type Completion Time #Pieces #Copies Compressed Tag ------- -- -- - ----------- ------------------- ------- ------- ---------- --- 257 B A A DISK 22-04-2013 21:33:38 1 1 YES TAG20130422T213335 258 B F A DISK 22-04-2013 21:45:34 1 1 YES TAG20130422T213339 259 B A A DISK 22-04-2013 21:45:38 1 1 YES TAG20130422T214537 260 B F A DISK 22-04-2013 21:45:41 1 1 NO TAG20130422T214539 261 B F A DISK 23-04-2013 05:02:30 1 1 NO TAG20130423T050224 262 B F A DISK 23-04-2013 06:17:30 1 1 NO TAG20130423T061726Now I'm going to execute few sql statements to modify my database and to know the SCN at which those operations were performed.
Lukely in a normal situation you don't have to get every time the current SCN after each DML operations: but in this scenario these values will be useful because I want to compare them with those returned by the LogMiner utility when I need to recover the database.
So approximately at SCN equals to 14928918 my database has two tables with few rows into my schema.
SQL> select count(*) from marcov.t1; COUNT(*) ---------- 2000 SQL> select count(*) from marcov.t2; COUNT(*) ---------- 4000 SQL> select dbms_flashback.get_system_change_number scn from dual; SCN ---------- 14928918When SCN is equals to 14928987 in the same schema I have created another table and inserted few rows.
SQL> create table marcov.new_deployment (a number); Table created. SQL> insert into marcov.new_deployment select * from marcov.t1; 2000 rows created. SQL> commit; Commit complete. SQL> select count(*) from marcov.new_deployment; COUNT(*) ---------- 2000 SQL> select dbms_flashback.get_system_change_number scn from dual; SCN ---------- 14928987At SCN number 14929031 my recently created table no more exists because it was "inadvertently" dropped:
SQL> drop table marcov.new_deployment purge; Table dropped. SQL> select count(*) from marcov.new_deployment; select count(*) from marcov.new_deployment * ERROR at line 1: -- SCN of reference SQL> select dbms_flashback.get_system_change_number scn from dual; SCN ---------- 14929031I want to perform an incomplete recovery and stop it just before the moment at which someone dropped my table.
I know someone dropped my table so I can use the LogMiner utility and look at every operation performed on my table.
First of all I need to specify which redo log (online or archived of course) should be analyzed.
I was alerted as soon as the table was accidentally dropped so I would try to start my redo log analysis from the CURRENT one.
If you want to analyze more redo logs at the same time you can use the DBMS_LOGMNR.ADDFILE option into the DBMS_LOGMNR.ADD_LOGFILE procedure or start the LogMiner using DBMS_LOGMNR.START_LOGMNR with the CONTINUOUS_MINE as option.
Let me see which redo log is the CURRENT.
SQL> select member from v$logfile a, v$log b where a.group#=b.group# and b.status = 'CURRENT'; MEMBER ------------------------------------------------------------ /home/oracle/app/oracle/oradata/orcl/redo02.log /home/oracle/app/oracle/oradata/orcl/redo02b.logBefore starting a LogMiner session you have to add the redo log file you want to analyze using the DBMS_LOGMRN.ADD_LOGFILE procedure. In my case I want to add my CURRENT redo log file.
SQL> exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/app/oracle/oradata/orcl/redo02.log', options=>dbms_logmnr.addfile); PL/SQL procedure successfully completed.Then you can start your LogMiner session specifying to use the dictionary currently in use in the database.
SQL> exec dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog); PL/SQL procedure successfully completed.After you have successfully executed the DBMS_LOGMRN.START_LOGMNR, the v$logmnr_contents view will contain the redo data of interest.
To query the v$logmnr_contents view your user must have the SELECT ANY TRANSACTION privilege.
In the following statement I want to know the operations occurred on my dropped table, when they were performed, the associated SCN and the statement executed.
SQL> col sql_redo format a60 SQL> col ts format a30 SQL> select scn, to_char(timestamp, 'dd/mm/yyyy hh24:mi:ss') ts, operation, sql_redo from v$logmnr_contents where table_name = 'NEW_DEPLOYMENT' order by ts; SCN TS OPERATION SQL_REDO ---------- ------------------------------ -------------------------------- ------------------------------------------------------------ 14928965 23/04/2013 22:16:49 DDL create table marcov.new_deployment (a number); 14929007 23/04/2013 22:17:54 DDL drop table marcov.new_deployment purge;As you can see my table was created when SCN was equal to 14928965 and dropped when it was 14929007.
These values are logically consistent of course with the previous calculated SCN using the DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER procedure: I obtained a SCN equals to 14928987 after the table was created (14928965 from v$logmnr_contents view), but still not dropped and equals to 14929031 few seconds later the table was dropped (14929007 from v$logmnr_contents view). I have all the necessary information so I can close the LogMiner session and perform a SCN-based incomplete recovery just one step before the SCN be equal to 14929007.
SQL> exec dbms_logmnr.end_logmnr(); PL/SQL procedure successfully completed.To perform an incomplete recovery the database must be in MOUNT mode.
RMAN> shutdown immediate; database closed database dismounted Oracle instance shut down RMAN> startup mount; connected to target database (not started) Oracle instance started database mounted Total System Global Area 456146944 bytes Fixed Size 1344840 bytes Variable Size 373295800 bytes Database Buffers 75497472 bytes Redo Buffers 6008832 bytesIn a previous post related on time-based incomplete recovery I issued a series of single RMAN commands: now I want to use another syntax using the set until ... option (set until scn in this case) and a run { ... } block.
RMAN> run { 2> set until scn 14929007; 3> restore database; 4> recover database; 5> alter database open resetlogs; 6> } executing command: SET until clause Starting restore at 23-04-2013 22:22:13 allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=19 device type=DISK skipping datafile 7; already restored to file /home/oracle/app/oracle/oradata/orcl/read_only01.dbf channel ORA_DISK_1: starting datafile backup set restore channel ORA_DISK_1: specifying datafile(s) to restore from backup set channel ORA_DISK_1: restoring datafile 00001 to /home/oracle/app/oracle/oradata/orcl/system01.dbf channel ORA_DISK_1: restoring datafile 00002 to /home/oracle/app/oracle/oradata/orcl/sysaux01.dbf channel ORA_DISK_1: restoring datafile 00003 to /home/oracle/app/oracle/oradata/orcl/undotbs01.dbf channel ORA_DISK_1: restoring datafile 00004 to /home/oracle/app/oracle/oradata/orcl/users01.dbf channel ORA_DISK_1: restoring datafile 00005 to /home/oracle/app/oracle/oradata/orcl/example01.dbf channel ORA_DISK_1: restoring datafile 00006 to /home/oracle/app/oracle/oradata/orcl/APEX.dbf channel ORA_DISK_1: restoring datafile 00008 to /home/oracle/app/oracle/oradata/orcl/ZZZ01.dbf channel ORA_DISK_1: restoring datafile 00009 to /home/oracle/app/oracle/oradata/orcl/example02.dbf channel ORA_DISK_1: restoring datafile 00010 to /home/oracle/app/oracle/oradata/orcl/APEX02.dbf channel ORA_DISK_1: restoring datafile 00011 to /home/oracle/app/oracle/oradata/orcl/marcov01.dbf channel ORA_DISK_1: restoring datafile 00012 to /home/oracle/app/oracle/oradata/orcl/test01.dbf channel ORA_DISK_1: reading from backup piece /home/oracle/app/oracle/flash_recovery_area/ORCL/backupset/2013_04_22/o1_mf_nnndf_TAG20130422T213339_8qd3s6fx_.bkp channel ORA_DISK_1: piece handle=/home/oracle/app/oracle/flash_recovery_area/ORCL/backupset/2013_04_22/o1_mf_nnndf_TAG20130422T213339_8qd3s6fx_.bkp tag=TAG20130422T213339 channel ORA_DISK_1: restored backup piece 1 channel ORA_DISK_1: restore complete, elapsed time: 00:04:32 Finished restore at 23-04-2013 22:26:46 Starting recover at 23-04-2013 22:26:47 using channel ORA_DISK_1 datafile 7 not processed because file is read-only starting media recovery archived log for thread 1 with sequence 49 is already on disk as file /home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_22/o1_mf_1_49_8qd5pd13_.arc archived log for thread 1 with sequence 50 is already on disk as file /home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_22/o1_mf_1_50_8qd6ckq5_.arc archived log for thread 1 with sequence 1 is already on disk as file /home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_23/o1_mf_1_1_8qf0kqy2_.arc channel ORA_DISK_1: starting archived log restore to default destination channel ORA_DISK_1: restoring archived log archived log thread=1 sequence=48 channel ORA_DISK_1: reading from backup piece /home/oracle/app/oracle/flash_recovery_area/ORCL/backupset/2013_04_22/o1_mf_annnn_TAG20130422T214537_8qd4hl7n_.bkp channel ORA_DISK_1: piece handle=/home/oracle/app/oracle/flash_recovery_area/ORCL/backupset/2013_04_22/o1_mf_annnn_TAG20130422T214537_8qd4hl7n_.bkp tag=TAG20130422T214537 channel ORA_DISK_1: restored backup piece 1 channel ORA_DISK_1: restore complete, elapsed time: 00:00:01 archived log file name=/home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_23/o1_mf_1_48_8qgv8t7p_.arc thread=1 sequence=48 channel default: deleting archived log(s) archived log file name=/home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_23/o1_mf_1_48_8qgv8t7p_.arc RECID=278 STAMP=813536810 archived log file name=/home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_22/o1_mf_1_49_8qd5pd13_.arc thread=1 sequence=49 archived log file name=/home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_22/o1_mf_1_50_8qd6ckq5_.arc thread=1 sequence=50 archived log file name=/home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_23/o1_mf_1_1_8qf0kqy2_.arc thread=1 sequence=1 archived log file name=/home/oracle/app/oracle/flash_recovery_area/ORCL/archivelog/2013_04_23/o1_mf_1_1_8qgs3znf_.arc thread=1 sequence=1 media recovery complete, elapsed time: 00:00:25 Finished recover at 23-04-2013 22:27:16 database openedAs you can see my table is now available again.
SQL> select count(*) from marcov.new_deployment; COUNT(*) ---------- 2000That's all.