Duplicate Oracle Database with RMAN

Martin Zahn, 30.10.2008

Details see: Oracle® Database Backup and Recovery Advanced User's Guide 10g Release 2 (10.2)


Overview

A powerful feature of RMAN is the ability to duplicate (clone), a database from a backup. It is possible to create a duplicate database on:

  • A remote server with the same file structure
  • A remote server with a different file structure
  • The local server with a different file structure

A duplicate database is distinct from a standby database, although both types of databases are created with the DUPLICATE command. A standby database is a copy of the primary database that you can update continually or periodically by using archived logs from the primary database. If the primary database is damaged or destroyed, then you can perform failover to the standby database and effectively transform it into the new primary database. A duplicate database, on the other hand, cannot be used in this way: it is not intended for failover scenarios and does not support the various standby recovery and failover options.

To prepare for database duplication, you must first create an auxiliary instance. For the duplication to work, you must connect RMAN to both the target (primary) database and an auxiliary instance started in NOMOUNT mode.

So long as RMAN is able to connect to the primary and duplicate instances, the RMAN client can run on any machine. However, all backups, copies of datafiles, and archived logs used for creating and recovering the duplicate database must be accessible by the server session on the duplicate host.

As part of the duplicating operation, RMAN manages the following:

  • Restores the target datafiles to the duplicate database and performs incomplete recovery by using all available backups and archived logs.
     
  • Shuts down and starts the auxiliary database.
     
  • Opens the duplicate database with the RESETLOGS option after incomplete recovery to create the online redo logs.
     
  • Generates a new, unique DBID for the duplicate database.

Preparing the Duplicate (Auxiliary) Instance for Duplication

Create an Oracle Password File

First we must create a password file for the duplicate instance.

export ORACLE_SID=APP2
orapwd file=orapwAPP2 password=manager entries=5 force=y

Ensure Oracle Net Connectivity to both Instances

Next add the appropriate entries into the TNSNAMES.ORA and LISTENER.ORA files in the $TNS_ADMIN directory.

LISTENER.ORA

APP1 = Target Database, APP2 = Auxiliary Database

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = gentic)(PORT = 1521))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = APP1.WORLD)
      (ORACLE_HOME = /opt/oracle/product/10.2.0)
      (SID_NAME = APP1)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = APP2.WORLD)
      (ORACLE_HOME = /opt/oracle/product/10.2.0)
      (SID_NAME = APP2)
    )
  )

TNSNAMES.ORA

APP1 = Target Database, APP2 = Auxiliary Database

APP1.WORLD =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = gentic)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = APP1.WORLD)
    )
  )

APP2.WORLD =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = gentic)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = APP2.WORLD)
    )
  )

SQLNET.ORA

NAMES.DIRECTORY_PATH= (TNSNAMES)
NAMES.DEFAULT_DOMAIN = WORLD
NAME.DEFAULT_ZONE = WORLD
USE_DEDICATED_SERVER = ON

Now restart the Listener

lsnrctl stop
lsnrctl start

Create an Initialization Parameter File for the Auxiliary Instance

Create an INIT.ORA parameter file for the auxiliary instance, you can copy that from the target instance and then modify the parameters.

### Duplicate Database
### -----------------------------------------------
# This is only used when you duplicate the database
# on the same host to avoid name conflicts

DB_FILE_NAME_CONVERT              = (/u01/oracle/db/APP1/,/u01/oracle/db/APP2/)
LOG_FILE_NAME_CONVERT             = (/u01/oracle/db/APP1/,/u01/oracle/db/APP2/,
                                     /opt/oracle/db/APP1/,/opt/oracle/db/APP2/)

### Global database name is db_name.db_domain
### -----------------------------------------

db_name                           = APP2
db_unique_name                    = APP2_GENTIC
db_domain                         = WORLD
service_names                     = APP2
instance_name                     = APP2

### Basic Configuration Parameters
### ------------------------------

compatible                        = 10.2.0.4
db_block_size                     = 8192
db_file_multiblock_read_count     = 32
db_files                          = 512
control_files                     = /u01/oracle/db/APP2/con/APP2_con01.con,
                                    /opt/oracle/db/APP2/con/APP2_con02.con

### Database Buffer Cache, I/O
### --------------------------
# The Parameter SGA_TARGET enables Automatic Shared Memory Management

sga_target                        = 500M
sga_max_size                      = 600M

### REDO Logging without Data Guard
### -------------------------------

log_archive_format                = APP2_%s_%t_%r.arc
log_archive_max_processes         = 2
log_archive_dest                  = /u01/oracle/db/APP2/arc

### System Managed Undo
### -------------------

undo_management                   = auto
undo_retention                    = 10800
undo_tablespace                   = undo

### Traces, Dumps and Passwordfile
### ------------------------------

audit_file_dest                   = /u01/oracle/db/APP2/adm/admp
user_dump_dest                    = /u01/oracle/db/APP2/adm/udmp
background_dump_dest              = /u01/oracle/db/APP2/adm/bdmp
core_dump_dest                    = /u01/oracle/db/APP2/adm/cdmp
utl_file_dir                      = /u01/oracle/db/APP2/adm/utld
remote_login_passwordfile         = exclusive

Create a full Database Backup

Make sure that a full backup of the target is accessible on the duplicate host. You can use the following BASH script to backup the target database.

rman nocatalog target / <<-EOF
   configure retention policy to recovery window of 3 days;
   configure backup optimization on;
   configure controlfile autobackup on;
   configure default device type to disk;
   configure device type disk parallelism 1 backup type to compressed backupset;
   configure datafile backup copies for device type disk to 1;
   configure maxsetsize to unlimited;
   configure snapshot controlfile name to '/u01/backup/snapshot_controlfile';
   show all;

   run {
     allocate channel ch1 type Disk maxpiecesize = 1900M;
     backup full database noexclude
     include current controlfile
     format '/u01/backup/datafile_%s_%p.bak'
     tag 'datafile_daily';
   }

   run {
     allocate channel ch1 type Disk maxpiecesize = 1900M;
     backup archivelog all
     delete all input
     format '/u01/backup/archivelog_%s_%p.bak'
     tag 'archivelog_daily';
   }

   run {
      allocate channel ch1 type Disk maxpiecesize = 1900M;
      backup format '/u01/backup/controlfile_%s.bak' current controlfile;
   }

   crosscheck backup;
   list backup of database;
   report unrecoverable;
   report schema;
   report need backup;
   report obsolete;
   delete noprompt expired backup of database;
   delete noprompt expired backup of controlfile;
   delete noprompt expired backup of archivelog all;
   delete noprompt obsolete recovery window of 3 days;
   quit
EOF

Creating a Duplicate Database on the Local Host

Before beginning RMAN duplication, use SQL*Plus to connect to the auxiliary instance and start it in NOMOUNT mode. If you do not have a server-side initialization parameter file for the auxiliary instance in the default location, then you must specify the client-side initialization parameter file with the PFILE parameter on the DUPLICATE command.

Get original Filenames from TARGET

To rename the database files you can use the SET NEWNAME command. Therefore, get the original filenames from the target and modify these names in the DUPLICATE command.

ORACLE_SID=APP1
export ORACLE_SID

set feed off
set pagesize 10000
column name format a40 heading "Datafile"
column file# format 99 heading "File-ID"

select  name, file# from v$dbfile;

column member format a40 heading "Logfile"
column group# format 99 heading "Group-Nr"

select  member, group# from v$logfile;

Datafile                                  File-ID
----------------------------------------  -------
/u01/oracle/db/APP1/sys/APP1_sys1.dbf           1
/u01/oracle/db/APP1/sys/APP1_undo1.dbf          2
/u01/oracle/db/APP1/sys/APP1_sysaux1.dbf        3
/u01/oracle/db/APP1/usr/APP1_users1.dbf         4

Logfile                                  Group-Nr
---------------------------------------- --------
/u01/oracle/db/APP1/rdo/APP1_log1A.rdo          1
/opt/oracle/db/APP1/rdo/APP1_log1B.rdo          1
/u01/oracle/db/APP1/rdo/APP1_log2A.rdo          2
/opt/oracle/db/APP1/rdo/APP1_log2B.rdo          2
/u01/oracle/db/APP1/rdo/APP1_log3A.rdo          3
/opt/oracle/db/APP1/rdo/APP1_log3B.rdo          3
/u01/oracle/db/APP1/rdo/APP1_log4A.rdo          4
/opt/oracle/db/APP1/rdo/APP1_log4B.rdo          4
/u01/oracle/db/APP1/rdo/APP1_log5A.rdo          5
/opt/oracle/db/APP1/rdo/APP1_log5B.rdo          5
/u01/oracle/db/APP1/rdo/APP1_log6A.rdo          6
/opt/oracle/db/APP1/rdo/APP1_log6B.rdo          6
/u01/oracle/db/APP1/rdo/APP1_log7A.rdo          7
/opt/oracle/db/APP1/rdo/APP1_log7B.rdo          7
/u01/oracle/db/APP1/rdo/APP1_log8A.rdo          8
/opt/oracle/db/APP1/rdo/APP1_log8B.rdo          8
/u01/oracle/db/APP1/rdo/APP1_log9A.rdo          9
/opt/oracle/db/APP1/rdo/APP1_log9B.rdo          9
/u01/oracle/db/APP1/rdo/APP1_log10A.rdo        10
/opt/oracle/db/APP1/rdo/APP1_log10B.rdo        10

Create Directories for the duplicate Database

mkdir -p /u01/oracle/db/APP2
mkdir -p /opt/oracle/db/APP2
cd /opt/oracle/db/APP2
mkdir con rdo
cd /u01/oracle/db/APP2
mkdir adm arc con rdo sys tmp usr bck
cd adm
mkdir admp bdmp cdmp udmp utld

Create Symbolic Links to Password and INIT.ORA File

Oracle must be able to locate the Password and INIT.ORA File.

cd $ORACLE_HOME/dbs
ln -s /home/oracle/config/10.2.0/orapwAPP2 orapwAPP2
ln -s /home/oracle/config/10.2.0/initAPP2.ora initAPP2.ora

Duplicate the Database

Now you are ready to duplicate the database APP1 to APP2.

ORACLE_SID=APP2
export ORACLE_SID

sqlplus sys/manager as sysdba
startup force nomount pfile='/home/oracle/config/10.2.0/initAPP2.ora';
exit;

rman TARGET sys/manager@APP1 AUXILIARY sys/manager@APP2

Recovery Manager: Release 10.2.0.4.0 - Production on Tue Oct 28 12:00:13 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
connected to target database: APP1 (DBID=3191823649)
connected to auxiliary database: APP2 (not mounted)

RUN
{
  SET NEWNAME FOR DATAFILE 1 TO '/u01/oracle/db/APP2/sys/APP2_sys1.dbf';
  SET NEWNAME FOR DATAFILE 2 TO '/u01/oracle/db/APP2/sys/APP2_undo1.dbf';
  SET NEWNAME FOR DATAFILE 3 TO '/u01/oracle/db/APP2/sys/APP2_sysaux1.dbf';
  SET NEWNAME FOR DATAFILE 4 TO '/u01/oracle/db/APP2/usr/APP2_users1.dbf';
  DUPLICATE TARGET DATABASE TO APP2
  PFILE = /home/oracle/config/10.2.0/initAPP2.ora
  NOFILENAMECHECK
  LOGFILE GROUP 1 ('/u01/oracle/db/APP2/rdo/APP2_log1A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log1B.rdo') SIZE 10M REUSE,
          GROUP 2 ('/u01/oracle/db/APP2/rdo/APP2_log2A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log2B.rdo') SIZE 10M REUSE,
          GROUP 3 ('/u01/oracle/db/APP2/rdo/APP2_log3A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log3B.rdo') SIZE 10M REUSE,
          GROUP 4 ('/u01/oracle/db/APP2/rdo/APP2_log4A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log4B.rdo') SIZE 10M REUSE,
          GROUP 5 ('/u01/oracle/db/APP2/rdo/APP2_log5A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log5B.rdo') SIZE 10M REUSE,
          GROUP 6 ('/u01/oracle/db/APP2/rdo/APP2_log6A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log6B.rdo') SIZE 10M REUSE,
          GROUP 7 ('/u01/oracle/db/APP2/rdo/APP2_log7A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log7B.rdo') SIZE 10M REUSE,
          GROUP 8 ('/u01/oracle/db/APP2/rdo/APP2_log8A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log8B.rdo') SIZE 10M REUSE,
          GROUP 9 ('/u01/oracle/db/APP2/rdo/APP2_log9A.rdo',
                   '/opt/oracle/db/APP2/rdo/APP2_log9B.rdo') SIZE 10M REUSE,
          GROUP 10 ('/u01/oracle/db/APP2/rdo/APP2_log10A.rdo',
                    '/opt/oracle/db/APP2/rdo/APP2_log10B.rdo') SIZE 10M REUSE;
}

The whole, long output is not shown here, but check, that RMAN was able to open the duplicate database with the RESETLOGS option.

.....
.....
contents of Memory Script:
{
Alter clone database open resetlogs;
}
executing Memory Script

database opened
Finished Duplicate Db at 28-OCT-08

As the final step, eliminate or uncomment the DB_FILE_NAME_CONVERT and LOG_FILE_NAME_CONVERT in the INIT.ORA file and restart the database.

initAPP2.ora

### Duplicate Database
### -----------------------------------------------
# This is only used when you duplicate the database
# on the same host to avoid name conflicts
# DB_FILE_NAME_CONVERT =  (/u01/oracle/db/APP1/,/u01/oracle/db/APP2/)
# LOG_FILE_NAME_CONVERT = (/u01/oracle/db/APP1/,/u01/oracle/db/APP2/,
                           /opt/oracle/db/APP1/,/opt/oracle/db/APP2/)

sqlplus / as sysdba
shutdown immediate;
startup;

Total System Global Area 629145600 bytes
Fixed Size 1269064 bytes
Variable Size 251658936 bytes
Database Buffers 373293056 bytes
Redo Buffers 2924544 bytes
Database mounted.
Database opened.

Creating a Duplicate Database to Remote Host

This scenario is exactly the same as described for the local host. Copy the RMAN Backup files to the remote host on the same directory as on the localhost.

cd /u01/backup
scp gentic:/u01/backup/* .

The other steps are the same as described under «Creating a Duplicate Database on the Local Host».