Restore Oracle database by using RMAN duplicate in Oracle 12c
by Pradeep Rai, Oracle Database Administrator, Rackspace Technology
Introduction
Oracle® Recovery Manager (RMAN) is a tool that can duplicate or clone a database from a backup or from an active database. RMAN can create a duplicate database on a remote server with the same file structure, on a remote server with a different file structure, or on a local server with a different file structure. Recovery Manager (RMAN) is a tool that can duplicate or clone a database from a backup or from an active database. RMAN can create a duplicate database on a remote server with the same file structure, on a remote server with a different file structure, or on a local server with a different file structure.
When you receive any request to refresh the Oracle target database from any source available:
- First, ask the application team for the backup location of the source database, if they had previously asked to preserve any backup of the source database. If an existing backup is not available, then confirm with the application team if you need to back up the source database now when the request comes in. After you've confirmed when to take a backup, you can use the following script to back up the source database.
- Ask the application team to provide any specific post-refresh tasks.
- Transfer the source backup to the target server in your specific location.
If the source database must continue to run while being backed up, use the script for a hot backup. If the source database is able to stop running for the backup, use the script for a cold backup.
Create a new file called rman_full_HOT_DATABASENAME.sh and paste the following script into it:
export ORACLE_HOME=Correct_ORACLE_HOME
export ORACLE_SID=Correct_ ORACLE SID
export PATH=$PATH:$ORACLE_HOME/bin
export LOG=Correct_ Log_Loaction/rman_HOT_DATABASENAME_backup.log
rman target / <<EOF>>$LOG
run
{
allocate channel ch1 type disk maxpiecesize 4048M format '/backup/RMAN/DATABASENAME/DATABASENAME_HOT_backup_%U.bak';
allocate channel ch2 type disk maxpiecesize 4048M format '/backup/RMAN/DATABASENAME/DATABASENAME_HOT_backup_%U.bak';
allocate channel ch3 type disk maxpiecesize 4048M format '/backup/RMAN/DATABASENAME/DATABASENAME_HOT_backup_%U.bak';
backup as compressed backupset database TAG 'DONOTDELETE_ITKnumber';
backup AS COMPRESSED BACKUPSET archivelog all format '/backup/RMAN/DATABASENAME/DATABASENAME_ARC_BACKUP_%d_%u_%p_%s.bak';
backup current controlfile format '/backup/RMAN/DATABASENAME/DATABASENAME_HOT_backup_CTL_%d%s%t_%U.bak';
release channel ch1;
release channel ch2;
release channel ch3;
}
exit
EOF
Use the following command to run the script:
$ nohup sh rman_full_HOT_DATABASENAME.sh &
Cold backup
**Note**: For a cold backup, there is no need to take a backup of the archive log and the application should be down before starting the backup process.
Create a new file called rman_full_COLD_DATABASENAME.sh and paste the following script into it:
export ORACLE_HOME=Correct_ORACLE_HOME
export ORACLE_SID=Correct_ORACLE_SID
export PATH=$PATH:$ORACLE_HOME/bin
export LOG=Correct Log Loaction/rman_COLD_DATABASENAME_backup.log
rman target / <<EOF>>$LOG
run
{
allocate channel ch1 type disk maxpiecesize 4048M format '/backup/RMAN/DATABASENAME/DATABASENAME_COLD_backup_%U.bak';
allocate channel ch2 type disk maxpiecesize 4048M format '/backup/RMAN/DATABASENAME/DATABASENAME_COLD_backup_%U.bak';
allocate channel ch3 type disk maxpiecesize 4048M format '/backup/RMAN/DATABASENAME/DATABASENAME_COLD_backup_%U.bak';
backup as compressed backupset database TAG 'ticketnumber';
backup current controlfile format '/backup/RMAN/DATABASENAME/DATABASENAME_COLD_backup_CTL_%d%s%t_%U.bak';
release channel ch1;
release channel ch2;
release channel ch3;
}
exit
EOF
Use the following command to run the script:
$ nohup sh rman_full_COLD_DATABASENAME.sh &
Pre-refresh tasks
Now you can perform the following re-refresh tasks on the target database:
- Preserve all SQL profiles
- Preserve all DB links
- Preserve all synonyms
- Preserve all user passwords
- Preserve all grant/object, Grant/system, and Grant/roles
- Preserve all general information
- Copy pfile and spfile in the specific directory per your requirement
- Edit the correct value for the `logfile_name_convert` parameter and the`db_file_name_convert` parameter. Also check the value of `undo_tablespace` and make sure that it is defined the same in the target as the source database.
- Prepare the script to clone the database
Preserve all SQL profiles
First, check whether any SQL profiles are present on the target database by using the following command:
SQL> select count(*) from dba_sql_profiles;
If the count is zero, then you don't need to perform the following steps to preserve SQL profiles. If the **count** is more than zero, then SQL profiles are present and you need to preserve them by using the following steps:
Step 1
grant dba to TEST identified by password;
Step 2
CONN TEST/password
Step 3
BEGIN
DBMS_SQLTUNE.CREATE_STGTAB_SQLPROF (table_name => 'SQL_PROFILES3',schema_name=>'SYSTEM');
END;
/
Step 4
BEGIN
DBMS_SQLTUNE.PACK_STGTAB_SQLPROF
(profile_category => '%',
staging_table_name => 'SQL_PROFILES3',
staging_schema_owner=>'SYSTEM');
END;
/
Step 5
select count(*) from SYSTEM.sql_profiles3;
Step 6
expdp TEST/password directory=expdp dumpfile=expdp_sql_profiles.dmp TABLES=SYSTEM.SQL_PROFILES3 logfile=expdp_sql_profiles.log
Import and unpack SQL profiles
Use the following steps to import and then unpack the SQL profiles:
Note: After the target database is restored, you must perform the following steps in the target database.
Step 1
grant dba to TEST identified by password;
Step 2
impdp TEST/password dumpfile=expdp_sql_profiles.dmp TABLES=SYSTEM.SQL_PROFILES3 DIRECTORY=expdp TABLE_EXISTS_ACTION=REPLACE logfile=impdp_sql_profiles.log
Step 3
BEGIN
DBMS_SQLTUNE.UNPACK_STGTAB_SQLPROF
(staging_table_name => 'SQL_PROFILES3',
staging_schema_owner=>'SYSTEM', replace=>TRUE);
END;
/
Preserve all DB links
Create a file called dblink.sh and paste the following script into it:
export ORACLE_HOME=Correct _ORACLE_HOME
export ORACLE_SID=Correct_ ORACLE_SID
expdp \'/ as sysdba\' directory=expdp dumpfile=dblink.dmp full=y content=metadata_only include=db_link logfile=expdp_dblink.log
Then run the following command to execute the script:
$ nohup sh dblink.sh &
Preserve all synonyms
Create a file called Synonyms_query.sql and paste the following SQL script
into it:
Spool synonyms.sql
set pages 10000
set long 999999
set linesize 450
SELECT DBMS_METADATA.GET_DDL('SYNONYM', SYNONYM_NAME, OWNER) || ';' "output" FROM dba_synonyms where table_owner not in('SYS','SYSTEM','DBSNMP','ORACLE_OCM','MDSYS','OLAPSYS','ORDSYS','WMSYS','ANONYMOUS','CTXSYS','OUTLN','SI_INFORMTN_SCHEMA','SYSMAN','EXFSYS','XDB','DMSYS');
Spool off
Then run the following command to execute the script:
$ nohup sqlplus / as sysdba @Synonyms_query.sql > Synonyms_query.log &
Export method
Create a file called synonyms.sh and paste the following script into it:
export ORACLE_HOME=Correct ORACLE HOME
export ORACLE_SID=Correct_ORACLE SID
expdp \'/ as sysdba\' directory=expdp dumpfile=SYNONYMS.dmp logfile=expdp_SYNONYMS.log FULL=y CONTENT=METADATA_ONLY INCLUDE=PUBLIC_SYNONYM/SYNONYM
Then run the following command to execute the script:
$ nohup sh synonyms.sh &
Preserve all user passwords
Create a file called usders_password.sql and paste the following script into it:
Spool password.sql
COL ColumnName FORMAT A32000
set pagesize 2000
set pages 0
column output format a300
set line 300
set long 100000
select
'alter user '||u.username||' identified by values '''||s.spare4||''';' cmd
from dba_users u
join sys.user$ s
on u.user_id = s.user#
where u.username in (select username from dba_users where ORACLE_MAINTAINED='N')
/
Spool off
Then run the following command to execute the script:
$ nohup sqlplus / as sysdba @usders_password.sql > usders_password.log &
Preserve all grant/object, Grant/system, and Grant/roles
Create a file called grant.sh and paste the following script into it:
export ORACLE_HOME=Correct_ORACLE HOME
export ORACLE_SID=Correct_ORACLE SID
expdp \'/ as sysdba\' directory= expdp dumpfile=URG.dmp logfile=expdp_URG.log FULL=y CONTENT=METADATA_ONLY INCLUDE=USER,ROLE,ROLE_GRANT,PROFILE
Then run the following command to execute the script:
$ nohup sh grant.sh &
Preserve all general information
Create a file called prerefresh.sql and paste the following script into it:
Note: Change `correct_location` as per your requirement.
spool pre_clone_info_$ORACLE_SID.log
alter database backup controlfile to trace as 'correct_loactionlocation/ctrl$ORACLE_SID.sql';
SELECT name,database_role, open_mode FROM v$database;
-- select name,open_mode from v$pdbs;
archive log list
show parameter pfile
show parameter control_files
set pages 10000
set serveroutput on size 1000000 long 1000000
SELECT DBMS_METADATA.GET_DDL('DB_LINK',a.db_link,a.owner) || ';' "output" FROM dba_db_links a;
col OWNER for a20
col DB_LINK for a25
col USERNAME for a20
col HOST for a35
select * from dba_db_links;
set lines 200
col DIRECTORY_NAME for a40
col DIRECTORY_PATH for a110
select * from dba_directories;
select 'create or replace directory '||DIRECTORY_NAME||' as '''||DIRECTORY_PATH||''';' from dba_directories;
set long 20000 longchunksize 20000 pagesize 0 linesize 1000 feedback off verify off trimspool on
set lines 300 pages 200
col FILE_NAME for a60;
select file_name,tablespace_name,bytes/1024/1024,status from dba_data_files;
select file_name,tablespace_name,bytes/1024/1024,status from dba_temp_files;
select tablespace_name from dba_tablespaces;
set lines 300
select username from dba_users;
select name from v$controlfile;
set lines 200 pages 200
select * from v$logfile;
select * from v$log;
select substr(name,1,instr(name,'/',-1)) from v$datafile
union
select substr(name,1,instr(name,'/',-1)) from v$tempfile
union
select substr(member,1,instr(member,'/',-1)) from v$logfile
union
select substr(name,1,instr(name,'/',-1)) from v$controlfile;
show parameter utl
spool off
Then run the following command to execute the script:
$ nohup sqlplus / as sysdba @prerefresh.sql > prerefresh.log &
Copy pfile and spfile
Copy the pfile and spfile from the source database. You need to edit the correct value for the `logfile_name_convert` and
`db_file_name_convert` parameters then also check the value of `undo_tablespace`.
Use the following query on the source database and the target database:
set lines 200 pages 200
select distinct substr(name,1,instr(name,'/',-1)) from v$datafile;
select distinct substr(member,1,instr(member,'/',-1)) from v$logfile;
According to the output you receive, edit the following parameters in the
pfile that you copied with your specific requirements:
Note: Be sure to take a backup of the original pfile before making any changes.
.db_file_name_convert='path1_of_source_datafile',’path1_of_trget_datafile’, 'path2_of_source_datafile',’path2_of_trget_datafile’,
*.log_file_name_convert='path1_of_source_logile',’path1_of_trget_logfile, 'path2_of_source_logfile',’path2_of_trget_logfile’,
Next, check the parameter `undo_tablespace` in both the source and target databases by using the following command:
SQL> show parameters undo_tablespace
If the output is different in the target database, you must update the `undo_tablespace` parameter to match the value in the source database.
Prepare a script to clone the database
If you used a hot backup
Create a file called rman_dup.sh and paste the following script into it:
export ORACLE_HOME=Correct_ORACLE_HOME
export ORACLE_SID=Correct_ORACLE SID
export PATH=$ORACLE_HOME/bin:$PATH
rman AUXILIARY / cmdfile=rman_duplicate_script.scr msglog=rman_duplicate_script.log
Next, create another new file called rman_duplicate_script.scr and paste
the following script into it:
run {
allocate auxiliary channel aux1 device type disk;
allocate auxiliary channel aux2 device type disk;
allocate auxiliary channel aux3 device type disk;
DUPLICATE DATABASE TO Target_db_name BACKUP LOCATION 'Loaction_of_backup_of_source database' nofilenamecheck;
release channel aux1;
release channel aux2;
release channel aux3;
}
If you used a cold backup
Create a file called rman_dup.sh and paste the following script into it:
export ORACLE_HOME=Correct_ORACLE_HOME
export ORACLE_SID=Correct_ORACLE SID
export PATH=$ORACLE_HOME/bin:$PATH
rman AUXILIARY / cmdfile=rman_duplicate_script.scr msglog=rman_duplicate_script.log
Next, create another new file called rman_duplicate_script.scr and paste the following script into it:
run {
allocate auxiliary channel aux1 device type disk;
allocate auxiliary channel aux2 device type disk;
allocate auxiliary channel aux3 device type disk;
allocate auxiliary channel aux9 device type disk;
DUPLICATE DATABASE TO Target_db_name BACKUP BACKUP LOCATION 'Loaction_of_backup_of_source database' nofilenamecheck noredo;
release channel aux1;
release channel aux2;
release channel aux3;
}
Start the target database
Start the target database
Start the target database by using the following steps:
1. Use the following command to start the target database in the mount mode by
using restrict:
SQL> startup mount restrict;
2. Next, drop the target database by using the following command:
SQL> DROP DATABASE
Note: Before dropping the target database, be sure the application is down or you have the proper go-ahead from the application. Reach out to the application team if you aren't sure.
3. Start the target database in nomount mode using the pfile that you edited with the correct do_file_name_convert, log_file_name_convert, and undo_tablespace` parameters.
4. Verify the parameters in the target database by using the following commands:
show parameter db_file
show parameter log_file
show parameter db_name
show parameter undo
5. Use the script that you created in the previous section to clone the database
and check the log:
$ nohup sh rman_dup.sh &
6. After the cloning process is complete, open the database in read/write mode.
Shut down the target database and copy the original pfile and spfile
at the default location ($ORACLE_HOME/dbs).
7. Start the target database again and check the parameters showing the parameter
`spfile`. It should point to the default location.
8. Start the post-refresh tasks.
Post-refresh tasks
Use the following steps after you refresh the database:
1. Import SQL profiles by using the steps in the
Import and unpack the SQL profiles section.
2. Import DB links.
Before you import the DB links, be sure to remove all private and public DB links from the target database. Use the dump file that you preserved in the Preserve all DB links section.
For example:
impdp \'/ as sysdba\' directory=expdp dumpfile=dblink.dmp logfile=impdp_dblink.log
3. Reset the passwords of all users to the passwords that you preserved from the source database.
4. Hand over the database to the application team.
Conclusion
With the help of this blog you can easily clone your Oracle database by using RMAN duplicate. RMAN duplicate not only makes your work very easy but faster as well. The steps explained above can duplicate your database using any backup. However, it is important to note that the above steps do not explain duplicating databases by using the ACTIVE database method.

Recent Posts
Informe sobre el estado de la nube en 2025
Enero 10th, 2025
Patrones de redes híbridas de Google Cloud - Parte 2
Octubre 16th, 2024
Patrones de redes híbridas de Google Cloud - Parte 2
Octubre 15th, 2024
Cómo aprovecha Rackspace AWS Systems Manager
Octubre 9th, 2024
Windows Server impide la sincronización horaria con Rackspace NTP
Octubre 3rd, 2024