{"id":1137,"date":"2016-03-15T13:53:16","date_gmt":"2016-03-15T11:53:16","guid":{"rendered":"http:\/\/www.ludovicocaldara.net\/dba\/?p=1137"},"modified":"2020-08-18T16:26:26","modified_gmt":"2020-08-18T14:26:26","slug":"how-cold-incremental-recovery-saved-me-once","status":"publish","type":"post","link":"https:\/\/www.ludovicocaldara.net\/dba\/how-cold-incremental-recovery-saved-me-once\/","title":{"rendered":"How cold incremental recovery saved me once"},"content":{"rendered":"<p><strong>UPDATE: <\/strong>In the original version I was missing a few keywords: &#8220;incremental level 0&#8221; for the base backup and &#8220;resetlogs&#8221; at the database open. Thanks Gregorz for your comments.<\/p>\n<p>Sorry for this &#8220;memories&#8221; post, but the technical solution at the end is worth the read, I hope \ud83d\ude09<\/p>\n<p>Back in 2010, I was in charge of a quite complex project and faced some difficulties that led me to recover a database in a different manner. A few years have passed, but I used again the same procedure many times with full satisfaction&#8230; I think it&#8217;s worth to publish it now.<\/p>\n<p>But first, let me introduce the project details and the problem.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Scope of the project<\/strong><\/p>\n<p>Transport a &gt;1TB RAC database from AIX 5 on P6 to AIX 6 on P7, from a third-party datacenter in southern Italy to our main datacenter in northern Italy.<br \/>\nThe Database featured &gt;1000 datafiles and a huge table (800GB) partitioned by range and sub-partitioned by list (or the opposite, can&#8217;t remember).<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Challenges<\/strong><\/p>\n<p>For budget containement, the project owner asked to avoid the use of HACMP (and thus, avoid the use of shared JFS2). I decided\u00a0 then to take the risk and migrate from JFS2\u00a0 to ASM.<\/p>\n<p>In order to avoid a few platform-related ASM bugs, I also had to upgrade from Oracle 10.2.0.3 to Oracle 10.2.0.4.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Constraints<\/strong><\/p>\n<p>I had no access to the source database that was 800km far from our datacenter, and I was granted only to ask for RMAN backups.<\/p>\n<p>The total time of service disruption accepted was quite short (&lt;30 minutes) considering the size and the distance of the database, and there was no direct connectivity between the sites (for political reasons).<\/p>\n<p>Globally, the network throughput for sharing files over ftp was very poor.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>First solution<\/strong><\/p>\n<p>This kind of move was very common to me, and because I was not grated to ask for a temporary Data Guard configuration, the easy solution for me was to ask:<\/p>\n<p>1 &#8211; one RMAN ONLINE full backup physically sent on disk<\/p>\n<p>2 &#8211; many RMAN archive backups sent over network (via ftp)<\/p>\n<p>Then, on my side, restore the full backup, recover the archives sent over time and, at the date X, ask a final archive backup, ask to close the db and send the online redo logs to do a complete recovery on my side, then startup open upgrade.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Problem<\/strong><\/p>\n<p>I did a first &#8220;dry run&#8221; open resetlogs in order to test the procedure and make it faster, and also asked to test the application pointing to the destination database.<\/p>\n<p>The very bad surprise was that the source database was doing a huge amount of nologging inserts leading to monster index corruptions after the recovery on the destination database.<\/p>\n<pre class=\"lang:plsql decode:true \">ORA-26040: Data block was loaded using the NOLOGGING option\r\n\r\n<\/pre>\n<p>According to the current database maintainer, setting the force logging on the source database was NOT an option because the SAN was not able to cope with the high redo rates.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Solution<\/strong><\/p>\n<p>By knowing the Oracle recovery mechanisms, I have proposed to the remote maintainer to change the recovery strategy, despite this solution was not clearly stated in the Oracle documentation:<\/p>\n<p>1 &#8211; Take a first online incremental backup from the begin scn of\u00a0 the base full backup (thank God block change tracking was in place) and send it physically over disk<\/p>\n<p>2 &#8211; Take other smaller online\u00a0 incremental backups, send them over ftp\u00a0 and apply them on the destination with &#8220;noredo&#8221;<\/p>\n<p>3 &#8211; At the date X, shutdown the source, mount it and take a last incremental in mount state<\/p>\n<p>4 &#8211; recover noredo the last incremental and open resetlogs the database.<\/p>\n<p>According to the documentation, the &#8220;cold incremental strategy&#8221; applies if you take &#8220;cold full backups&#8221;. But from a technical point of view, taking a cold incremental and recovering it on top of a fuzzy online backup this is 100% equivalent of taking a full consistent backup in mount state.<br \/>\nBecause all the blocks are consistent to a specific SCN, there are no fuzzy datafiles:\u00a0 they are recovered from incremental taken from a mounted database! This allows to do incremental recovery and open the databases without applying any single archived log and by shutting down the database only once.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Technical steps<\/strong><\/p>\n<p>First, take a\u00a0 full ONLINE backup on the source:<\/p>\n<pre class=\"lang:plsql decode:true\">-- SOURCE\r\nSQL&gt; alter database backup controlfile to '\/tmp\/source\/ludo.cf' reuse;\r\n\r\nDatabase altered.\r\n\r\nSQL&gt; exit\r\n$ rman target \/\r\nRMAN&gt; backup incremental level 0 database as compressed backupset format '\/tmp\/source\/%U';<\/pre>\n<pre class=\"lang:sh decode:true\"># SOURCE\r\nscp -rp \/tmp\/source\/ destsrv:\/tmp\/dest\/\r\nludo.cf              100% |*************************************| 40944 KB    00:00\r\n...<\/pre>\n<p>Then restore it on the destination (with no recovery):<\/p>\n<pre class=\"lang:plsql decode:true \"># DEST\r\nRMAN&gt; restore controlfile from '\/tmp\/ludo.cf';\r\n\r\nStarting restore at 11-AUG-15\r\nusing target database control file instead of recovery catalog\r\nallocated channel: ORA_DISK_1\r\nchannel ORA_DISK_1: SID=1058 device type=DISK\r\n\r\nchannel ORA_DISK_1: copied control file copy\r\noutput file name=\/...\/control01.ctl\r\noutput file name=\/...\/control02.ctl\r\nFinished restore at 11-AUG-15\r\n\r\nRMAN&gt; alter database mount;\r\n\r\nStatement processed\r\nreleased channel: ORA_DISK_1\r\n\r\nRMAN&gt; catalog start with '\/tmp\/dest\/';\r\n...\r\nRMAN&gt; run\r\n2&gt; {\r\n3&gt; set newname for database to '+DATA';\r\n4&gt;\r\n5&gt; restore database;\r\n6&gt; }\r\n...\r\nFinished restore at 11-AUG-15\r\nRMAN&gt;\r\n<\/pre>\n<p>Then, run a COLD incremental backup on the source:<\/p>\n<pre class=\"lang:sh decode:true\">-- SOURCE\r\nSQL&gt; shutdown immediate;\r\n...\r\nORACLE instance shut down.\r\n\r\nSQL&gt; startup mount\r\nORACLE instance started.\r\n...\r\nDatabase mounted.\r\nSQL&gt; exit\r\n$ rman target \/\r\nRMAN&gt;  BACKUP AS COMPRESSED BACKUPSET INCREMENTAL LEVEL 1 \r\n2&gt; CUMULATIVE DATABASE format '\/tmp\/source\/incr%U';\r\n...\r\nFinished backup at 11-AUG-15\r\nRMAN&gt; exit\r\n$ scp -rp \/tmp\/source\/incr* destsrv:\/tmp\/dest\/<\/pre>\n<p>And run the incremental recovery on the source (without redo):<\/p>\n<pre class=\"lang:plsql decode:true\"># DEST\r\nRMAN&gt; catalog start with '\/tmp\/dest\/incr';\r\n...\r\nRMAN&gt; run {\r\n2&gt; recover database noredo;\r\n3&gt; }\r\n...\r\nchannel ORA_DISK_1: starting incremental datafile backup set restore\r\n...\r\nFinished recover at 11-AUG-15\r\nRMAN&gt; exit\r\n$ sqlplus \/ as sysdba\r\n...\r\nSQL&gt; alter database disable block change tracking;\r\nDatabase altered.\r\nSQL&gt; alter database flashback off;\r\nDatabase altered.\r\nSQL&gt; alter database flashback on;\r\nDatabase altered.\r\nSQL&gt; create restore point PREUPG guarantee flashback database;\r\nRestore point created.\r\nSQL&gt; -- open resetlogs can be avoided if I copy the online redo logs\r\nSQL&gt; alter database open resetlogs upgrade;\r\nDatabase altered.\r\n...\r\n-- run catupgrd here<\/pre>\n<p>That&#8217;s all!<\/p>\n<p>This solution gave me the opportunity to move physically the whole &gt;1TB nologging database from one region to another one with a minimal service disruption and without touching at all the source database.<\/p>\n<p>I used it many times later on, even for bigger databases and on several platforms (yes, also Windows, sigh), it works like a charm.<\/p>\n<p>HTH<\/p>\n<p>&#8212;<\/p>\n<p>Ludovico<\/p>\n","protected":false},"excerpt":{"rendered":"<p>UPDATE: In the original version I was missing a few keywords: &#8220;incremental level 0&#8221; for the base backup and &#8220;resetlogs&#8221; at the database open. Thanks Gregorz for your comments. Sorry for this &#8220;memories&#8221; post, but the technical solution at the &hellip; <a href=\"https:\/\/www.ludovicocaldara.net\/dba\/how-cold-incremental-recovery-saved-me-once\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[326,3,330],"tags":[263,260,259,262,265,261,264],"class_list":["post-1137","post","type-post","status-publish","format-standard","hentry","category-oracle","category-oracledb","category-oracle-inst-upg","tag-block-corruptions","tag-incremental-backup","tag-incremental-recovery","tag-nologging","tag-ora-26040","tag-recover-strategy","tag-vdatabase_block_corruption"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/posts\/1137","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/comments?post=1137"}],"version-history":[{"count":7,"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/posts\/1137\/revisions"}],"predecessor-version":[{"id":1323,"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/posts\/1137\/revisions\/1323"}],"wp:attachment":[{"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/media?parent=1137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/categories?post=1137"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ludovicocaldara.net\/dba\/wp-json\/wp\/v2\/tags?post=1137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}