The problem
When you need to create testing Oracle database environment, the best option is to have exactly same ORACLE_HOME that is in production. Unfortunately many running productions are heavily patched and if you do not have really proper documentation (many of us has inherited work from someone before), it is very hard to create exact clone of ORACLE_HOME by manual approach-installation from the beginning.From eBS 11.5.10.2, when "rapid clone" was properly implemented, Oracle APPS DBA's has a nice tool (in $ORACLE_HOME/clone directory) to do that regardless underlying ORACLE_HOME was 10g version. For classic 10g database installations, this was not possible.
In Oracle 11g, this functionality was ported to standalone database installations (non EBS) and DBA's can use it with great pleasure. And this saves DBA's life a lot.
The solution
The whole task is divided on source part (where original ORACLE_HOME is placed) and target part (where new, cloned ORACLE_HOME should be established).Environments
I'll explain how to clone ORACLE_HOME to different box (different server), different path...what covers any cloning situation that you may fall into!Source
Source define environment that will be used as source for cloning. In mine case this is vmcentosprod server. Mine "best practice" for Oracle on Linux is to have one ".env" file for each database in each ORACLE_HOME. In this case this is EUCHARIS.env file whose content is:#!/bin/sh TMP=/tmp; export TMP TMPDIR=$TMP; export TMPDIR ORACLE_HOSTNAME=vmcentos; export ORACLE_HOSTNAME ORACLE_BASE=/u01; export ORACLE_BASE ORACLE_SID=EUCHARIS; export ORACLE_SID export PS1="[\u $ORACLE_SID@\h \W]\$ " ORACLE_HOME=$ORACLE_BASE/EUCHARIS/eucharisdb/11.2; export ORACLE_HOME TNS_ADMIN=$ORACLE_HOME/network/admin; export TNS_ADMIN ORACLE_TERM=xterm; export ORACLE_TERM PATH=${PATH}:$HOME/bin:$ORACLE_HOME/bin; export PATH PATH=${PATH}:/usr/bin:/bin:/usr/bin/X11:/usr/local/bin:/sbin; export PATH LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib:/usr/local/bin export LD_LIBRARY_PATH CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib:$ORACLE_HOME/network/jlib; export CLASSPATH THREADS_FLAG=native; export THREADS_FLAG alias q="rlwrap $ORACLE_HOME/bin/sqlplus" export SQLPATH="/home/oracle/admin_scripts" DB_NAME=EUCHARIS; export DB_NAMESo most important values for cloning are:
ORACLE_BASE=/u01 ORACLE_HOME=/u01/EUCHARIS/eucharisdb/11.2 ORACLE_HOSTNAME=vmcentosprod ORACLE_SID=EUCHARIS
Target
Target server is vmcentos. New EUCARIS.env was done by sarch/replace of original EUCHARIS.env file and changing just one value for ORACLE_BASE from "u01" to "/u02". Here is the whole content of new EUCARIS.env file:#!/bin/sh TMP=/tmp; export TMP TMPDIR=$TMP; export TMPDIR ORACLE_HOSTNAME=vmcentos; export ORACLE_HOSTNAME ORACLE_BASE=/u02; export ORACLE_BASE ORACLE_SID=EUCARIS; export ORACLE_SID export PS1="[\u $ORACLE_SID@\h \W]\$ " ORACLE_HOME=$ORACLE_BASE/EUCARIS/eucarisdb/11.2; export ORACLE_HOME TNS_ADMIN=$ORACLE_HOME/network/admin; export TNS_ADMIN ORACLE_TERM=xterm; export ORACLE_TERM PATH=${PATH}:$HOME/bin:$ORACLE_HOME/bin; export PATH PATH=${PATH}:/usr/bin:/bin:/usr/bin/X11:/usr/local/bin:/sbin; export PATH LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib:/usr/local/bin export LD_LIBRARY_PATH CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib:$ORACLE_HOME/network/jlib; export CLASSPATH THREADS_FLAG=native; export THREADS_FLAG alias q="rlwrap $ORACLE_HOME/bin/sqlplus" export SQLPATH="/home/oracle/admin_scripts" DB_NAME=EUCARIS; export DB_NAMESo most important values for target are:
ORACLE_BASE=/u02 ORACLE_HOME=/u02/EUCARIS/eucarisdb/11.2 ORACLE_HOSTNAME=vmcentos ORACLE_SID=EUCARISAs you see we have totally different environments: different box and different path (notice that "h" is missing in target string EUCHARIS->EUCARIS, eucharisdb->eucarisdb). Not to mention that duplicated database will also have different name but this is over the scope of this article.
Just to mention that on both servers, owner of "/u01" and "/u02" directories is oracle user, which is in dba group. DBA group is used for installation as well for active work. If this is not your case then adopt it.
1. Tarring source ORACLE_HOME
First step is to create tar of whole ORACLE_HOME on source server[oracle@vmcentosprod u01]$ cd /u01/EUCHARIS/eucharisdb/ [oracle@vmcentosprod eucharisdb]$ tar cvf eucharis.tar /u01/EUCHARIS/eucharisdb/11.2 11.2/ 11.2/crs/ 11.2/crs/sbs/ 11.2/crs/sbs/clsrwrap.sbs 11.2/crs/sbs/localconfig.sbs ... u01/EUCHARIS/eucharisdb/11.2/sqlplus/admin/pupbld.sql u01/EUCHARIS/eucharisdb/11.2/sqlplus/admin/plustrce.sql u01/EUCHARIS/eucharisdb/11.2/dc_ocm/ u01/EUCHARIS/eucharisdb/11.2/dc_ocm/clean_cron_proc.sh [oracle@vmcentosprod eucharisdb]$
2. Copy eucharis.tar file to target server
[oracle@vmcentosprod eucharisdb]$ scp -rp eucharis.tar oracle@vmcentos:/u02If you are creating ORACLE_HOME on the same server then this step may be skipped!
3. Unpack eucharis.tar file on target server
On target server in /u02 directory create EUCARIS directory and position in it.[oracle@vmcentos eucharisdb]$ mkdir /u02/EUCARIS [oracle@vmcentos eucharisdb]$ cd /u02/EUCARIS/Untar, previously copied eucharis.tar file:
[oracle@vmcentos EUCARIS]$ tar xvf /u02/eucharis.tar u01/EUCHARIS/eucharisdb/11.2/ u01/EUCHARIS/eucharisdb/11.2/crs/ u01/EUCHARIS/eucharisdb/11.2/crs/sbs/ ... u01/EUCHARIS/eucharisdb/11.2/sqlplus/admin/plustrce.sql u01/EUCHARIS/eucharisdb/11.2/dc_ocm/ u01/EUCHARIS/eucharisdb/11.2/dc_ocm/clean_cron_proc.sh [oracle@vmcentos EUCARIS]$As you see mine practice is to keep full path from source...what saves me sometimes in careless unpacking.
Last is to move unpacked "11.2" directory with it's content to proper place.
[oracle@vmcentos EUCARIS]$ mkdir /u02/EUCARIS [oracle@vmcentos EUCARIS]$ mkdir /u02/EUCARIS/eucarisdb [oracle@vmcentos EUCARIS]$ mv /u02/EUCARIS/u01/EUCHARIS/eucharisdb/11.2/ /u02/EUCARIS/eucarisdb/Checking that all is consistent on target side (user, date, owner):
[oracle@vmcentos EUCARIS]$ cd /u02/EUCARIS/eucarisdb/11.2 [oracle@vmcentos 11.2]$ ll total 316 drwxr-xr-x 3 oracle dba 4096 Apr 7 11:00 admin drwxr-xr-x 8 oracle dba 4096 Jul 1 10:02 apex drwxr-xr-x 8 oracle dba 4096 Apr 7 10:50 assistants drwxr-xr-x 2 oracle dba 12288 Apr 7 11:17 bin drwxr-xr-x 7 oracle dba 4096 Apr 7 11:03 ccr drwxr-xr-x 3 oracle dba 4096 Apr 7 11:04 cdata drwxr-xr-x 4 oracle dba 4096 Apr 7 11:17 cfgtoollogs drwxr-xr-x 4 oracle dba 4096 Apr 7 10:58 clone drwxr-xr-x 2 oracle dba 4096 Apr 7 11:04 config drwxr-xr-x 6 oracle dba 4096 Apr 7 10:50 crs drwxr-xr-x 3 oracle dba 4096 Apr 7 10:50 csmig drwxr-xr-x 6 oracle dba 4096 Apr 7 11:04 css drwxr-xr-x 10 oracle dba 4096 Apr 7 11:05 ctx drwxr-xr-x 6 oracle dba 4096 Apr 7 10:50 cv drwxr-xr-x 4 oracle dba 4096 Jul 9 07:29 dbs drwxr-xr-x 2 oracle dba 4096 Apr 7 11:01 dc_ocm drwxr-xr-x 4 oracle dba 4096 Apr 7 11:08 deinstall drwxr-xr-x 3 oracle dba 4096 Apr 7 10:50 demo drwxr-xr-x 3 oracle dba 4096 Apr 7 10:50 diagnostics drwxr-xr-x 4 oracle dba 4096 Apr 7 10:50 dv drwxr-xr-x 3 oracle dba 4096 Apr 7 10:50 emcli drwxr-xr-x 3 oracle dba 4096 Apr 7 10:50 has drwxr-xr-x 5 oracle dba 4096 Apr 7 11:08 hs drwxr-xr-x 8 oracle dba 4096 Apr 7 10:50 ide drwxr-xr-x 8 oracle dba 4096 Apr 7 11:17 install -rw-r--r-- 1 oracle dba 37 Apr 7 10:50 install.platform drwxr-xr-x 2 oracle dba 4096 Apr 7 10:55 instantclient drwxr-x--- 13 oracle dba 4096 Apr 7 11:16 inventory drwxr-xr-x 4 oracle dba 4096 Apr 7 10:59 j2ee drwxr-xr-x 8 oracle dba 4096 Apr 7 10:50 javavm drwxr-xr-x 3 oracle dba 4096 Apr 7 11:02 jdbc drwxr-xr-x 4 oracle dba 4096 Apr 7 10:50 jdev drwxr-xr-x 6 oracle dba 4096 Apr 7 11:02 jdk drwxr-xr-x 2 oracle dba 4096 Apr 7 11:01 jlib drwxr-xr-x 12 oracle dba 4096 Apr 7 11:04 ldap drwxr-xr-x 4 oracle dba 12288 Apr 7 11:08 lib drwxr-xr-x 4 oracle dba 4096 Apr 7 12:34 log drwxr-xr-x 6 oracle dba 4096 Apr 7 10:50 md drwxr-xr-x 2 oracle dba 4096 Apr 7 10:54 mesg drwxr-xr-x 6 oracle dba 4096 Apr 7 11:04 mgw drwxr-xr-x 11 oracle dba 4096 Apr 7 11:08 network drwxr-xr-x 6 oracle dba 4096 Apr 7 10:50 nls drwxr-xr-x 20 oracle dba 4096 Apr 7 10:55 oc4j -rw------- 1 oracle dba 1772 Apr 7 11:04 ocm.rsp drwxr-xr-x 6 oracle dba 4096 Apr 7 10:50 odbc drwxr-xr-x 5 oracle dba 4096 Apr 7 10:50 olap drwxr-xr-x 5 oracle dba 4096 Apr 7 10:50 ons drwxr-xr-x 6 oracle dba 4096 Apr 7 11:03 OPatch drwxr-xr-x 7 oracle dba 4096 Apr 7 11:04 opmn drwxr-xr-x 4 oracle dba 4096 Apr 7 10:50 oracore -rw-r----- 1 oracle dba 43 Apr 7 10:50 oraInst.loc drwxr-xr-x 8 oracle dba 4096 Apr 7 10:50 ord drwxr-xr-x 7 oracle dba 4096 Apr 7 11:03 oui drwxr-xr-x 26 oracle dba 4096 Apr 7 11:04 owb drwxr-xr-x 4 oracle dba 4096 Apr 7 10:50 owm drwxr-xr-x 5 oracle dba 4096 Apr 7 11:08 perl drwxr-xr-x 6 oracle dba 4096 Apr 7 10:50 plsql drwxr-xr-x 7 oracle dba 4096 Apr 7 10:50 precomp drwxr-xr-x 7 oracle dba 4096 Apr 7 11:04 racg drwxr-xr-x 13 oracle dba 4096 Apr 7 11:08 rdbms drwxr-xr-x 4 oracle dba 4096 Apr 7 11:02 relnotes -rwxr-x--- 1 oracle dba 458 Apr 7 11:08 root.sh drwxr-xr-x 4 oracle dba 4096 Apr 7 10:50 scheduler drwxr-xr-x 3 oracle dba 4096 Apr 7 10:50 slax drwxr-xr-x 13 oracle dba 4096 Apr 7 11:00 sqldeveloper drwxr-xr-x 3 oracle dba 4096 Apr 7 10:50 sqlj drwxr-xr-x 7 oracle dba 4096 Apr 7 11:07 sqlplus drwxr-xr-x 10 oracle dba 4096 Apr 7 11:04 srvm drwxr-xr-x 15 oracle dba 4096 Apr 7 11:04 sysman drwxr-xr-x 2 oracle dba 4096 Apr 7 10:58 timingframework drwxr-xr-x 3 oracle dba 4096 Apr 7 11:02 ucp drwxr-xr-x 4 oracle dba 4096 Apr 7 10:50 uix drwxr-xr-x 2 oracle dba 4096 Apr 7 10:54 utl drwxr-xr-x 3 oracle dba 4096 Apr 7 10:50 wwg drwxr-xr-x 7 oracle dba 4096 Apr 7 10:55 xdk [oracle@vmcentos 11.2]$ pwd /u02/EUCARIS/eucarisdb/11.2 [oracle@vmcentos 11.2]$
4. clone.pl
Now it is time to assign EUCARIS.env (new environement script from target server) which will define all needed for next steps.Because we have moved files to different directory and different server, many Oracle paths are wrong. Beside that many libraries point to invallid place what will prevent Oracle form normal functioning. So this will be fixed with clone.pl script, which is placed in $ORACLE_HOME/clone/bin directory:
[oracle EUCARIS@vmcentos ~]$ cd /u02/EUCARIS/eucarisdb/11.2/clone/bin [oracle EUCARIS@vmcentos ~]$ pwd /u02/EUCARIS/eucarisdb/11.2/clone/bin [oracle EUCARIS@vmcentos bin]$ perl clone.pl ORACLE_HOME=$ORACLE_HOME ORACLE_BASE=$ORACLE_BASE ./runInstaller -clone -waitForCompletion "ORACLE_HOME=/u02/EUCARIS/eucarisdb/11.2" "ORACLE_BASE=/u02" -defaultHomeName -silent -noConfig -nowait Starting Oracle Universal Installer... Checking swap space: must be greater than 500 MB. Actual 4031 MB Passed Preparing to launch Oracle Universal Installer from /tmp/OraInstall2010-07-09_10-45-46AM. Please wait ...Oracle Universal Installer, Version 11.2.0.1.0 Pr oduction Copyright (C) 1999, 2009, Oracle. All rights reserved. You can find the log of this install session at: /oraInventory/logs/cloneActions2010-07-09_10-45-46AM.log .................................................................................................... 100% Done. Installation in progress (Friday, July 9, 2010 10:46:21 AM GMT-01:00) .............................................................................. 78% Done. Install successful Linking in progress (Friday, July 9, 2010 10:46:37 AM GMT-01:00) Link successful Setup in progress (Friday, July 9, 2010 10:48:43 AM GMT-01:00) Setup successful End of install phases.(Friday, July 9, 2010 10:54:04 AM GMT-01:00) Starting to execute configuration assistants The following configuration assistants have not been run. This can happen because Oracle Universal Installer was invoked with the -noConfig option. -------------------------------------- The "/u02/EUCARIS/eucarisdb/11.2/cfgtoollogs/configToolFailedCommands" script contains all commands that failed, were skipped or were cancelled. This file may be used to run these configuration assistants outside of OUI. Note that you may have to update this script with passwords (if any) before executing t he same. The "/u02/EUCARIS/eucarisdb/11.2/cfgtoollogs/configToolAllCommands" script contains all commands to be executed by the configuration assistants. This file may be used to run the configuration assistants outside of OUI. Note that you may have to update this script with passwords (if any) before executing the same. -------------------------------------- WARNING: The following configuration scripts need to be executed as the "root" user. /u02/EUCARIS/eucarisdb/11.2/root.sh To execute the configuration scripts: 1. Open a terminal window 2. Log in as "root" 3. Run the scripts The cloning of OraHome1 was successful. Please check '/oraInventory/logs/cloneActions2010-07-09_10-45-46AM.log' for more details. [oracle EUCARIS@vmcentos bin]$
5. root.sh script
In "/oraInventory/logs/cloneActions2010-07-09_10-45-46AM.log" file, at the very end, there is a notice that you have to run in new ORACLE_HOME (/u02/EUCARIS/eucarisdb/11.2/) as root "root.sh" script.[root@vmcentos 11.2]# sh /u02/EUCARIS/eucarisdb/11.2/root.sh Check /u02/EUCARIS/eucarisdb/11.2/install/root_vmcentos_2010-07-09_10-58-32.log for the output of root script [root@vmcentos 11.2]#Check log /u02/EUCARIS/eucarisdb/11.2/install/root_vmcentos_2010-07-09_10-58-32.log
[root@vmcentos 11.2]# cat /u02/EUCARIS/eucarisdb/11.2/install/root_vmcentos_2010-07-09_10-58-32.log Running Oracle 11g root.sh script... The following environment variables are set as: ORACLE_OWNER= oracle ORACLE_HOME= /u02/EUCARIS/eucarisdb/11.2 Entries will be added to the /etc/oratab file as needed by Database Configuration Assistant when a database is created Finished running generic part of root.sh script. Now product-specific root actions will be performed. Finished product-specific root actions.All looks good!
6. Check oraInventory
Because we want cloned ORACLE_HOME to act as any other "normaly" created ORACLE_HOME, it should be properly registered in Oracle Inventory. So let us check it's content. In mine case oraInventory was located:[oracle EUCHARIS@vmcentos ~]$ cat /oraInventory/oraInst.loc inventory_loc=/oraInventory inst_group=dbaSo let us check main file inventory.xml:
[oracle EUCHARIS@vmcentos ContentsXML]$ cat /oraInventory/ContentsXML/inventory.xml <?xml version="1.0" standalone="yes" ?> <!-- Copyright (c) 1999, 2009, Oracle. All rights reserved. --> <!-- Do not modify the contents of this file by hand. --> <INVENTORY> <VERSION_INFO> <SAVED_WITH>11.2.0.1.0</SAVED_WITH> </MINIMUM_VER>2.1.0.6.0</MINIMUM_VER> </VERSION_INFO> <HOME_LIST> <HOME NAME="OraDb11g_home1" LOC="/u01/UAT/uatdb/11.2" TYPE="O" IDX="1"/> <HOME NAME="OraHome1" LOC="/u02/EUCARIS/eucarisdb/11.2" TYPE="O" IDX="2"/> </HOME_LIST> </INVENTORY>As you see beside UAT database, which was on target server before clonig (ORACLE_HOME_NAME="OraDb11g_home1") we have successfully added cloned ORACLE_HOME with ORACLE_HOME_NAME="OraHome1". This name is default because we didn't set it in clone.pl script parameter.
The end
One of the most important characteristic, of cloned ORACLE_HOME in explained way, is that it can be done on the same server as well. Only one path has to be different.And the best of all, while source is cloned all database inside source ORACLE_HOME may be up and running without any problems what give us possibility to clone any production whenever we want.
Cheers!