Steve Rea's Oracle and SunGardHE Banner Tips, Tricks, and Scripts

Back to Home


RMAN Backups and Cloning

Contents:
    Backups Using RMAN (includes rmanbackup.shl and rmancrosscheck.shl scripts)
    Cleaning Out the RMAN Backup Directory and Archivelogs
    Cloning Using RMAN (includes rmanclone.shl script)
    Cloning Using RMAN on Windows
    Cloning Using RMAN across servers
    Restoring a Database from an RMAN Backup
    Creating a Data Guard Standby Database Using RMAN
    Recreating a Data Guard Standby Database Using RMAN
   
Creating a Local Data Guard Standby Database on Windows (added 5/30/10)

Backups Using RMAN

RMAN (Recovery Manager) is Oracle's backup and recovery tool, which is included with your Oracle database (8.0 and above).  You don't have to install anything to use it, and, there is very little, if anything, that you have to set up to get it going (although there are a lot of things you can configure when you get further into RMAN).  You do have to be logged into your oracle user ID on your UNIX server containing the database (we are on AIX 5.2 and 5.3 servers with Oracle 10.2.0.3 databases), and you do have to have your ORACLE_SID set to the database you want to work with (which RMAN calls the "target" database), but, other than that, you can do something as simple as the following to back up your database while it is running, assuming you are in ARCHIVELOG mode:

rman target /
backup database;
exit;

The above "backup database" command backs up your datafiles, control file, and server parameter file (if you have one, but not your init.ora file).  If you also want to back up your archive logs, you would change that command to "backup database plus archivelog;"  RMAN also lets you back up individual types of files separately, such as just the archivelogs, or your control file, or your server parameter file, or even individual tablespaces or datafiles.

The default directory that RMAN puts these backups into is $ORACLE_HOME/dbs in UNIX (or %ORACLE_HOME%/database in Windows, but, I'll just be using UNIX here).  You can tell RMAN to put them somewhere else that you can manage manually, or even set up a "Flash Recovery Area" (FRA) and let Oracle manage the backups and archivelogs for you (such as automatically deleting old backups).  And, you can set up a "Recovery Catalog" to contain RMAN backup information about all of your databases in one central location (which is in addition to this information being stored in the database's control file).  But, let's keep it simple for now, and use the default backup directory without a recovery catalog.  (See the end of "Creating a Data Guard Standby Database Using RMAN" on how to create an RMAN backup to a "different" Oracle Home that is defined on another server.)

The first time you try to do an RMAN backup of your archive logs, you will probably get "RMAN-06059: expected archived log not found, lost of archived log compromises recoverability" (yes, that is an Oracle spelling error - it says "lost" instead of "loss"!) and "ORA-19625: error identifying file ..." with the file name of one of your archive logs (and other messages with these).  This happens when you've deleted your old archive logs from disk, but, entries for them still exist in your database.  To tell RMAN to ignore those missing archive logs, you will run the following "crosscheck" command, and, after that, you can run the "backup database plus archivelog;" command again:

rman target /
crosscheck archivelog all;
exit;

If your database is in NOARCHIVELOG mode, you can restart it in the mount state and back it up:

rman target /
startup force mount
backup database;
alter database open;
exit;

Instead of trying to remember which databases we have on our system to back up, and whether they are in ARCHIVELOG mode or in NOARCHIVELOG mode, and which ones need to be shut down to make an RMAN backup, and what commands to enter to back up the datafiles and control files and server parameter files and archive logs, and how to tag those backups so that we know what's in them at a glance, why not just create a script to figure out all of this stuff for us?  And, while we're at it, let's have it back up whichever SID's we want at the time, or a predefined list of SID's, or even all SID's listed in the /etc/oratab file, and have it do either full backups or incremental backups either as we specify or based on the day of the week (incremental backups on weekdays, full backups on weekends).  Well, here it is:

Script: rmanbackup.shl

Performs an RMAN backup of the current database SID, or the given database SID's, or a pre-defined list of database SID's, or all of the SID's listed in /etc/oratab.  The backup can either be a full backup (incremental level=0) or an incremental (differential level=1) backup.  If no parameters are specified, a full backup of the current $ORACLE_SID is done.  Otherwise, the parameters consist of the list of SID's to be backed up and/or any of the following:

LIST - include the pre-defined list (bkup_list) of SID's.
ORATAB - include all SID's listed in the /etc/oratab file.
FULL - make a full backup of all of the SID's that are listed.
INCR - make an incremental (level=1) backup of all SID's listed.

If the type of backup is not specified, and no specific SID's are given (just LIST or ORATAB), an incremental backup is done Monday through Thursday or a full backup is done Friday through Sunday (assuming nightly backups).  The pre-defined list of SID's for the "LIST" backup is specified in the "bkup_list" variable shown below (edit the "export bkup_list" line in this script to match your environment):

export bkup_list='PROD PPRD TEST'

Databases that are currently down will not be backed up, since they must be at least in the mount state for RMAN to connect to them.  Databases in NOARCHIVELOG mode will be shut down and started back up in the mount state to do their backup.  Databases in ARCHIVELOG mode will be backed up online.  RMAN configuration settings (default device type, compression, parallelism, autobackup, etc.) are given in the rmanbackup.config file (rename rmanbackup.config.txt to rmanbackup.config after you download it - some browsers can't download ".config" files), which is run at the beginning of the RMAN backup session, for example (edit this configuration file to match your needs):

configure default device type to disk;
configure device type disk backup type to compressed backupset parallelism 2;
configure retention policy to recovery window of 35 days;
# configure controlfile autobackup on;

What those "configure" commands say is that I'm making a disk backup, that I am running two backups in parallel (Oracle decides which datafiles, etc., go into each backup file ("backup piece")) and am doing a compressed backup (which takes more time but saves a lot of disk space), and that I'm keeping the backups around for 35 days (5 weeks) in case I need to recover from them (after which time they are marked as "OBSOLETE" and subject to deletion).  Note in all of this that I haven't said anything about "channels", if you've heard the term in regards to RMAN.  That's because RMAN can allocate them behind the scenes for you, and you don't have to specify them.  For example, in the above configure commands, the "parallelism 2" value tells RMAN to allocate 2 channels for the backup.   (The "configure" commands and auto channel allocation are in Oracle 9i and above.)

Note:  In this backup script, I'm doing the datafile, archivelog, spfile, and controlfile backups separately so that I can add tags to them; otherwise, only the datafile backupset will be tagged.  This also lets me archive the current log file after the datafile backups to get the most current set of archive logs.  Also note that this script deletes archivelogs more than a week old which have been backed up at least 5 times.  Delete that line ("delete noprompt archivelog ...") or change it as desired in this script to match your needs.  (Note: I'm not using "delete obsolete" to delete the backups, because "report obsolete" shows additional files that I don't want deleted, including server parameter file backups done recently within the retention policy window.  Also, I removed the deletion of backups older than 36 days (the retention policy) from the script because the deletion command ignored the "keep" settings for the backups.)   If you delete any of the archive logs or backup files using an O/S command, be sure to run rmancrosscheck.shl (below) before you run an RMAN backup.

Examples:
    To make a full backup of the current $ORACLE_SID:
        rmanbackup.shl
        rmanbackup.shl full
    To make an incremental backup of the current $ORACLE_SID:
        rmanbackup.shl incr
    To make a full backup of a given database SID, such as PROD:
        rmanbackup.shl prod
        rmanbackup.shl prod full
    To make an incremental backup of a given database SID, such as PROD:
        rmanbackup.shl prod incr
    To make a full backup of the pre-defined list (bkup_list) of SID's:
        rmanbackup.shl list full
    To make an incremental backup of the pre-defined list of SID's:
        rmanbackup.shl list incr
    To make a full or incremental backup of the pre-defined list of SID's based on the current day of the week:
        rmanbackup.shl list
    To make a full backup of PROD and PREP:
        rmanbackup.shl prod prep full
    To make a full backup of the pre-defined list of SID's, plus SEED
        rmanbackup.shl list seed full
    To make a full backup of the SID's listed in /etc/oratab:
        rmanbackup.shl oratab full
    To make a full or incremental backup of the /etc/oratab SID's based on the current day of the week:
        rmanbackup.shl oratab

Pretty cool, huh?  OK, now that we have a full RMAN backup, what can we do with it?  Well, besides recovering the database in case of a hardware crash or file corruption or someone accidentally (or on purpose) deleting data or even the datafiles themselves or other disasters that you may encounter (which we will discuss later on), how about things like cloning the production database to create a test database, or using the backup to create a standby database for your production database on another site?  RMAN can do this for you.

Script: rmancrosscheck.shl

Performs a crosscheck on all control files, RMAN backups, and archivelogs for all of the active databases on this server so that any of them that were manually deleted (through an O/S command) don't cause any errors in the RMAN backups. This should be run before the rmanbackup.shl script.

Usage:
    rmancrosscheck.shl

Cleaning Out the RMAN Backup Directory and Archivelogs

You need to monitor the directory that you store the RMAN backups in (which is usually $ORACLE_HOME/dbs on UNIX systems) to make sure that you don't fill up the drive.  Below is how I monitor our /pgms directory, which contains the RMAN backups, and how to delete the old backups there.  Be sure to run rmancrosscheck.shl (above) after you delete any RMAN backups for your databases.

See how much free space (the %Used column) is in the /pgms directory (which contains the RMAN backups):
    login oracle
    df -k | egrep '(pgms|used)'
If this shows /pgms is over 90% used, remove RMAN backups older than 10 days:
First, list what will be deleted (this should only include files with names like PROD_r2ke8s6m_1_1_dbf):
    cd $ORACLE_HOME/dbs
    find . \( -name '*_1_1' -o -name '*_1_1_dbf' -o -name '*_1_1_spf' -o -name '*_1_1_ctl' -o -name '*_1_1_arc' \) -mtime +10 -exec ls -ltr {} \;
To delete all those listed above:
    find . \( -name '*_1_1' -o -name '*_1_1_dbf' -o -name '*_1_1_spf' -o -name '*_1_1_ctl' -o -name '*_1_1_arc' \) -mtime +10 -exec rm {} \;
Or, exclude some files to delete, such as not deleting files in subdirectories (grep -v '^...*/'):
    find . \( -name '*_1_1' -o -name '*_1_1_dbf' -o -name '*_1_1_spf' -o -name '*_1_1_ctl' -o -name '*_1_1_arc' \) -mtime +10 | grep -v '^...*/' | sed 's/^/rm /' | sh
See the resulting free space in /pgms:
    df -k | egrep '(pgms|used)'

Also, you need to monitor the archivelogs directories for all of your databases on your server, and delete any old archivelogs if they are about to fill up your drive.  Below is how I monitor our /orcl directory, which contains the archivelogs for all of the databases.  Be sure to run rmancrosscheck.shl (above) after you delete any of the archive logs for your databases.

See how much free space is in the /orcl directory (which contains the archivelogs):
    login oracle
    df -k | egrep '(orcl|used)'
Find what archivelog directories are on this server, and how many archivelog files are in them:
    find /orcl/oradata -name archivelogs | sed 's/.*/echo & `ls & \| wc -l`/' | sh
If the /orcl directory fills up, the databases will stop until some room is freed up on /orcl for those archivelogs (users may get the error message: "ORA-00257: archiver error. Connect internal only, until freed.").  The remove_old_logs.shl script in each of the archivelogs directories (such as in /orcl/oradata/PROD/archivelogs) will remove archivelogs older than the given number of days (be sure to change to the appropriate archivelogs directory before running the script).  Below is an example of removing all but the last 4 days of archivelogs for the PROD database:
    cd /orcl/oradata/PROD/archivelogs
    ls -ltr
    remove_old_logs.shl
        4
The script below will generate and execute the above commands for all databases with more than 10 archivelog files:
    find /orcl/oradata -name archivelogs | sed 's/.*/echo & `ls & \| wc -l`/' | sh |
        sed 's/\(.*\) \(.*\)/if [ \2 -gt 10 ]; then~cd \1~ls -ltr~remove_old_logs.shl <<EOF~4~EOF~fi/' |
        tr '~' '\n' | sh
See the results from the deletions:
    find /orcl/oradata -name archivelogs | sed 's/.*/echo & `ls & \| wc -l`/' | sh
    df -k | egrep '(orcl|ndxs|used)'

NOTE: After removing backups and/or archivelogs and before doing another RMAN backup, run rmancrosscheck.shl (above) to tell RMAN that those files are no longer available. This script is also scheduled to run right before the nightly RMAN backups on our database servers.

Cloning Using RMAN

To clone a database, RMAN not only needs to connect to the database being cloned, such as your production database (PROD), but also to the database being created, such as your test database (TEST) (which RMAN calls the "auxiliary" database).  But, wait a minute!  If the test database hasn't been created, how do I connect to it?!  Actually, the test database just needs to be in the nomount state, which means that just a parameter file (init<SID>.ora file) or a server parameter file (spfile<SID>.ora) needs to exist in the $ORACLE_HOME/dbs directory for the test database.  Also, an entry for the test database must exist in the /etc/oratab file.  Finally, for RMAN to connect to the databases, entries for them must exist in the $ORACLE_HOME/network/admin/tnsnames.ora file.

But, we have to take care of one other detail.  We've copied the initPROD.ora file to the initTEST.ora file and changed the locations of the control files, the dump, audit, and archivelog directories, and the db_name parameter, for the test database in initTEST.ora; but, the datafile and archivelog names for the test database also have to be different than the production database.  Well, that's where the init.ora parameters db_file_name_convert and log_file_name_convert come into play (if you've created a standby database, you'll recognize these parameters).  If you define those in the initTEST.ora file as shown below, RMAN will change all occurrences of "PROD" in the datafile and log file names to "TEST" for the clone:

db_file_name_convert=('PROD','TEST')
log_file_name_convert=('PROD','TEST')

Then, after starting up the test database in nomount mode, you can do something as simple as the following to clone your production database while it is running:

rman target / auxiliary sys/<test_sys_password>@myserver_test
duplicate target database to TEST;
exit

If you've already cloned to TEST before, you will need to delete the TEST database's files before you do the clone again.  RMAN can do that for you, too, using the "drop database including backups;" command when the TEST database is in a mount state.  But, make sure you are dropping TEST, not PROD!  Note that this will also delete your server parameter file for TEST, so, if you are using spfile's, you will need to create a parameter file (initTEST.ora) before dropping TEST, and then recreate the server parameter file after the drop.

OK, that's a lot to remember and check as well.  So, here we go with another script, which checks to make sure that the /etc/oratab entries exist, that the parameter files exist, and that the tnsnames.ora entries exist, then, it creates a pfile from the spfile if one exists, drops the clone database if it exists (Oracle 10g), creates a new spfile and sets up the file_name_convert parameters, and runs the duplicate command.  And, to top it off, for the Banner folks, it also updates the gubinst fields to reflect the clone and date.  Here it is:

Script: rmanclone.shl

Performs an RMAN clone of one database SID to another database SID up to an optional point-in-time or up to the current point-in-time.  The RMAN database backup(s) of the source SID must be available on-line, as well as sufficient archive logs to recover up to the desired point-in-time.

Usage:
    rmanclone.shl <from SID> <to SID> <MM/DD/YY:HH/MI/SS>
where the "as of" date and time is optional (default is now).

Prerequisites: The target SID's init.ora file or spfile.ora file must already exist. The target SID's init.ora file, if any, is saved off, and an spfile is created for the target.  Also, the connect string for the source and the target is assumed to be in the form of "<server>_<sid>", such as myserver_prod and myserver_test (edit the "export rman_server=myserver" line in this script to match your environment), and those source and target entries must exist in the $ORACLE_HOME/network/admin/tnsnames.ora file.  The source and target SID's must also be in the /etc/oratab file.  And, you have to be logged into the oracle user ID on your UNIX database server.

Examples:
    To clone PROD to TEST as of now:
        rmanclone.shl PROD TEST
    To clone PROD to TEST as of midnight:
        rmanclone.shl PROD TEST `date +"%D:00:00:00"`

Cloning Using RMAN on Windows

For those of you with Oracle databases on Windows, I don't have any Windows batch scripts, but, below is what I did to clone a Windows database (from PROD to TEST) using RMAN.  You will need to change the names and values (such as myserver, myschool, syspassword), along with the pathnames (such as d:\oracle\v9206, which is my ORACLE_HOME) to match your environment.  This was on Oracle 9.2.0.6.  Note that 9.2.0.6 doesn't have a "backup type to compressed backupset" option on its "configure device type disk" command.  The commands below are run in an MS/DOS command prompt window.

Create the parameter file (initTEST.ora) for the test clone database (TEST) from a copy of PROD's parameter file:
    copy d:\oracle\v9206\database\initPROD.ora d:\oracle\v9206\database\initTEST.ora
    Edit d:\oracle\v9206\database\initTEST.ora
        change all occurrences of PROD to TEST

Add the myserver_test connect string to d:\oracle\v9206\network\admin\tnsnames.ora:
    myserver_test =
        (DESCRIPTION =
            (ADDRESS_LIST =
                (ADDRESS = (PROTOCOL = TCP)(Host = myserver.myschool.edu)(Port = 1521))
            )
            (CONNECT_DATA = (SID = test)
            )
        )

Add entries for PROD (if needed) and TEST to the SID_LIST section of d:\oracle\v9206\network\admin\listener.ora:
    SID_LIST_LISTENER=
        (SID_LIST=
            (SID_DESC=
                (SID_NAME=PROD)
                (ORACLE_HOME = d:\oracle\v9206)
            )
            (SID_DESC=
                (SID_NAME=TEST)
                (ORACLE_HOME = d:\oracle\v9206)
            )
        )

Reload the listener to pick up the above additions:
    set oracle_home=d:\oracle\v9206
    set oracle_sid=prod
    lsnrctl reload

Create the directories for the TEST database:
    sqlplus "sys/<syspassword> as sysdba"
        set heading off echo off feedback off trimspool on
        select distinct 'mkdir ' || replace(substr(file_name,1,
            instr(file_name,'\',-1)-1),'PROD','TEST')
            from dba_data_files
        union
        select distinct 'mkdir ' || replace(substr(file_name,1,
            instr(file_name,'\',-1)-1),'PROD','TEST')
            from dba_temp_files
        union
        select distinct 'mkdir ' || replace(value,'PROD','TEST')
            from v$parameter where name in ('background_dump_dest','user_dump_dest',
            'core_dump_dest','audit_file_dest','log_archive_dest')
            and value is not null
        union
        select distinct 'mkdir ' || replace(substr(substr(value,instr(value,'LOCATION=')+9),1,
            instr(substr(value,instr(value,'LOCATION=')+9),' ')-1),'PROD','TEST')
            from v$parameter where name between 'log_archive_dest_1' and
            'log_archive_dest_10' and instr(value,'LOCATION=') > 0;
        exit
Run the resulting mkdir commands from the above SQL:
    mkdir D:\ORADATA\TEST
    mkdir c:\oradata\TEST\archivelogs
    mkdir d:\oradata\TEST\bdump
    mkdir d:\oradata\TEST\cdump
    mkdir d:\oradata\TEST\udump

Create the NT services for the TEST Oracle instance using oradim:
    set oracle_sid=test
    oradim -new -sid test -intpwd <syspassword> -startmode auto -pfile d:\oracle\v9206\database\initTEST.ora

Create a server parameter file for TEST and add the file_name_convert parameters for the cloning process:
    sqlplus "sys/<syspassword> as sysdba"
        startup force nomount
        create spfile from pfile;
        startup force nomount
        alter system set db_file_name_convert='PROD','TEST' scope=spfile;
        alter system set log_file_name_convert='PROD','TEST' scope=spfile;
        shutdown
        exit
    oradim -delete -sid test
    del d:\oracle\v9206\database\pwdtest.ora
    move d:\oracle\v9206\database\initTEST.ora d:\oracle\v9206\database\initTEST.ora.save
    oradim -new -sid test -intpwd <syspassword> -startmode auto -spfile
    sqlplus "sys/<syspassword> as sysdba"
        startup nomount
        column name format a25
        column value format a50
        select name,value from v$parameter where name like '%file_name_convert';
        exit

Create an RMAN backup of the PROD database and clone it to TEST:
    set oracle_sid=prod
    rman target sys/<syspassword>@myserver_prod auxiliary sys/<syspassword>@myserver_test
        configure default device type to disk;
        configure device type disk parallelism 2;
        configure retention policy to recovery window of 35 days;
        crosscheck archivelog all;
        backup database plus archivelog;
        duplicate target database to TEST;
        exit

Create an RMAN backup of the new TEST database:
    set oracle_sid=test
    rman target sys/<syspassword>@myserver_test
        configure default device type to disk;
        configure device type disk parallelism 2;
        configure retention policy to recovery window of 35 days;
        backup database plus archivelog;
        exit

Cloning Using RMAN across servers

If you want to create a clone of one database on one server to another server using RMAN, you will have to copy or FTP the RMAN backup files from the original database server to the new database server.  Unfortunately, RMAN can't access backup files on another server, even though it can connect to a database on another server.  You could use the same procedure to copy a database from one server to another (just leave out changing the SID names and file names). This should be faster than export/import. Below are my notes on how I did this, when I created a clone of PROD on PrimaryServer to XXXX on StandbyServer.  This was done on 5/4/09 at 22:42:56 - you will have to change the dates here to your values. Note that this assumes that the directory structure on StandbyServer is the same as the directory structure on PrimaryServer.

THESE STEPS ARE DONE ON PrimaryServer:

Create a full backup of PROD, which will have to be FTP'ed to StandbyServer:
    login oracle
        PROD
    rmanbackup.shl PROD full

Create the clone's init.ora file from PROD (note: if you had already created a clone earlier, and you are just re-creating the clone now, some of these steps that you've already done can be left out):
    cd $ORACLE_HOME/dbs
    sqlplus "/ as sysdba"
        create pfile='initXXXX.ora' from spfile;
        exit
    vi initXXXX.ora
        :1,$s/PROD/XXXX/g
        :wq

Get the list of backup files from today to FTP to StandbyServer:
    find $ORACLE_HOME/dbs \( -name '*_1_1' -o -name '*_1_1_dbf' -o -name '*_1_1_spf' -o -name '*_1_1_ctl' -o -name '*_1_1_arc' \) |
        sed 's/^/ls -ltr /' | sh | grep ' May 04 22' | grep PROD | sed 's/.\{58\}/get /'
        shows:
            get /pgms/oracle/product/v10203/dbs/PROD_qeke7d00_1_1_dbf
            get /pgms/oracle/product/v10203/dbs/PROD_qdke7d00_1_1_dbf
            get /pgms/oracle/product/v10203/dbs/PROD_qfke7d9k_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_qgke7d9m_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_qhke7dd8_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_qjke7de6_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_qike7de6_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_qkke7dem_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_qlke7den_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_qnke7df6_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_qmke7df6_1_1_spf
            get /pgms/oracle/product/v10203/dbs/PROD_qoke7dfl_1_1_ctl

Generate the commands to remove and create the directories for the XXXX database (the remove commands are used in the case where an XXXX database had been created before):
    sqlplus "/ as sysdba"
        set heading off feedback off
        spool makedirs.shl
        select distinct ' rm -r ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_data_files
        union
        select distinct ' rm -r ' || substr(substr(value,instr(value,'LOCATION=')+9),1,
            instr(substr(value,instr(value,'LOCATION=')+9),' ')-13)
            from v$parameter where name between 'log_archive_dest_1' and
            'log_archive_dest_10' and instr(value,'LOCATION=') > 0
        union
        select distinct ' rm -r ' || substr(value,1,instr(value,'/',-1)-1) from v$parameter
            where name in ('background_dump_dest','user_dump_dest','core_dump_dest',
            'audit_file_dest','log_archive_dest')
            and value is not null
        union
        select distinct 'mkdir -p ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_data_files
        union
        select distinct 'mkdir -p ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_temp_files
        union
        select distinct 'mkdir -p ' || value from v$parameter
            where name in ('background_dump_dest','user_dump_dest','core_dump_dest',
            'audit_file_dest','log_archive_dest')
            and value is not null
        union
        select distinct 'mkdir -p ' || substr(substr(value,instr(value,'LOCATION=')+9),1,
            instr(substr(value,instr(value,'LOCATION=')+9),' ')-1)
            from v$parameter where name between 'log_archive_dest_1' and
            'log_archive_dest_10' and instr(value,'LOCATION=') > 0;
        spool off
        exit
    vi makedirs.shl
        :1,$s/PROD/XXXX/g
        :wq
    cat makedirs.shl
        shows (along with the SQL above, which can be deleted from makedirs.shl):
            rm -r /data/oradata/XXXX
            rm -r /ndxs/oradata/XXXX
            rm -r /orcl/oradata/XXXX
            rm -r /pgms/oradata/XXXX
            mkdir -p /data/oradata/XXXX
            mkdir -p /ndxs/oradata/XXXX
            mkdir -p /orcl/oradata/XXXX/archivelogs
            mkdir -p /pgms/oradata/XXXX/audit
            mkdir -p /pgms/oradata/XXXX/bdump
            mkdir -p /pgms/oradata/XXXX/cdump
            mkdir -p /pgms/oradata/XXXX/udump

THESE STEPS ARE DONE ON StandbyServer:

Add the clone's entry to the oratab file on StandbyServer:
    login oracle
        XXXX
    vi /etc/oratab
        add: XXXX:/pgms/oracle/product/v10203:N
        :wq

Add the clone's entry to the tnsnames file:
    vi $ORACLE_HOME/network/admin/tnsnames.ora
        add:
            StandbyServer_xxxx =
                (DESCRIPTION =
                    (ADDRESS_LIST =
                        (ADDRESS =
                            (PROTOCOL = TCP)
                            (Host = StandbyServer.uaex.edu)
                            (Port = 1521)
                        )
                    )
                    (CONNECT_DATA = (SID = XXXX)
                    )
                )

Add the clone's entry to the listener.ora file:
    vi $ORACLE_HOME/network/admin/listener.ora
        add:
            (SID_DESC=
                (SID_NAME=XXXX)
                (ORACLE_HOME=/pgms/oracle/product/v10203)
            )
        :wq
Then, reload the listener:
    lsnrctl reload

FTP the init.ora file, makedirs.shl file, and the backup files from PrimaryServer to StandbyServer:
    cd $ORACLE_HOME/dbs
    ftp PrimaryServer.uaex.edu
            oracle
        type ascii
        get /pgms/oracle/product/v10203/dbs/initXXXX.ora
        get /pgms/oracle/product/v10203/dbs/makedirs.shl
        type binary
        get /pgms/oracle/product/v10203/dbs/PROD_qeke7d00_1_1_dbf
        get /pgms/oracle/product/v10203/dbs/PROD_qdke7d00_1_1_dbf
        get /pgms/oracle/product/v10203/dbs/PROD_qfke7d9k_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_qgke7d9m_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_qhke7dd8_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_qjke7de6_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_qike7de6_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_qkke7dem_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_qlke7den_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_qnke7df6_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_qmke7df6_1_1_spf
        get /pgms/oracle/product/v10203/dbs/PROD_qoke7dfl_1_1_ctl
        bye

Delete and recreate the directories for the new XXXX database on StandbyServer.  Also, save off and restore the remove_old_logs.shl and fillup.shl scripts if they exist in the archivelogs directory (these are some local scripts that I use - you may have other scripts in your archivelogs directory that you want to preserve a copy of):
    cp -p /orcl/oradata/${ORACLE_SID}/archivelogs/remove_old_logs.shl /home/oracle/remove_old_logs.${ORACLE_SID}.shl
    cp -p /orcl/oradata/${ORACLE_SID}/archivelogs/fillup.shl /home/oracle/fillup.${ORACLE_SID}.shl
    sh $ORACLE_HOME/dbs/makedirs.shl
    cp -p /home/oracle/remove_old_logs.${ORACLE_SID}.shl /orcl/oradata/${ORACLE_SID}/archivelogs/remove_old_logs.shl
    cp -p /home/oracle/fillup.${ORACLE_SID}.shl /orcl/oradata/${ORACLE_SID}/archivelogs/fillup.shl

Create the password file for the new XXXX database:
    rm $ORACLE_HOME/dbs/orapwXXXX
    orapwd file=$ORACLE_HOME/dbs/orapwXXXX password=<sys password> entries=5

Find the date and time to duplicate up to:
    export NLS_DATE_FORMAT='DD-MON-YY HH24:MI:SS'
    rman target sys/<syspassword>@PrimaryServer_prod
        list backup summary completed after "to_date('05/04/09','MM/DD/YY')";
            shows that the last full backup backup file (PROD_090504224256MONFULL_CTL) completed on 04-MAY-09 at 22:48:23
    exit

Clone the PROD database to XXXX as of 05/04/09 22:49:00. Note that the "target" database is PrimaryServer_prod on PrimaryServer, even though the RMAN backup files are on StandbyServer.
    sqlplus "/ as sysdba"
        startup nomount
        exit
    rman target sys/<syspassword>@PrimaryServer_prod auxiliary sys/<syspassword>@StandbyServer_xxxx <<EOF
        run
            {
                set until time = "to_date('05/04/09:22:49:00','MM/DD/YY:HH24:MI:SS')";
                duplicate target database to XXXX;
            }
        exit
EOF

Update the gubinst fields to reflect the clone name and date (this is only for Banner databases - if you had any other post-cloning changes, you would do them here):
    sqlplus "/ as sysdba"
        update gubinst set (gubinst_instance_name,gubinst_name) =
            (select name || to_char(sysdate,'MMDD'),name || ' was cloned on ' ||
                to_char(sysdate,'MM/DD/YY') from v$database);
        select gubinst_instance_name,gubinst_name from gubinst;
        exit

Restoring a Database from an RMAN Backup

This is how we restored TEST from last Friday's (6/19/2009) full backup. The development database server crashed on Wednesday morning, corrupting the /ndxs files.
        login root
        cd /pgms/oracle/product/v10203/dbs

Mount the backup tape contining the RMAN backup files to restore (from full backup done on June 19) here, and restore the June 19 TEST RMAN backup files.
        cpio -itvC64 </dev/rmt0 | grep 'Jun 19 .*TEST.*_1_1_' |
                sed 's/.*\/pgms/\/pgms/' >xyz
        cpio -imvC64 `cat xyz | tr '\n' ' '` </dev/rmt0
        cd $ORACLE_HOME/dbs
        ls -ltr | grep TEST | grep 'Jun 19'
                shows:
                        -rw-r----- 1 oracle dba 900452352 Jun 19 00:38 TEST_2rkhu7hp_1_1_dbf
                        -rw-r----- 1 oracle dba 1605632 Jun 19 00:38 TEST_2tkhu8k1_1_1_dbf
                        -rw-r----- 1 oracle dba 98304 Jun 19 00:38 TEST_2ukhu8k5_1_1_dbf
                        -rw-r----- 1 oracle dba 994357248 Jun 19 00:38 TEST_2skhu7hp_1_1_dbf
                        -rw-r----- 1 oracle dba 80832512 Jun 19 00:40 TEST_30khu8ku_1_1_arc
                        -rw-r----- 1 oracle dba 80167936 Jun 19 00:40 TEST_2vkhu8ku_1_1_arc
                        -rw-r----- 1 oracle dba 77558784 Jun 19 00:41 TEST_31khu8nv_1_1_arc
                        -rw-r----- 1 oracle dba 98304 Jun 19 00:41 TEST_32khu8pe_1_1_spf
                        -rw-r----- 1 oracle dba 1605632 Jun 19 00:41 TEST_33khu8pg_1_1_ctl

Shut down the existing TEST database.
        login oracle
                TEST
        sqlplus "/ as sysdba"
                shutdown abort
                exit

Delete and recreate the directories for the TEST database on AIX. Also, save off and restore the remove_old_logs.shl and fillup.shl scripts if they exist in the archivelogs directory (these are some local scripts that I use - you may have other scripts in your archivelogs directory that you want to preserve a copy of):
        cp -p /orcl/oradata/${ORACLE_SID}/archivelogs/remove_old_logs.shl /home/oracle/remove_old_logs.${ORACLE_SID}.shl
        cp -p /orcl/oradata/${ORACLE_SID}/archivelogs/fillup.shl /home/oracle/fillup.${ORACLE_SID}.shl
        rm -r /data/oradata/TEST
        rm -r /ndxs/oradata/TEST
        rm -r /orcl/oradata/TEST
        rm -r /pgms/oradata/TEST
        mkdir -p /data/oradata/TEST
        mkdir -p /ndxs/oradata/TEST
        mkdir -p /orcl/oradata/TEST/archivelogs
        mkdir -p /pgms/oradata/TEST/audit
        mkdir -p /pgms/oradata/TEST/bdump
        mkdir -p /pgms/oradata/TEST/cdump
        mkdir -p /pgms/oradata/TEST/udump
        cp -p /home/oracle/remove_old_logs.${ORACLE_SID}.shl /orcl/oradata/${ORACLE_SID}/archivelogs/remove_old_logs.shl
        cp -p /home/oracle/fillup.${ORACLE_SID}.shl /orcl/oradata/${ORACLE_SID}/archivelogs/fillup.shl

Restore the control file (the one produced by my rmanbackup.shl script) with a "_ctl" suffix and an end date of June 19. Also restore the archivelogs created during the backup. Then, restore the database up to June 19 at 12:41:21 AM.
        rman target /
                startup force nomount
                restore controlfile from 'TEST_33khu8pg_1_1_ctl';
                startup force mount
                spool log to listbackupset.lst
                list backupset;
                spool log off
                host "grep ' *[0-9][0-9]* *19-JUN-09$' listbackupset.lst";
                        shows:
                                1 3898 400381508 18-JUN-09 400382628 19-JUN-09
                                1 3899 400382628 19-JUN-09 400384018 19-JUN-09
                                1 3900 400384018 19-JUN-09 400384253 19-JUN-09
                                1 3901 400384253 19-JUN-09 400384260 19-JUN-09
                restore archivelog from scn=400381508 until scn=400384260;
                restore database until time "to_date('06/19/09:00:41:21','MM/DD/YY:HH24:MI:SS')";
                        The date and time is when the control file backup finished on June 19
                        (as shown in the restored TEST_33khu8pg_1_1_ctl file above).
                exit

Recover the database and open it with the resetlogs option (you should probably make a full backup of the restored database after this).
        sqlplus "/ as sysdba"
                startup force mount
                recover automatic database until cancel using backup controlfile;
                        CANCEL
                startup force mount
                alter database open resetlogs;
                exit

Creating a Data Guard Standby Database Using RMAN

Creating a Data Guard standby database on StandbyServer for the primary PROD database on PrimaryServer using RMAN is similar to cloning using RMAN across servers.  Below are my notes on how I did this for our production database.  Note that this assumes that the directory structure on StandbyServer is the same as the directory structure on PrimaryServer (but, see at the end on how to deal with differing Oracle Homes on the two servers).

THESE STEPS ARE DONE ON PrimaryServer:

Add the new StandbyServer standby database entry to $ORACLE_HOME/network/admin/tnsnames.ora on PrimaryServer (note: if you had already created a standby earlier, and you are just re-creating the standby now, some of these steps that you've already done can be left out):
    login oracle
        PROD
    vi $ORACLE_HOME/network/admin/tnsnames.ora
        add to bottom of tnsnames.ora file:
            StandbyServer_prod =
                (DESCRIPTION =
                    (ADDRESS_LIST =
                        (ADDRESS =
                            (PROTOCOL = TCP)
                            (Host = StandbyServer.uaex.edu)
                            (Port = 1521)
                        )
                    )
                (CONNECT_DATA = (SID = PROD)
                )
            )
        :wq

Create a full backup of PROD, which will have to be FTP'ed to StandbyServer:
    rmanbackup.shl PROD full

If you don't already have an spfile.ora for PROD, create the primary's and standby's spfile.ora file from PROD (don't do this if you already have an spfile - you may wipe it out!):
    cd $ORACLE_HOME/dbs
    sqlplus "/ as sysdba"
        create spfile from pfile;
        shutdown
        startup
        exit

Make a copy of the primary's spfile.ora to FTP to the standby site:
    cp -p spfilePROD.ora spfilePROD.ora.standby

Add the parameters for the Data Guard settings to the primary PROD database's spfile.ora file:
    sqlplus "/ as sysdba"
        alter system set db_unique_name = 'PROD_primary' scope=spfile;
        alter system set log_archive_config = 'DG_CONFIG=(PROD_primary,PROD_standby)' scope=spfile;
        alter system set log_archive_dest_1 = 'LOCATION=/orcl/oradata/PROD/archivelogs MANDATORY VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=PROD_primary' scope=spfile;
        alter system set log_archive_dest_state_1 = ENABLE scope=spfile;
        alter system set log_archive_dest_2 = 'SERVICE=StandbyServer_prod LGWR SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=PROD_standby' scope=spfile;
        alter system set log_archive_dest_state_2 = ENABLE scope=spfile;
        alter system set standby_archive_dest = /orcl/oradata/PROD/archivelogs scope=spfile;
        alter system set standby_file_management = AUTO scope=spfile;
        alter system set fal_server = StandbyServer_prod scope=spfile;
        alter system set fal_client = PrimaryServer_prod scope=spfile;
        exit

Create the standby's control file from PROD:
    rman target /
        backup current controlfile for standby;
            shows the following file ("piece handle") was created:
                /pgms/oracle/product/v10203/dbs/cikh4u15_1_1
        exit

Get the list of backup files from today to FTP to StandbyServer:
    find $ORACLE_HOME/dbs \( -name '*_1_1' -o -name '*_1_1_dbf' -o -name '*_1_1_spf' -o -name '*_1_1_ctl' -o -name '*_1_1_arc' \) |
        sed 's/^/ls -ltr /' | sh | grep ' Jun 08 20' | grep PROD | sed 's/.\{58\}/get /'
        shows:
            get /pgms/oracle/product/v10203/dbs/PROD_bfkh3fko_1_1_dbf
            get /pgms/oracle/product/v10203/dbs/PROD_bekh3fko_1_1_dbf
            get /pgms/oracle/product/v10203/dbs/PROD_bgkh3fue_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bhkh3fue_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bikh3fuu_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bjkh3fuu_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bkkh3fvd_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_blkh3fve_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bmkh3fvt_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bnkh3fvt_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bokh3g0c_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bpkh3g0c_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bqkh3g0s_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_brkh3g0s_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bskh3g1c_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_btkh3g1c_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bukh3g1s_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_bvkh3g1s_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_c0kh3g2d_1_1_spf
            get /pgms/oracle/product/v10203/dbs/PROD_c1kh3g2f_1_1_ctl

Generate the commands to remove and create the directories for the standby database (the remove commands are used in the case where a standby database had been created before on StandbyServer):
    sqlplus "/ as sysdba"
        set heading off feedback off
        spool makedirs.shl
        select distinct ' rm -r ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_data_files
        union
        select distinct ' rm -r ' || substr(substr(value,instr(value,'LOCATION=')+9),1,
            instr(substr(value,instr(value,'LOCATION=')+9),' ')-13)
            from v$parameter where name between 'log_archive_dest_1' and
            'log_archive_dest_10' and instr(value,'LOCATION=') > 0
        union
        select distinct ' rm -r ' || substr(value,1,instr(value,'/',-1)-1) from v$parameter
            where name in ('background_dump_dest','user_dump_dest','core_dump_dest',
            'audit_file_dest','log_archive_dest')
            and value is not null
        union
        select distinct 'mkdir -p ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_data_files
        union
        select distinct 'mkdir -p ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_temp_files
        union
        select distinct 'mkdir -p ' || value from v$parameter
            where name in ('background_dump_dest','user_dump_dest','core_dump_dest',
            'audit_file_dest','log_archive_dest')
            and value is not null
        union
        select distinct 'mkdir -p ' || substr(substr(value,instr(value,'LOCATION=')+9),1,
            instr(substr(value,instr(value,'LOCATION=')+9),' ')-1)
            from v$parameter where name between 'log_archive_dest_1' and
            'log_archive_dest_10' and instr(value,'LOCATION=') > 0;
        spool off
        exit
    cat makedirs.shl
        shows (along with the SQL above, which can be deleted from makedirs.shl):
            rm -r /data/oradata/PROD
            rm -r /ndxs/oradata/PROD
            rm -r /orcl/oradata/PROD
            rm -r /pgms/oradata/PROD
            mkdir -p /data/oradata/PROD
            mkdir -p /ndxs/oradata/PROD
            mkdir -p /orcl/oradata/PROD/archivelogs
            mkdir -p /pgms/oradata/PROD/audit
            mkdir -p /pgms/oradata/PROD/bdump
            mkdir -p /pgms/oradata/PROD/cdump
            mkdir -p /pgms/oradata/PROD/udump

Generate the SQL to create the standby redo log groups for the new StandbyServer standby database:
    sqlplus "/ as sysdba"
        column o1 noprint
        column o2 noprint
        column maxgroup new_value maxgroup
        select max(group#) maxgroup from v$logfile where type = 'ONLINE';
        select group# o1,1 o2,'alter database add standby logfile group ' ||
            to_char(group#+&maxgroup) || ' ('
            from v$log
        union all
        select group#,2,' ''' || replace(replace(member,group#,group#+&maxgroup),
            '/log_','/stby_log_') || ''','
            from v$logfile lf1 where member not in (select max(member) from v$logfile lf2
            where lf1.group# = lf2.group#) and type = 'ONLINE'
        union all
        select l1.group#,3,' ''' || replace(replace(member,l1.group#,l1.group#+&maxgroup),
            '/log_','/stby_log_') || ''') size ' || bytes / 1024 || 'K;'
            from v$logfile lf1,v$log l1 where lf1.group# = l1.group#
            and member = (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
            and type = 'ONLINE'
        union all
        select group#+1,1,'alter database add standby logfile group ' ||
            to_char(group#+1+&maxgroup) || ' (' from v$log
            where group# = &maxgroup
        union all
        select group#+1,2,' ''' || replace(replace(member,group#,group#+1+&maxgroup),
            '/log_','/stby_log_') || ''',' from v$logfile lf1 where group# = &maxgroup
            and member not in (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
            and type = 'ONLINE'
        union all
        select l1.group#+1,3,' ''' || replace(replace(member,l1.group#,l1.group#+1+&maxgroup),
            '/log_','/stby_log_') || ''') size ' || bytes / 1024 || 'K;'
            from v$logfile lf1,v$log l1 where lf1.group# = l1.group#
            and l1.group# = &maxgroup
            and member = (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
            and type = 'ONLINE'
            order by 1,2,3;
        exit
            shows:
                alter database add standby logfile group 4 (
                    '/orcl/oradata/PROD/stby_log_PROD_4A.rdo',
                    '/orcl/oradata/PROD/stby_log_PROD_4B.rdo') size 4096K;
                alter database add standby logfile group 5 (
                    '/orcl/oradata/PROD/stby_log_PROD_5A.rdo',
                    '/orcl/oradata/PROD/stby_log_PROD_5B.rdo') size 4096K;
                alter database add standby logfile group 6 (
                    '/orcl/oradata/PROD/stby_log_PROD_6A.rdo',
                    '/orcl/oradata/PROD/stby_log_PROD_6B.rdo') size 4096K;
                alter database add standby logfile group 7 (
                    '/orcl/oradata/PROD/stby_log_PROD_7A.rdo',
                    '/orcl/oradata/PROD/stby_log_PROD_7B.rdo') size 4096K;

THESE STEPS ARE DONE ON StandbyServer:

Add the new PROD standby database entry to the oratab file on StandbyServer and switch to it:
    login oracle
        (enter any existing database if it asks for a SID)
    vi /etc/oratab
        add:
            PROD:/pgms/oracle/product/v10203:N
        :wq
    . oraenv
        PROD

Add the new PROD standby database entry to the listener.ora file:
    vi $ORACLE_HOME/network/admin/listener.ora
        add:
            (SID_DESC=
                (SID_NAME=PROD)
                (ORACLE_HOME=/pgms/oracle/product/v10203)
            )
        :wq
Then, reload the listener:
    lsnrctl reload

FTP the makedirs.shl file, standby spfile.ora file, standby control file, and the backup files from PrimaryServer to StandbyServer:
    cd $ORACLE_HOME/dbs
    ftp PrimaryServer.uaex.edu
            oracle
        type ascii
        get /pgms/oracle/product/v10203/dbs/makedirs.shl
        type binary
        get /pgms/oracle/product/v10203/dbs/spfilePROD.ora.standby
        get /pgms/oracle/product/v10203/dbs/cikh4u15_1_1
        get /pgms/oracle/product/v10203/dbs/PROD_bfkh3fko_1_1_dbf
        get /pgms/oracle/product/v10203/dbs/PROD_bekh3fko_1_1_dbf
        get /pgms/oracle/product/v10203/dbs/PROD_bgkh3fue_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bhkh3fue_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bikh3fuu_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bjkh3fuu_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bkkh3fvd_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_blkh3fve_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bmkh3fvt_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bnkh3fvt_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bokh3g0c_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bpkh3g0c_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bqkh3g0s_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_brkh3g0s_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bskh3g1c_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_btkh3g1c_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bukh3g1s_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_bvkh3g1s_1_1_arc
        get /pgms/oracle/product/v10203/dbs/PROD_c0kh3g2d_1_1_spf
        get /pgms/oracle/product/v10203/dbs/PROD_c1kh3g2f_1_1_ctl
        bye
    mv spfilePROD.ora.standby spfilePROD.ora

Delete and recreate the directories for the new PROD database on StandbyServer.  Also, save off and restore the remove_old_logs.shl and fillup.shl scripts if they exist in the archivelogs directory (these are some local scripts that I use - you may have other scripts in your archivelogs directory that you want to preserve a copy of):
    cp -p /orcl/oradata/${ORACLE_SID}/archivelogs/remove_old_logs.shl /home/oracle/remove_old_logs.${ORACLE_SID}.shl
    cp -p /orcl/oradata/${ORACLE_SID}/archivelogs/fillup.shl /home/oracle/fillup.${ORACLE_SID}.shl
    sh $ORACLE_HOME/dbs/makedirs.shl
    cp -p /home/oracle/remove_old_logs.${ORACLE_SID}.shl /orcl/oradata/${ORACLE_SID}/archivelogs/remove_old_logs.shl
    cp -p /home/oracle/fillup.${ORACLE_SID}.shl /orcl/oradata/${ORACLE_SID}/archivelogs/fillup.shl

Create the standby's password file:
    rm $ORACLE_HOME/dbs/orapwPROD
    orapwd file=$ORACLE_HOME/dbs/orapwPROD password=<sys password> entries=5

Modify the spfile parameters for the standby database:
    sqlplus "/ as sysdba"
        startup nomount
        alter system set audit_trail='false' scope=spfile;
        alter system set db_unique_name='PROD_standby' scope=spfile;
        alter system set log_archive_config='DG_CONFIG=(PROD_primary,PROD_standby)' scope=spfile;
        alter system set log_archive_dest_1='LOCATION=/orcl/oradata/PROD/archivelogs MANDATORY VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=PROD_standby' scope=spfile;
        alter system set log_archive_dest_2='SERVICE=PrimaryServer_prod LGWR SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=PROD_primary' scope=spfile;
        alter system set log_archive_dest_state_2=enable scope=spfile;
        alter system set fal_server='PrimaryServer_prod' scope=spfile;
        alter system set fal_client='StandbyServer_prod' scope=spfile;
        startup force nomount
        exit

Create the new PROD standby database on StandbyServer from the PROD RMAN backups from PrimaryServer:
    rman target sys/<sys password>@PrimaryServer_prod auxiliary /
        duplicate target database for standby nofilenamecheck;
        exit

Start up managed recovery for the new PROD standby database on StandbyServer:
    sqlplus "/ as sysdba"
        alter database recover managed standby database disconnect from session;
            Note: This creates the redo log files in /orcl/oradata/PROD.
        exit

Do a log switch on the PROD primary database (you may have to do the switch several times), and check to see that the archive logs are coming across to the standby server:
PrimaryServer:
    sqlplus "/ as sysdba"
        alter system archive log current;
        exit
StandbyServer:
    ls -ltr /orcl/oradata/PROD/archivelogs

Add the standby log files for the new PROD standby database on StandbyServer and start up managed recovery (note: this can't be done until archiving has been started to the new standby from the primary by doing a log switch):
    sqlplus "/ as sysdba"
        alter database recover managed standby database cancel;
        alter database open read only;
        column member format a55
        select vs.group#,vs.bytes,vl.member from v$standby_log vs,v$logfile vl
            where vs.group# = vl.group# order by vs.group#,vl.member;
        alter database add standby logfile group 4 (
            '/orcl/oradata/PROD/stby_log_PROD_4A.rdo',
            '/orcl/oradata/PROD/stby_log_PROD_4B.rdo') size 4096K;
        alter database add standby logfile group 5 (
            '/orcl/oradata/PROD/stby_log_PROD_5A.rdo',
            '/orcl/oradata/PROD/stby_log_PROD_5B.rdo') size 4096K;
        alter database add standby logfile group 6 (
            '/orcl/oradata/PROD/stby_log_PROD_6A.rdo',
            '/orcl/oradata/PROD/stby_log_PROD_6B.rdo') size 4096K;
        alter database add standby logfile group 7 (
            '/orcl/oradata/PROD/stby_log_PROD_7A.rdo',
            '/orcl/oradata/PROD/stby_log_PROD_7B.rdo') size 4096K;
        select vs.group#,vs.bytes,vl.member from v$standby_log vs,v$logfile vl
            where vs.group# = vl.group# order by vs.group#,vl.member;
        alter database recover managed standby database disconnect from session;
        exit

Note: If StandbyServer does not have the same directory structure as PrimaryServer, such as if the ORACLE_HOME is different between the two servers, you can "fool" RMAN into looking for the backups using the standby server's Oracle Home directory instead of the primary server's Oracle Home directory by creating a UNIX link and referencing that instead when creating the RMAN backups for the standby, as shown below.  RMAN expects to back up and restore from the same ORACLE_HOME directory, but PrimaryServer's Oracle Home is different than StandbyServer's Oracle Home in this case.  So, it's time to pull a UNIX trick out of the bag!

Make an RMAN backup of PROD to "/oratest10/ora102/dbs" (the Oracle Home on StandbyServer) on PrimaryServer to match the $ORACLE_HOME on StandbyServer (see "env ORACLE_HOME" on StandbyServer) by creating the /oratest10/ora102/dbs link on PrimaryServer to point to $ORACLE_HOME/dbs on the primary server:
    login root
    mkdir -p /oratest10/ora102
    ln -s /pgms/oracle/product/v10203/dbs /oratest10/ora102/dbs
    chown oracle.dba /oratest10/ora102
    chmod 755 /oratest10/ora102

Create a full RMAN backup of PROD to "/oratest10/ora102/dbs" (which means we can't use my rmanclone.shl script - we'll have to do RMAN manually), along with the standby control file, making sure the logs on the primary are all archived (change the date and time to match yours). These will have to be FTP'ed to the Oracle Home on StandbyServer.
    login oracle
        PROD
    export NLS_DATE_FORMAT='DD-MON-YY HH24:MI:SS'
    export bkup_date=`date +"%y%m%d%H%M%S%aFULL`
    export bkup_tag="${ORACLE_SID}_${bkup_date}"
    echo $bkup_tag
    date
    rman target / <<EOF
        configure channel 1 device type disk format '/oratest10/ora102/dbs/%U';
        configure channel 2 device type disk format '/oratest10/ora102/dbs/%U';
        backup incremental level=0 database tag='${bkup_tag}_dbf';
        sql 'alter system archive log current';
        backup archivelog all tag='${bkup_tag}_arc';
        backup spfile tag='${bkup_tag}_spf';
        backup current controlfile tag='${bkup_tag}_ctl';
        backup current controlfile for standby tag='${bkup_tag}_sctl';
        sql 'alter system archive log current';
        backup archivelog all not backed up 1 times tag='${bkup_tag}_sarc';
        list backup of controlfile completed after "to_date('05-MAY-09 12:00:00','DD-MON-YY HH24:MI:SS')";
        list backup summary completed after "to_date('05-MAY-09 12:00:00','DD-MON-YY HH24:MI:SS')";
        configure channel 1 device type disk clear;
        configure channel 2 device type disk clear;
        exit
EOF

Recreating a Data Guard Standby Database Using RMAN

NOTE:  Use my rmanbackup.shl script dated 6/30/09 or later for this.  It includes creating a standby controlfile during the backups.  If your version does not include a 6/30/09 revision, get the latest version of the rmanbackup.shl script.

Rereating a Data Guard standby database on StandbyServer for the primary PROD database on PrimaryServer using RMAN is similar to creating a Data Guard standby database using RMAN, but leaving out some of the steps that had already been done when initially creating the standby. We do not need to add the tnsnames.ora entries or the oratab entry because they already exist, and we will use the same spfile and password file for the standby database that currently exists. Below are my notes on how I did this for our production database. (The standby had gotten out of sync when one of the archive logs on the primary was deleted, and the standby stopped applying any changes later than that missing archive log file.)

THESE STEPS ARE DONE ON PrimaryServer:

Create a full backup of PROD, which will have to be FTP'ed to StandbyServer (the backup includes the standby control file):
    login oracle
        PROD
    rmanbackup.shl PROD full

Get the list of backup files from today to FTP to StandbyServer:
    find $ORACLE_HOME/dbs \( -name '*_1_1' -o -name '*_1_1_dbf' -o -name '*_1_1_spf' -o -name '*_1_1_ctl' -o -name '*_1_1_arc' -o -name '*_1_1_sby' \) |
        sed 's/^/ls -ltr /' | sh | grep ' Jun 30 08:2' | grep PROD | sed 's/.\{58\}/get /'
        shows:
            get /pgms/oracle/product/v10203/dbs/PROD_n9kis3tp_1_1_sby
            get /pgms/oracle/product/v10203/dbs/PROD_nbkis3tr_1_1_dbf
            get /pgms/oracle/product/v10203/dbs/PROD_nakis3tr_1_1_dbf
            get /pgms/oracle/product/v10203/dbs/PROD_nckis482_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_ndkis482_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nekis48i_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nfkis48i_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_ngkis492_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nhkis492_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nikis49h_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_njkis49h_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nkkis4a1_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nlkis4a1_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nmkis4ag_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nnkis4ah_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nokis4b0_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_npkis4b1_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nqkis4bg_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nrkis4bg_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nskis4c1_1_1_spf
            get /pgms/oracle/product/v10203/dbs/PROD_ntkis4c3_1_1_ctl

Generate the commands to remove and create the directories for the standby database (the remove commands are used in the case where a standby database had been created before on StandbyServer):
    sqlplus "/ as sysdba"
        set heading off feedback off
        spool makedirs.shl
        select distinct ' rm -r ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_data_files
        union
        select distinct ' rm -r ' || substr(substr(value,instr(value,'LOCATION=')+9),1,
            instr(substr(value,instr(value,'LOCATION=')+9),' ')-13)
            from v$parameter where name between 'log_archive_dest_1' and
            'log_archive_dest_10' and instr(value,'LOCATION=') > 0
        union
        select distinct ' rm -r ' || substr(value,1,instr(value,'/',-1)-1) from v$parameter
            where name in ('background_dump_dest','user_dump_dest','core_dump_dest',
            'audit_file_dest','log_archive_dest')
            and value is not null
        union
        select distinct 'mkdir -p ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_data_files
        union
        select distinct 'mkdir -p ' ||
            substr(file_name,1,instr(file_name,'/',-1)-1)
            from dba_temp_files
        union
        select distinct 'mkdir -p ' || value from v$parameter
            where name in ('background_dump_dest','user_dump_dest','core_dump_dest',
            'audit_file_dest','log_archive_dest')
            and value is not null
        union
        select distinct 'mkdir -p ' || substr(substr(value,instr(value,'LOCATION=')+9),1,
            instr(substr(value,instr(value,'LOCATION=')+9),' ')-1)
            from v$parameter where name between 'log_archive_dest_1' and
            'log_archive_dest_10' and instr(value,'LOCATION=') > 0;
        spool off
        exit
    vi /home/oracle/makedirs.shl
        :1,/^ rm /-1d
        :$d
        :wq
    cat makedirs.shl
        shows (along with the SQL above, which can be deleted from makedirs.shl):
            rm -r /data/oradata/PROD
            rm -r /ndxs/oradata/PROD
            rm -r /orcl/oradata/PROD
            rm -r /pgms/oradata/PROD
            mkdir -p /data/oradata/PROD
            mkdir -p /ndxs/oradata/PROD
            mkdir -p /orcl/oradata/PROD/archivelogs
            mkdir -p /pgms/oradata/PROD/audit
            mkdir -p /pgms/oradata/PROD/bdump
            mkdir -p /pgms/oradata/PROD/cdump
            mkdir -p /pgms/oradata/PROD/udump

Generate the SQL to create the standby redo log groups for the new StandbyServer standby database:
    sqlplus "/ as sysdba"
        column o1 noprint
        column o2 noprint
        column maxgroup new_value maxgroup
        select max(group#) maxgroup from v$logfile where type = 'ONLINE';
        select group# o1,1 o2,'alter database add standby logfile group ' ||
            to_char(group#+&maxgroup) || ' ('
            from v$log
        union all
        select group#,2,' ''' || replace(replace(member,group#,group#+&maxgroup),
            '/log_','/stby_log_') || ''','
            from v$logfile lf1 where member not in (select max(member) from v$logfile lf2
            where lf1.group# = lf2.group#) and type = 'ONLINE'
        union all
        select l1.group#,3,' ''' || replace(replace(member,l1.group#,l1.group#+&maxgroup),
            '/log_','/stby_log_') || ''') size ' || bytes / 1024 || 'K;'
            from v$logfile lf1,v$log l1 where lf1.group# = l1.group#
            and member = (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
            and type = 'ONLINE'
        union all
        select group#+1,1,'alter database add standby logfile group ' ||
            to_char(group#+1+&maxgroup) || ' (' from v$log
            where group# = &maxgroup
        union all
        select group#+1,2,' ''' || replace(replace(member,group#,group#+1+&maxgroup),
            '/log_','/stby_log_') || ''',' from v$logfile lf1 where group# = &maxgroup
            and member not in (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
            and type = 'ONLINE'
        union all
            select l1.group#+1,3,' ''' || replace(replace(member,l1.group#,l1.group#+1+&maxgroup),
            '/log_','/stby_log_') || ''') size ' || bytes / 1024 || 'K;'
            from v$logfile lf1,v$log l1 where lf1.group# = l1.group#
            and l1.group# = &maxgroup
            and member = (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
            and type = 'ONLINE'
            order by 1,2,3;
        exit
            shows:
                alter database add standby logfile group 4 (
                    '/orcl/oradata/PROD/stby_log_PROD_4A.rdo',
                    '/orcl/oradata/PROD/stby_log_PROD_4B.rdo') size 4096K;
                alter database add standby logfile group 5 (
                    '/orcl/oradata/PROD/stby_log_PROD_5A.rdo',
                    '/orcl/oradata/PROD/stby_log_PROD_5B.rdo') size 4096K;
                alter database add standby logfile group 6 (
                    '/orcl/oradata/PROD/stby_log_PROD_6A.rdo',
                    '/orcl/oradata/PROD/stby_log_PROD_6B.rdo') size 4096K;
                alter database add standby logfile group 7 (
                    '/orcl/oradata/PROD/stby_log_PROD_7A.rdo',
                    '/orcl/oradata/PROD/stby_log_PROD_7B.rdo') size 4096K;

THESE STEPS ARE DONE ON StandbyServer:

Log into the unix oracle account, set the ORACLE_SID to the standby SID, and shut down the current standby database:
    login oracle
        PROD
    sqlplus "/ as sysdba"
        shutdown immediate
        exit

FTP the backup files and the standby control file from PrimaryServer to StandbyServer:
    cd $ORACLE_HOME/dbs
    ftp PrimaryServer.uaex.edu
                oracle
            type ascii
            get /home/oracle/makedirs.shl
            type binary
            get /pgms/oracle/product/v10203/dbs/PROD_n9kis3tp_1_1_sby
            get /pgms/oracle/product/v10203/dbs/PROD_nbkis3tr_1_1_dbf
            get /pgms/oracle/product/v10203/dbs/PROD_nakis3tr_1_1_dbf
            get /pgms/oracle/product/v10203/dbs/PROD_nckis482_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_ndkis482_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nekis48i_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nfkis48i_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_ngkis492_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nhkis492_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nikis49h_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_njkis49h_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nkkis4a1_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nlkis4a1_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nmkis4ag_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nnkis4ah_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nokis4b0_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_npkis4b1_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nqkis4bg_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nrkis4bg_1_1_arc
            get /pgms/oracle/product/v10203/dbs/PROD_nskis4c1_1_1_spf
            get /pgms/oracle/product/v10203/dbs/PROD_ntkis4c3_1_1_ctl
            bye

Delete and recreate the directories for the new PROD database on StandbyServer. Also, save off and restore the remove_old_logs.shl and fillup.shl scripts if they exist in the archivelogs directory (these are some local scripts that I use - you may have other scripts in your archivelogs directory that you want to preserve a copy of):
    cd
    cp -p /orcl/oradata/${ORACLE_SID}/archivelogs/remove_old_logs.shl     /home/oracle/remove_old_logs.${ORACLE_SID}.shl
    cp -p /orcl/oradata/${ORACLE_SID}/archivelogs/fillup.shl /home/oracle/fillup.${ORACLE_SID}.shl
    sh /home/oracle/makedirs.shl
    cp -p /home/oracle/remove_old_logs.${ORACLE_SID}.shl /orcl/oradata/${ORACLE_SID}/archivelogs/remove_old_logs.shl
    cp -p /home/oracle/fillup.${ORACLE_SID}.shl /orcl/oradata/${ORACLE_SID}/archivelogs/fillup.shl

Create the new PROD standby database on StandbyServer from the PROD RMAN backups from PrimaryServer:
    sqlplus "/ as sysdba"
        startup nomount
        exit
    rman target sys/<sys password>@PrimaryServer_prod auxiliary /
        duplicate target database for standby nofilenamecheck;
        exit

Start up managed recovery for the new PROD standby database on StandbyServer:
    sqlplus "/ as sysdba"
        alter database recover managed standby database disconnect from session;
            Note: This creates the redo log files in /orcl/oradata/PROD.
        exit

Do a log switch on the PROD primary database (you may have to do the switch several times), and check to see that the archive logs are coming across to the standby server:
PrimaryServer:
    sqlplus "/ as sysdba"
        alter system archive log current;
        exit
StandbyServer:
    ls -ltr /orcl/oradata/PROD/archivelogs

Add the standby log files for the new PROD standby database on StandbyServer and start up managed recovery (note: this can't be done until archiving has been started to the new standby from the primary by doing a log switch):
    sqlplus "/ as sysdba"
        alter database recover managed standby database cancel;
        alter database open read only;
        column member format a55
        select vs.group#,vs.bytes,vl.member from v$standby_log vs,v$logfile vl
            where vs.group# = vl.group# order by vs.group#,vl.member;
        alter database add standby logfile group 4 (
            '/orcl/oradata/PROD/stby_log_PROD_4A.rdo',
            '/orcl/oradata/PROD/stby_log_PROD_4B.rdo') size 4096K;
        alter database add standby logfile group 5 (
            '/orcl/oradata/PROD/stby_log_PROD_5A.rdo',
            '/orcl/oradata/PROD/stby_log_PROD_5B.rdo') size 4096K;
        alter database add standby logfile group 6 (
            '/orcl/oradata/PROD/stby_log_PROD_6A.rdo',
            '/orcl/oradata/PROD/stby_log_PROD_6B.rdo') size 4096K;
        alter database add standby logfile group 7 (
            '/orcl/oradata/PROD/stby_log_PROD_7A.rdo',
            '/orcl/oradata/PROD/stby_log_PROD_7B.rdo') size 4096K;
        select vs.group#,vs.bytes,vl.member from v$standby_log vs,v$logfile vl
            where vs.group# = vl.group# order by vs.group#,vl.member;
        alter database recover managed standby database disconnect from session;
        exit

Creating a Local Data Guard Standby Database on Windows (added 5/30/10)

Below is how I created a local Data Guard standby database (ORC2) for a primary database (ORCL) on Windows.  It also uses RMAN to back up and duplicate the database.

Create a pfile from the primary, if you don't have one already:

set ORACLE_SID=ORCL
sqlplus "sys/whatever1 as sysdba"
    create pfile from spfile;
    exit

Make Data Guard additions/changes, resulting in the following in the initORCL.ora file (also changing the dump_dest directories for ORCL; note: the dump_dest parameters have been depreciated in Oracle 11g):

edit C:\11gr2\product\11.2.0\dbhome_1\database\initORCL.ora
    *.background_dump_dest = c:\11gr2\oradata\orcl\bdump
    *.core_dump_dest = c:\11gr2\oradata\orcl\cdump
    *.user_dump_dest = c:\11gr2\oradata\orcl\udump
    *.audit_file_dest = c:\11gr2\oradata\orcl\audit
    #log_archive_dest = /orcl/oradata/ORCL/archivelogs
    *.log_archive_dest_1 = 'LOCATION=/orcl/oradata/ORCL/archivelogs MANDATORY VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=ORCL'
    *.log_archive_dest_state_1 = ENABLE
    *.log_archive_dest_2 = 'SERVICE=ORC2 LGWR SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=ORC2'
    *.log_archive_dest_state_2 = ENABLE
    *.standby_archive_dest = /orcl/oradata/ORCL/archivelogs  # for switchover
    *.standby_file_management = AUTO  # for switchover; or MANUAL for raw devices
    #*.remote_archive_enable = TRUE  # TRUE or SEND, but must change SEND to RECEIVE on switchover
    *.instance_name = ORCL
    *.lock_name_space = ORCL  # use when primary and standby on same system; same as instance_name
    *.fal_server = ORC2  # for switchover
    *.fal_client = ORCL  # for switchover
    *.db_file_name_convert = ('ORC2','ORCL','orc2','orcl')  # for switchover
    *.log_file_name_convert = ('ORC2','ORCL','orc2','orcl')  # for switchover
    # log_archive_trace = 15  # to see progression of archiving of redo logs to the standby site
    *.audit_trail = false  # for switchover; do not have auditing turned on in a standby database - can't audit to read-only database!

Copy and edit the standby's pfile to change the SID and to add the Data Guard parameters, such as:

copy C:\11gr2\product\11.2.0\dbhome_1\database\initORCL.ora C:\11gr2\product\11.2.0\dbhome_1\database\initORC2.ora
Change all occurrences of orc2 to orcx, orcl to orc2, and orcx to orcl EXCEPT FOR db_name (leave as orcl), and make Data Guard additions/changes, resulting in the following in the initORC2.ora file (note: the dump_dest parameters have been depreciated in Oracle 11g):
edit C:\11gr2\product\11.2.0\dbhome_1\database\initORC2.ora
    *.control_files = (c:\11gr2\oradata\orc2\control01.ctl,c:\11gr2\flash_recovery_area\orc2\control02.ctl)
    *.background_dump_dest = c:\11gr2\oradata\orc2\bdump
    *.core_dump_dest = c:\11gr2\oradata\orc2\cdump
    *.user_dump_dest = c:\11gr2\oradata\orc2\udump
    *.audit_file_dest = c:\11gr2\oradata\orc2\audit
    #log_archive_dest = c:\11gr2\oradata\orc2\archivelogs
    *.log_archive_config='DG_CONFIG=(ORC2,ORCL)'
    *.log_archive_dest_1='LOCATION=C:\11gr2\oradata\orc2\archivelogs MANDATORY VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=ORC2'  # for switchover
    *.log_archive_dest_state_1 = ENABLE  # for switchover
    *.log_archive_dest_2='SERVICE=orcl LGWR SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=ORCL'  # for switchover
    *.log_archive_dest_state_2 = ENABLE  # for switchover
    *.standby_archive_dest = c:\11gr2\oradata\orc2\archivelogs
    *.standby_file_management = AUTO  # or MANUAL for raw devices
    #*.remote_archive_enable = TRUE  # TRUE or RECEIVE, but must change RECEIVE to SEND on switchover
    *.instance_name = ORC2
    *.lock_name_space = ORC2;  # use when primary and standby on same system; same as instance_name
    *.fal_server = ORCL
    *.fal_client = ORC2
    *.db_file_name_convert = ('ORCL','ORC2','orcl','orc2')
    *.log_file_name_convert = ('ORCL','ORC2','orcl','orc2')
    # log_archive_trace = 15  # to see progression of archiving of redo logs to the standby site
    *.audit_trail = false  # do not have auditing turned on in a standby database - can't audit to read-only database!

Add the standby database to the tnsnames file, if it is not already there:

edit C:\11gr2\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora to add:
ORC2 =
    (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.102)(PORT = 1521))
        (CONNECT_DATA =
            (SERVER = DEDICATED)
            (SERVICE_NAME = orc2.maristream.org)
        )
    )

Add the standby database to the listener.ora file, if it is not already there:

edit C:\11gr2\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora to add:
    (SID_DESC=
        (SID_NAME=ORC2)
        (ORACLE_HOME=C:\11gr2\product\11.2.0\dbhome_1)
    )

Create a Windows service for the standby:

oradim -new -sid orc2 -intpwd whatever1 -startmode manual -pfile C:\11gr2\product\11.2.0\dbhome_1\database\initORC2.ora
Or, start up the standby's service:
oradim -start -sid ORC2 -starttype srvc

Create the standby's data file, temp file, dump file, and archivelog directory(s) if they don't exist:

sqlplus "sys/whatever1 as sysdba"
    set heading off echo off feedback off trimspool on verify off
    define primary=ORCL
    define standby=ORC2
    select distinct 'mkdir ' || replace(substr(file_name,1,
        instr(file_name,'\',-1)-1),'&primary','&standby')
        from dba_data_files
    union
    select distinct 'mkdir ' || replace(substr(file_name,1,
        instr(file_name,'\',-1)-1),'&primary','&standby')
        from dba_temp_files
    union
    select distinct 'mkdir ' || replace(value,'&primary','&standby')
        from v$parameter where name in ('background_dump_dest','user_dump_dest',
        'core_dump_dest','audit_file_dest','log_archive_dest')
        and value is not null
    union
    select distinct 'mkdir ' || replace(substr(substr(value,instr(value,'LOCATION=')+9),1,
        instr(substr(value,instr(value,'LOCATION=')+9),' ')-1),'&primary','&standby')
        from v$parameter where name between 'log_archive_dest_1' and
        'log_archive_dest_10' and instr(value,'LOCATION=') > 0;
    alter system archive log current;
    exit
Such as:
    mkdir C:\11GR2\ADMIN\ORC2\ADUMP
    mkdir C:\11GR2\ORADATA\ORC2
    mkdir C:\11gr2\oradata\orc2\archivelogs
    mkdir c:\11gr2\diag\rdbms\orc2\orc2\cdump
    mkdir c:\11gr2\diag\rdbms\orc2\orc2\trace

Also make the dump file directories declared in the init.ora files (but, these have been depreciated in Oracle 11g):

mkdir c:\11gr2\oradata\orc2\bdump
mkdir c:\11gr2\oradata\orc2\cdump
mkdir c:\11gr2\oradata\orc2\udump
mkdir c:\11gr2\oradata\orc2\audit
mkdir c:\11gr2\oradata\orcl\bdump
mkdir c:\11gr2\oradata\orcl\cdump
mkdir c:\11gr2\oradata\orcl\udump
mkdir c:\11gr2\oradata\orcl\audit

Delete the standby's datafiles, control files, and spfile if they currently exist:

set ORACLE_SID=ORC2
sqlplus "sys/whatever1 as sysdba"
    select 'del ' || file_name from dba_data_files
    union
    select 'del ' || file_name from dba_temp_files
    union
    select 'del ' || replace(value,', ',chr(10)||chr(13)||'del ') from v$parameter
        where name = 'control_files'
    union
    select 'del ' || value from v$parameter where name = 'spfile'
        and value is not null;
    shutdown immediate
    exit
Such as:
    del C:\11GR2\ORADATA\ORC2\CONTROL01.CTL
    del C:\11GR2\FLASH_RECOVERY_AREA\ORC2\CONTROL02.CTL
    del C:\11GR2\ORADATA\ORC2\EXAMPLE01.DBF
    del C:\11GR2\ORADATA\ORC2\SYSAUX01.DBF
    del C:\11GR2\ORADATA\ORC2\SYSTEM01.DBF
    del C:\11GR2\ORADATA\ORC2\TEMP01.DBF
    del C:\11GR2\ORADATA\ORC2\UNDOTBS01.DBF
    del C:\11GR2\ORADATA\ORC2\USERS01.DBF

Or, could use RMAN to drop the database:

set ORACLE_SID=ORC2
RMAN target /
    drop database including backups;
    exit

Delete the standby's spfile if the above didn't catch it:

del C:\11gr2\product\11.2.0\dbhome_1\database\spfileORC2.ora

Copy the password file from the primary (PWDorcl.ora) to the standby (PWDorc2.ora):

copy C:\11gr2\product\11.2.0\dbhome_1\database\PWDorcl.ora C:\11gr2\product\11.2.0\dbhome_1\database\PWDorc2.ora

Create the standby's spfile from the edited pfile and start up the standby in the nomount state:

sqlplus "sys/whatever1 as sysdba"
    create spfile from pfile;
    startup force nomount
    exit

Get the date and time (substitute in the tag parameters below) and createan RMAN backup of the primary including the standby's control file:

date
time
set ORACLE_SID=ORCL
rman target sys/whatever1
    configure default device type to disk;
    configure device type disk backup type to compressed backupset parallelism 2;
    configure retention policy to recovery window of 35 days;
    # configure controlfile autobackup on;
    backup current controlfile for standby format='%d_%U_sby' tag='ORCL_20100527123500_sby';
    backup incremental level=0 database format='%d_%U_dbf' tag='ORCL_20100527123500_dbf';
    sql 'alter system archive log current';
    backup archivelog all format='%d_%U_arc' tag='ORCL_20100527123500_arc';
    backup spfile format='%d_%U_spf' tag='ORCL_20100527123500_spf';
    backup current controlfile format='%d_%U_ctl' tag='ORCL_20100527123500_ctl';
    delete noprompt archivelog all completed before 'sysdate-8' backed up 5 times
        to device type disk;
    exit

Generate the SQL to create the standby redo log groups for the new standby database:

sqlplus "sys/whatever1 as sysdba"
    column o1 noprint
    column o2 noprint
    define primary=ORCL
    define standby=ORC2
    column maxgroup new_value maxgroup
    select max(group#) maxgroup from v$logfile where type = 'ONLINE';
    select group# o1,1 o2,'alter database add standby logfile group ' ||
        to_char(group#+&maxgroup) || ' ('
        from v$log
    union all
    select group#,2,' ''' || replace(replace(member,group#,group#+&maxgroup),
        '&primary\REDO','&standby\stby_REDO') || ''','
        from v$logfile lf1 where member not in (select max(member) from v$logfile lf2
        where lf1.group# = lf2.group#) and type = 'ONLINE'
    union all
    select l1.group#,3,' ''' || replace(replace(member,l1.group#,l1.group#+&maxgroup),
        '&primary\REDO','&standby\stby_REDO') || ''') size ' || bytes / 1024 || 'K;'
        from v$logfile lf1,v$log l1 where lf1.group# = l1.group#
        and member = (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
        and type = 'ONLINE'
    union all
    select group#+1,1,'alter database add standby logfile group ' ||
        to_char(group#+1+&maxgroup) || ' (' from v$log
        where group# = &maxgroup
    union all
    select group#+1,2,' ''' || replace(replace(member,group#,group#+1+&maxgroup),
        '&primary\REDO','&standby\stby_REDO') || ''',' from v$logfile lf1 where group# = &maxgroup
        and member not in (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
        and type = 'ONLINE'
    union all
    select l1.group#+1,3,' ''' || replace(replace(member,l1.group#,l1.group#+1+&maxgroup),
        '&primary\REDO','&standby\stby_REDO') || ''') size ' || bytes / 1024 || 'K;'
        from v$logfile lf1,v$log l1 where lf1.group# = l1.group#
        and l1.group# = &maxgroup
        and member = (select max(member) from v$logfile lf2 where lf1.group# = lf2.group#)
        and type = 'ONLINE'
        order by 1,2,3;
    exit
        shows:
        alter database add standby logfile group 4 (
             'C:\11GR2\ORADATA\ORC2\stby_REDO04.LOG') size 51200K;
         alter database add standby logfile group 5 (
             'C:\11GR2\ORADATA\ORC2\stby_REDO05.LOG') size 51200K;
         alter database add standby logfile group 6 (
             'C:\11GR2\ORADATA\ORC2\stby_REDO06.LOG') size 51200K;
         alter database add standby logfile group 7 (
             'C:\11GR2\ORADATA\ORC2\stby_REDO07.LOG') size 51200K;

Add the parameters for the Data Guard settings to the primary database's spfile.ora file (could have done this without shutting down the database by doing "alter system set" commands):

sqlplus 'sys/whatever1 as sysdba'
    shutdown immediate
    exit
del C:\11gr2\product\11.2.0\dbhome_1\database\spfileORCL.ora
sqlplus 'sys/whatever1 as sysdba'
    startup
    create spfile from pfile;
    startup force
    exit

Run the RMAN duplicate command to copy the primary to the standby as of a given date and time:

date
time
set ORACLE_SID=ORC2
rman target sys/whatever1@ORCL auxiliary sys/whatever1
    run
    {
        set until time = "to_date('05/27/10:12:45:00','MM/DD/YY:HH24:MI:SS')";
        duplicate target database for standby;
    }
    exit

Start up managed recovery for the new standby database:

sqlplus "sys/whatever1 as sysdba"
    startup force mount
    alter database recover managed standby database disconnect from session;
        Note: This creates the redo log files in C:\11gr2\oradata\orc2.
    exit
Note: To start a standby's service (not the instance):
    oradim -start -sid ORC2 -starttype srvc
To cancel recovery:
    alter database recover managed standby database cancel;

Do a log switch on the primary (you may have to do the switch several times), and check to see that the archive logs are coming across to the standby server:

set ORACLE_SID=ORCL
sqlplus "sys/whatever1 as sysdba"
    alter system archive log current;
    alter system archive log current;
    alter system archive log current;
    alter system archive log current;
    exit
Check to see that the archives are flowing:
    dir C:\11gr2\oradata\orc2\archivelogs

Add the standby log files for the new standby and restart managed recovery (note: this can't be done until archiving has been started to the new standby from the primary by doing a log switch):

set ORACLE_SID=ORC2
sqlplus "sys/whatever1 as sysdba"
    alter database recover managed standby database cancel;
    alter database open read only;
    column member format a55
    select vs.group#,vs.bytes,vl.member from v$standby_log vs,v$logfile vl
        where vs.group# = vl.group# order by vs.group#,vl.member;
    alter database add standby logfile group 4 (
        'C:\11GR2\ORADATA\ORC2\stby_REDO04.LOG') size 51200K;
    alter database add standby logfile group 5 (
        'C:\11GR2\ORADATA\ORC2\stby_REDO05.LOG') size 51200K;
    alter database add standby logfile group 6 (
        'C:\11GR2\ORADATA\ORC2\stby_REDO06.LOG') size 51200K;
    alter database add standby logfile group 7 (
        'C:\11GR2\ORADATA\ORC2\stby_REDO07.LOG') size 51200K;
    select vs.group#,vs.bytes,vl.member from v$standby_log vs,v$logfile vl
        where vs.group# = vl.group# order by vs.group#,vl.member;
    alter database recover managed standby database disconnect from session;
    exit


You Are Visitor Number

This Page Was Last Updated on 05/30/10

Copyright © 2009 by Maristream.   All information, scripts, forms, and other material
on this web site are freely available to all Banner and Oracle Database Administrators,
Systems Administrators, Programmers, and others that may need it.

The webmaster who maintains this web site may be reached at srea@maristream.org. Visit our other web sites:

Maristream - New Product Research and Development
www.maristream.org

CAKID - The Arkansas Foster Parent's Web Site
www.cakid.org

Disclaimer:  As with all software, especially where it affects your vital data, make sure that you examine theses scripts and that you understand what they do before you use them to see if they would have any adverse effect on your particular setup or database layout.  Make a full backup of your database in case you have to revert to your original copy of the database before the scripts were run.  Use these scripts at your own risk.  As a condition of using these scripts, you agree to hold harmless both Maristream and Stephen Rea for any problems that they may cause or other situations that may arise from their use, and that neither Maristream nor I will be held liable for those consequences.