crosscheck controlfilecopy all
Yeah right - you wish! There's no such thing my friend (not as of 10gR2 - 10.2.0.3.0 anyway), but I'll show you how you can do this yourself: First lets get the basis of this writeup out of the way. If you are here you've probably got a database with gazillion of binary backup controlfiles that were created via the following command: alter database backup controlfile to '/backup/ctl_bak_TODAY_DATE.ora'; Now you've implemented RMAN backup and you'd like to use the following command to delete obsolete backups: DELETE NOPROMPT OBSOLETE REDUNDANCY = 2; Here's the problem though ... this command fails with the following error: RMAN-06207: WARNING: 872 objects could not be deleted for DISK channel(s) due RMAN-06208: to mismatched status. Use CROSSCHECK command to fix status filling up your RMAN backup logfile with redundant error messages. You now want RMAN to forget about all these "old" backup controlfiles and you tried a CROSSCHECK command but realized that it doesn't support "all" keyword so you are now faced with an issue of doing a "crosscheck controlfilecopy "clt_name" for each and every file - quite a bit of manual labor. Well, Fear No Oracle buddy because I'll show you a quick and dirty trick that'll get you on your way to clean RMAN backups in no time. Follow along below: Here's the right command to CROSSCHECK a single CONTROLFILECOPY - this will be our template: RMAN> crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_07_21.backup.ctl"; using target database controlfile instead of recovery catalog allocated channel: ORA_DISK_1 channel ORA_DISK_1: sid=35 devtype=DISK validation failed for controlfile copy controlfile copy filename=/scratch/oradata/DBNAME/backups/2005_07_21.backup.ctl recid=25 stamp=564271666 Crosschecked 1 objects Lets start by creating a small shell script that'll give us a list of all missing Controlfile Copies: hostname.DBNAME-> cat 1.sh NLS_DATE_FORMAT='Mon-DD-YYYY HH24:MI:SS'; export NLS_DATE_FORMAT rman target / <<EOF ## delete old (redundant) backups ## ALLOCATE CHANNEL FOR MAINTENANCE DEVICE TYPE DISK; DELETE NOPROMPT OBSOLETE; RELEASE CHANNEL; exit EOF Now run 1.sh and save it's output in 1.log hostname.DBNAME-> ./1.sh > 1.log Here's what we are looking for in the 1.log hostname.DBNAME-> grep "Controlfile Copy" 1.log | head Controlfile Copy 2 Jun-15-2005 18:41:21 /scratch/oradata/DBNAME/backups/2005_06_15.backup.ctl Controlfile Copy 3 Jun-16-2005 22:07:40 /scratch/oradata/DBNAME/backups/2005_06_16.backup.ctl Controlfile Copy 4 Jun-17-2005 22:07:40 /scratch/oradata/DBNAME/backups/2005_06_17.backup.ctl Controlfile Copy 5 Jun-18-2005 22:07:40 /scratch/oradata/DBNAME/backups/2005_06_18.backup.ctl Controlfile Copy 6 Jun-19-2005 22:07:44 /scratch/oradata/DBNAME/backups/2005_06_19.backup.ctl Controlfile Copy 7 Jun-20-2005 22:07:38 /scratch/oradata/DBNAME/backups/2005_06_20.backup.ctl Controlfile Copy 8 Jun-21-2005 22:07:40 /scratch/oradata/DBNAME/backups/2005_06_21.backup.ctl Controlfile Copy 9 Jun-22-2005 22:07:40 /scratch/oradata/DBNAME/backups/2005_06_22.backup.ctl Controlfile Copy 10 Jun-23-2005 22:07:41 /scratch/oradata/DBNAME/backups/2005_06_23.backup.ctl Controlfile Copy 11 Jun-24-2005 22:07:40 /scratch/oradata/DBNAME/backups/2005_06_24.backup.ctl hostname.DBNAME-> Add a small AWK parse to match a template of a CROSSCHECK for a single CONTROLFILECOPY dumping all parsed output into clear_ctl.rman hostname.DBNAME-> grep "Controlfile Copy" 1.log | awk '{ print "crosscheck controlfilecopy \"" $6 "\";"}' > clear_ctl.rman hostname.DBNAME-> head clear_ctl.rman crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_15.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_16.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_17.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_18.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_19.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_20.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_21.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_22.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_23.backup.ctl"; crosscheck controlfilecopy "/scratch/oradata/DBNAME/backups/2005_06_24.backup.ctl"; hostname.DBNAME-> Run clear_ctl.rman.out hostname.DBNAME-> rman target / < clear_ctl.rman > clear_ctl.rman.out Verify output after it's done: hostname.DBNAME-> tail -14 clear_ctl.rman.out RMAN> released channel: ORA_DISK_1 allocated channel: ORA_DISK_1 channel ORA_DISK_1: sid=35 devtype=DISK validation failed for controlfile copy controlfile copy filename=/scratch/oradata/DBNAME/backups/2007_11_17.backup.ctl recid=874 stamp=638922083 Crosschecked 1 objects RMAN> Recovery Manager complete. hostname.DBNAME-> And finally re-run DELETE NOPROMPT OBSOLETE; (script 1.sh) Note how now RMAN is able to remove all of the missing ctl backups because they were properly crosschecked (See below) hostname.DBNAME-> ./1.sh ... ... ... deleted controlfile copy controlfile copy filename=/scratch/oradata/DBNAME/backups/2007_11_15.backup.ctl recid=872 stamp=638749280 deleted controlfile copy controlfile copy filename=/scratch/oradata/DBNAME/backups/2007_11_16.backup.ctl recid=873 stamp=638835768 deleted controlfile copy controlfile copy filename=/scratch/oradata/DBNAME/backups/2007_11_17.backup.ctl recid=874 stamp=638922083 Deleted 873 objects RMAN> released channel: ORA_MAINT_DISK_1 RMAN> RMAN> Recovery Manager complete. hostname.DBNAME-> And there you have it "crosscheck controlfilecopy all" ORACLE Angler way. Got a better way of doing this? Then what are you waiting for? Share it with us below!