As of Oracle 8.1.5, rman has a new command called duplicate which will allow DBAs to clone a database AND change the DBID.
Remember that as of Oracle 8, a new identity attribute was added to each database called the DBID, which is generated at create database time and cannot be changed.
A standard database clone, (ie by copying the datafiles & re-creating the control files) creates a copy database with the same DBID as the original, an effect which causes numerous problems later with backup utilities such as RMAN.
This procedure describes how to clone a DB and change the DBID. In this example, our source DB is called SEED, the DB we want to create is named TRNG, and our recovery catalog DB is called RCAT. Before continuing, make sure all init.ora files are created, tnsnames.ora/listener.ora, and password files entries are created for all three databases. Also each init.ora file must have REMOTE_LOGIN_PASSWORD_FILE=exclusive as you will need to connect as internal remotely. Finally, make sure CONTROL_FILES is set to a different destination in initTRNG.ora.
0. Determine your Database character set, and set NLS_LANG properly. If you're using UTF8, then NLS_LANG must be AMERICAN_AMERICA.UTF8
1. Create a recovery catalog. This step is probably the most annoying. But the Clone process involves rman, and in order for rman to work, it needs a recovery catalog. A recovery catalog is small Oracle database which stores information about all backups. You can keep this DB VERY small (200M is fine), and it only requires a system tablespace. After creating the database, create a user called 'rman' and grant the following privs to it.
grant dba to rman; grant recovery_catalog_owner to rman;
Now startup rman and connect as this user:
rman connect rcvcat 'rman/rman'; create catalog; *(for O816 & O817 only)
* Note if you are on O815, the CREATE CATALOG doesn't exist, you must instead run $ORACLE_HOME/rdbms/admin/catrman.sql as rman.
The last command builds the recovery catalog tables in the rman schema. One this step is done, you're ready to start the clone.
2. Use rman to make a copy of the Source Database.
Set ORACLE_SID=SEED, shutdown SEED, bring it up in MOUNT mode. then execute the following:
$ rman connect target 'internal/kernel' connect rcvcat 'rman/rman@RCAT' run { allocate channel c1 type disk format '/u01/oradata/SEED/backup.dat'; backup (database); }
in the above example, substitute the string after the word "format" with the location you want the backup to be written. The TRNG database is actually created from the backup file, so after the backup is done, you can open SEED.
3. Set ORACLE_SID=TRNG, then startup the TRNG database in nomount mode. This should be VERY familiar to people that cloned the old fashioned way.
4. determine where you want the destination datafiles & logfiles to be placed based on file id number. Oracle stores each datafile in the database with a file_id, which tells the order the file was created. The first file of the SYSTEM tablespace, for example, is always file #1. You can get the file number from querying DBA_DATA_FILES
SQL> desc dba_data_files
Name Null? Type
------------------------------------- --------- -------------
FILE_NAME VARCHAR2(513)
FILE_ID NUMBER
TABLESPACE_NAME VARCHAR2(30)
BYTES NUMBER
BLOCKS NUMBER
STATUS VARCHAR2(9)
RELATIVE_FNO NUMBER
AUTOEXTENSIBLE VARCHAR2(3)
MAXBYTES NUMBER
MAXBLOCKS NUMBER
INCREMENT_BY NUMBER
USER_BYTES NUMBER
USER_BLOCKS NUMBER
SQL> select file_id, file_name from dba_data_files;
FILE_ID FILE_NAME
---------- ----------------------------------------
6 /u04/oradata/SEED/devl_SEED_01.dbf
5 /u04/oradata/SEED/users_SEED_01.dbf
4 /u04/oradata/SEED/tools_SEED_01.dbf
3 /u04/oradata/SEED/temp_SEED_01.dbf
2 /u04/oradata/SEED/rbs_SEED_01.dbf
1 /u04/oradata/SEED/system_SEED_01.dbf
now, let suppose our TRNG DB datafiles are to be created under /u05/oradata/TRNG. Then based on the above query...
datafile 1 of the target DB should have a name of /u05/oradata/TRNG/system_TRNG_01.dbf
datafile 2 should be named /u05/oradata/TRNG/rbs_TRNG_01.dbf,
and so forth.
MAKE SURE YOU GET THIS MAPPING RIGHT, OTHERWISE, your tablespace names won't match their filenames!
5. set ORACLE_SID=SEED, and run the following RMAN script after making the appropriate subsitutions for datafile & logfile mappings. Make sure to get your logfile size correct, otherwise this won't work.
connect target 'internal/kernel' connect rcvcat 'rman/rman@RCAT' connect auxiliary 'internal/kernel@TRNG' set auxname for datafile 1 to '/u05/oradata/TRNG/system_TRNG_01.dbf'; set auxname for datafile 3 to '/u05/oradata/TRNG/temp_TRNG_01.dbf'; set auxname for datafile 2 to '/u05/oradata/TRNG/rbs_TRNG_01.dbf'; set auxname for datafile 4 to '/u05/oradata/TRNG/users_TRNG_01.dbf'; set auxname for datafile 5 to '/u05/oradata/TRNG/devl_TRNG_01.dbf'; run { allocate auxiliary channel c1 type disk; allocate auxiliary channel c2 type disk; duplicate target database to TRNG logfile group 1 ('/u05/oradata/TRNG/log_TRNG_01.rdo') size 5M, group 2 ('/u05/oradata/TRNG/log_TRNG_02.rdo') size 5M, group 3 ('/u05/oradata/TRNG/log_TRNG_03.rdo') size 5M; }
Once this procedure is done, you will have a TRNG database with a different DBID from SEED!