{"id":62,"date":"2009-07-25T14:00:00","date_gmt":"2009-07-25T12:00:00","guid":{"rendered":"https:\/\/ilmarkerm.eu\/blog\/2009\/07\/refreshing-test-database-from-production-using-incremental-backups\/"},"modified":"2009-07-25T14:00:00","modified_gmt":"2009-07-25T12:00:00","slug":"refreshing-test-database-from-production-using-incremental-backups","status":"publish","type":"post","link":"https:\/\/ilmarkerm.eu\/blog\/2009\/07\/refreshing-test-database-from-production-using-incremental-backups\/","title":{"rendered":"Refreshing test database from production using incremental backups"},"content":{"rendered":"<p>It&#8217;s common to use a production database copy for testing. But how to keep it fresh? If production database is large and located on a remote site (even on another country\/continent), then copying the full database backup over network may be too unreasonable and if the test database needs to be open for a longer time, then transporting and storing production archived logs to test site may be too unreasonable also.<br \/>\nIn this situation Oracle has three great technologies that can help: physical standby database, flashback database and RMAN.<\/p>\n<p>Here I&#8217;m using Oracle Database 10.2.0.4 EE.<\/p>\n<h3>Initial setup<\/h3>\n<p>This is just to create a test database as physical standby database. Do it in any way you like. Just make sure you create a guaranteed restore point before activating the standby.<\/p>\n<p>Create backup and standby controlfile. Give backupsets some tag, that can later be used for cleaning up the backups from primary database.<\/p>\n<pre>\nRMAN> backup device type disk format '\/home\/oracle\/backup\/%U' as compressed backupset\n  tag 'testdb_init' database INCLUDE CURRENT CONTROLFILE FOR STANDBY\n  plus archivelog;\n\nStarting backup at 24-JUL-09\nallocated channel: ORA_DISK_1\nchannel ORA_DISK_1: sid=159 devtype=DISK\nchannel ORA_DISK_1: starting compressed full datafile backupset\n... and so on\nFinished backup at 24-JUL-09\n<\/pre>\n<p>I also need to take spfile and password file.<\/p>\n<pre>\n$ cp $ORACLE_HOME\/dbs\/spfiletest1.ora \/home\/oracle\/backup\/\n$ cp $ORACLE_HOME\/dbs\/orapwtest1 \/home\/oracle\/backup\/\n<\/pre>\n<p>Now, copy everything over to the test database. I&#8217;m leaving all file locations exactly the same as in primary database.<\/p>\n<pre>\n$ scp \/home\/oracle\/backup\/* oracle@testdb:\/home\/oracle\/backup\/\n<\/pre>\n<p>On test server:<\/p>\n<pre>\n$ cd backup\/\n$ cp spfiletest1.ora $ORACLE_HOME\/dbs\/\n$ cp orapwtest1 $ORACLE_HOME\/dbs\/\n<\/pre>\n<p>Start up the test database instance and change service name to be different from the one used in production.<\/p>\n<pre>\nSQL> startup nomount\nORACLE instance started.\n\nTotal System Global Area  608174080 bytes\nFixed Size                  1268920 bytes\nVariable Size             167773000 bytes\nDatabase Buffers          436207616 bytes\nRedo Buffers                2924544 bytes\nSQL> show parameter service\n\nNAME                                 TYPE        VALUE\n------------------------------------ ----------- ------------------------------\nservice_names                        string      test1\n\nSQL> alter system set service_names='test_test1' scope=both;\n\nSystem altered.\n<\/pre>\n<p>Restore controlfile and restore the datafiles.<\/p>\n<pre>\nRMAN> restore controlfile from '\/home\/oracle\/backup\/0tkkuvob_1_1';\n\nStarting restore at 24-JUL-09\nusing target database control file instead of recovery catalog\nallocated channel: ORA_DISK_1\nchannel ORA_DISK_1: sid=156 devtype=DISK\n\nchannel ORA_DISK_1: restoring control file\nchannel ORA_DISK_1: restore complete, elapsed time: 00:00:08\noutput filename=\/u01\/app\/oracle\/oradata\/TEST1\/controlfile\/o1_mf_56lyof8g_.ctl\noutput filename=\/u01\/app\/oracle\/flash_recovery_area\/TEST1\/controlfile\/o1_mf_56lyofm4_.ctl\nFinished restore at 24-JUL-09\n\nRMAN> alter database mount;\nRMAN> sql \"alter database flashback off\";\n\nRMAN> catalog start with '\/home\/oracle\/backup';\n\nsearching for all files that match the pattern \/home\/oracle\/backup\n\nList of Files Unknown to the Database\n=====================================\nFile Name: \/home\/oracle\/backup\/0ukkuvok_1_1\nFile Name: \/home\/oracle\/backup\/0tkkuvob_1_1\n\nDo you really want to catalog the above files (enter YES or NO)? yes\ncataloging files...\ncataloging done\n\nList of Cataloged Files\n=======================\nFile Name: \/home\/oracle\/backup\/0ukkuvok_1_1\nFile Name: \/home\/oracle\/backup\/0tkkuvob_1_1\n\nRMAN> restore database;\n\nStarting restore at 24-JUL-09\n...\nFinished restore at 24-JUL-09\n\nRMAN> recover database;\n\nStarting recover at 24-JUL-09\nusing channel ORA_DISK_1\n\nstarting media recovery\nunable to find archive log\narchive log thread=1 sequence=51\nRMAN-00571: ===========================================================\nRMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============\nRMAN-00571: ===========================================================\nRMAN-03002: failure of recover command at 07\/24\/2009 17:09:50\nRMAN-06054: media recovery requesting unknown log: thread 1 seq 51 lowscn 360057\n<\/pre>\n<p>Recover database will fail at the end, but this is only because it didn&#8217;t find the current log. This doesn&#8217;t matter here.<\/p>\n<p>Test that media recovery process will start.<\/p>\n<pre>\nSQL> alter database recover managed standby database disconnect from session;\n\nDatabase altered.\n\nSQL> select process, status, sequence# from v$managed_standby where process like 'MRP%';\n\nPROCESS   STATUS        SEQUENCE#\n--------- ------------ ----------\nMRP0      WAIT_FOR_LOG         51\n\nSQL> alter database recover managed standby database cancel;\n\nDatabase altered.\n<\/pre>\n<p>If MRP* is started and waiting for log (and no error in alert.log), then everything is good.<\/p>\n<p>Set up flashback. Make sure that you have enough diskspace in FRA (flashback recovery area) for all flashback logs generated while the test database is open.<br \/>\nAfter flashback has been enabled, create a guaranteed restore point.<\/p>\n<pre>\nSQL> alter database flashback on;\n\nDatabase altered.\n\nSQL> create restore point prod_point guarantee flashback database;\n\nRestore point created.\n<\/pre>\n<p>Now, just activate standby database and open it.<\/p>\n<pre>\nSQL> alter database activate standby database;\nSQL> startup mount force\nSQL> alter database set standby database to maximize performance;\nSQL> alter database open;\n<\/pre>\n<p>Delete the backups from both databases. Just for cleaning up.<\/p>\n<pre>\nRMAN> delete backup tag 'testdb_init';\n<\/pre>\n<h3>Syncing with production<\/h3>\n<p>To make it more interesting, I&#8217;ll add some new datafiles to the primary database.<\/p>\n<pre>\nSQL> alter tablespace sysaux add datafile size 10m autoextend on next 10m maxsize 1g;\n\nTablespace altered.\n\nSQL> create tablespace test5891 datafile size 10m autoextend on next 10m maxsize 1g;\n\nTablespace created.\n<\/pre>\n<p>First, in test database find out the restore point SCN. This is the point from where to create the incremental backup.<\/p>\n<pre>\nSQL> select to_char(scn) from v$restore_point where name = 'PROD_POINT';\n\nTO_CHAR(SCN)\n---------------\n390703\n<\/pre>\n<p>Find out the current production database log sequence.<\/p>\n<pre>\nSQL> select sequence# from v$log where status = 'CURRENT';\n\n SEQUENCE#\n----------\n        57\n\nSQL> alter system checkpoint;\n<\/pre>\n<p>Create incremental backup from production and transport it to the test site. Also include all archived logs that were generated during backup.<\/p>\n<pre>\nRMAN> BACKUP INCREMENTAL FROM SCN=390703 device type disk format '\/home\/oracle\/backup\/%U'\n  as compressed backupset database INCLUDE CURRENT CONTROLFILE FOR STANDBY;\n\nRMAN> sql \"alter system archive log current\";\n\nRMAN> backup device type disk format '\/home\/oracle\/backup\/%U' as compressed backupset archivelog from sequence 57;\n<\/pre>\n<p>Close test database and flash it back to the restore point.<\/p>\n<pre>\nSQL> shutdown immediate\nSQL> startup mount\nSQL> flashback database to restore point PROD_POINT;\nSQL> drop restore point PROD_POINT;\nSQL> alter database flashback off;\nSQL> ALTER DATABASE CONVERT TO PHYSICAL STANDBY;\nSQL> startup mount force\n<\/pre>\n<p>Perform any cleanups, like added datafiles while the test database was open.<\/p>\n<p>Register backup and then apply the changes.<\/p>\n<pre>\nRMAN> catalog start with '\/home\/oracle\/backup';\n\nsearching for all files that match the pattern \/home\/oracle\/backup\n\nList of Files Unknown to the Database\n=====================================\nFile Name: \/home\/oracle\/backup\/13kl0v38_1_1\nFile Name: \/home\/oracle\/backup\/12kl0uuv_1_1\nFile Name: \/home\/oracle\/backup\/14kl0v87_1_1\n\nDo you really want to catalog the above files (enter YES or NO)? yes\ncataloging files...\ncataloging done\n\nList of Cataloged Files\n=======================\nFile Name: \/home\/oracle\/backup\/13kl0v38_1_1\nFile Name: \/home\/oracle\/backup\/12kl0uuv_1_1\nFile Name: \/home\/oracle\/backup\/14kl0v87_1_1\n\nRMAN> recover database;\n\nStarting recover at 25-JUL-09\nusing channel ORA_DISK_1\nchannel ORA_DISK_1: starting incremental datafile backupset restore\n...\n\nstarting media recovery\n\nchannel ORA_DISK_1: starting archive log restore to default destination\n...\nunable to find archive log\narchive log thread=1 sequence=59\nRMAN-00571: ===========================================================\nRMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============\nRMAN-00571: ===========================================================\nRMAN-03002: failure of recover command at 07\/25\/2009 12:10:43\nRMAN-06054: media recovery requesting unknown log: thread 1 seq 59 lowscn 391208\n<\/pre>\n<p>At the end, recover database will fail, because it cant find the current log, but it doesn&#8217;t matter here. Looking at the datafiles, RMAN has automatically created all newly added datafiles. That&#8217;s nice and easy.<\/p>\n<p>Now, I&#8217;ll check that standby database is working, create a new restore point and open the database.<\/p>\n<pre>\nSQL> alter database recover managed standby database disconnect from session;\n\nDatabase altered.\n\nSQL> select process, status, sequence# from v$managed_standby where process like 'MRP%';\n\nPROCESS   STATUS        SEQUENCE#\n--------- ------------ ----------\nMRP0      WAIT_FOR_LOG         59\n\nSQL> alter database recover managed standby database cancel;\n\nDatabase altered.\n\nSQL> alter database flashback on;\n\nDatabase altered.\n\nSQL> create restore point prod_point guarantee flashback database;\n\nRestore point created.\n\nSQL> alter database activate standby database;\n\nDatabase altered.\n\nSQL> startup mount force\nORACLE instance started.\n...\nDatabase mounted.\nSQL> alter database set standby database to maximize performance;\n\nDatabase altered.\n\nSQL> alter database open;\n\nDatabase altered.\n<\/pre>\n<p>That&#8217;s it. Pretty easy actually \ud83d\ude42<\/p>\n<p>So if you think this method can be useful to you, then try it out. I needed to work this out, because test database is on another continent from primary and physical standbys and the network link is pretty slow. Test database is open usually about a month so using incremental backups for refreshing is pretty much the only thing reasonable.<\/p>\n<p>Actually I use this method with backups taken from physical standby database, so in that case it&#8217;s not necessary to take the archivelogs also, just shut down media recovery process before starting the backup.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s common to use a production database copy for testing. But how to keep it fresh? If production database is large and located on a remote site (even on another country\/continent), then copying the full database backup over network may be too unreasonable and if the test database needs to be open for a longer [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[4],"class_list":["post-62","post","type-post","status-publish","format-standard","hentry","category-blog-entry","tag-oracle"],"_links":{"self":[{"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/posts\/62","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/comments?post=62"}],"version-history":[{"count":0,"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/posts\/62\/revisions"}],"wp:attachment":[{"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/media?parent=62"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/categories?post=62"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ilmarkerm.eu\/blog\/wp-json\/wp\/v2\/tags?post=62"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}