Oracle RMAN工具工作环境一共有三个数据库源对象:target、catalog和auxiliary。
target就是进行备份操作的源数据库,我们进行备份还原的对象都是在这个库上进行。默认情况下,备份集合信息是保存在controlfile,catalog是一个可选数据库,备份元数据可以单独放在catalog数据库中保存。auxiliary是作为辅助操作进行的,一些与备份还原相关的操作,都可以利用auxiliary上完成。
本篇从10g数据库入手,实验在相同host上构建不同名clone数据库。注意:在其他主机上进行clone操作完全相同。
1、环境介绍
我们选择Oracle 10gR2进行测试,Linux环境主机。
SQL> select * from v$version;
BANNER
---------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production
2、Target数据库备份
当前数据库没有选择catalog,采用controlfile进行备份文件。数据库实例名称为oratest,作为数据源。此时备份信息如下:
RMAN> list backup;
List of Backup Sets
===================
BS Key Type LV Size Device Type Elapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ ---------------
13 Full 595.90M DISK 00:00:30 05-MAR-14
BP Key: 13 Status: AVAILABLE Compressed: NO Tag: TAG20140305T111526
Piece Name: /u01/app/oracle/flash_recovery_area/ORATEST/backupset/2014_03_05/o1_mf_nnndf_TAG20140305T111526_9kf5pgf2_.bkp
(篇幅原因,有省略……)
BS Key Size Device Type Elapsed Time Completion Time
------- ---------- ----------- ------------ ---------------
15 15.07M DISK 00:00:02 05-MAR-14
BP Key: 15 Status: AVAILABLE Compressed: NO Tag: TAG20140305T112405
Piece Name: /u01/app/oracle/flash_recovery_area/ORATEST/backupset/2014_03_05/o1_mf_annnn_TAG20140305T112405_9kf66ppv_.bkp
List of Archived Logs in backup set 15
Thrd Seq Low SCN Low Time Next SCN Next Time
---- ------- ---------- --------- ---------- ---------
1 2 576174 04-MAR-14 578638 05-MAR-14
1 3 578638 05-MAR-14 578643 05-MAR-14
1 4 578643 05-MAR-14 578677 05-MAR-14
BS Key Type LV Size Device Type Elapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ ---------------
16 Full 6.80M DISK 00:00:01 05-MAR-14
BP Key: 16 Status: AVAILABLE Compressed: NO Tag: TAG20140305T112407
Piece Name: /u01/app/oracle/flash_recovery_area/ORATEST/autobackup/2014_03_05/o1_mf_s_841404247_9kf66qvs_.bkp
Control File Included: Ckp SCN: 578684 Ckp time: 05-MAR-14
SPFILE Included: Modification time: 05-MAR-14
注意:在备份过程中,一定要有一个单独的backup archivelog all的过程,将归档日志作为单独备份集合保存。如果不进行这个操作,在进行duplicate过程中会出现错误。
RMAN> backup archivelog all;
Starting backup at 05-MAR-14
(篇幅原因,有省略……)
Starting Control File and SPFILE Autobackup at 05-MAR-14
piece handle=/u01/app/oracle/flash_recovery_area/ORATEST/autobackup/2014_03_05/o1_mf_s_841404247_9kf66qvs_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 05-MAR-14
在进行duplicate操作过程中,target数据库最好维持mount状态!
3、网络配置
无论是在本机还是异地进行duplicate构建,保证target和auxiliary互联是重要的。所以在TNS连接方面,要进行配置过程。
Oracle Net配置三个文件,listener.ora、tnsnames.ora和sqlnet.ora。起码要保证tnsnames.ora的互联配置。
[oracle@SimpleLinuxUp admin]$ cat tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/10.2.0/db_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.
ORATEST = --target
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = oratest)
)
)
ORAAUX = --目标auxiliary
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = oraaux)
)
)
一些文献(包括官方MOS文章)都推荐额外进行listener.ora的配置,将两个服务作为静态注册注册进监听程序listener。这样做的基础是这样的:在进行duplicate过程中,如果我们是从target端进行操作,就需要通过auxiliary端的监听器访问auxiliary。而此时auxiliary只有一个实例对象,虽然可以动态注册,但是注册状态是blocked。
Service "oraaux" has 1 instance(s).
Instance "oraaux", status BLOCKED, has 1 handler(s) for this service...
从9i到11g,Blocked状态是不允许进行远程连入的。当我们试图通过监听器连入的时候,是会报错。
MAN> connect auxiliary sys/oracle@oraaux
RMAN-00571: =============================
RMAN-00569: ========= ERROR MESSAGE STACK FOLLOWS =====
RMAN-00571: ============================
RMAN-04006: error from auxiliary database: ORA-12528: TNS:listener: all appropriate instances are blocking new connections
解决方法有两个:一个就是放弃使用动态注册方法,就需要手工修改listener.ora文件。也就是为什么很多网络同仁文章中推荐这个步骤。另一种方法就是从auxiliary端进行duplicate操作,这样使用/匿名登录是没有问题的。第二种方法的缺点是一些时候需要将备份集合传递到auxiliary所在服务器目录中。
笔者本次就选取第二种方法进行实验。
4、参数文件设置和路径创建
参数文件是保证数据库启动到nomount状态和实例创建重要对象。我们进行auxiliary过程,要“模拟”出数据库实例。这个时候,可以选择使用target的参数文件模板进行修改。
SQL> create pfile from spfile; --在oratest上进行
File created.
在$ORACLE_HOME/dbs中,定位到initoratest.ora文本参数文件,修改其中内容,保存为initoraaux.ora。注意下面标红部分:
db_name = ORAAUX
oraaux.__db_cache_size=159383552
oraaux.__java_pool_size=4194304
oraaux.__large_pool_size=4194304
oraaux.__shared_pool_size=75497472
oraaux.__streams_pool_size=0
oraaux.db_file_name_convert = ('ORATEST','ORAAUX')
oraaux.log_file_name_convert = ('ORATEST','ORAAUX')
*.audit_file_dest='/u01/app/oracle/admin/oraaux/adump'
*.background_dump_dest='/u01/app/oracle/admin/oraaux/bdump'
*.compatible='10.2.0.1.0'
*.core_dump_dest='/u01/app/oracle/admin/oraaux/cdump'
*.db_block_size=8192
*.db_create_file_dest='/u01/app/oracle/oradata'
*.db_domain=''
*.db_file_multiblock_read_count=16
*.db_recovery_file_dest='/u01/app/oracle/flash_recovery_area'
*.db_recovery_file_dest_size=10485760000
*.dispatchers='(PROTOCOL=TCP) (SERVICE=oraauxXDB)'
*.job_queue_processes=10
*.open_cursors=300
*.pga_aggregate_target=81788928
*.processes=400
*.remote_login_passwordfile='EXCLUSIVE'
*.sessions=445
*.sga_target=247463936
*.undo_management='AUTO'
*.undo_tablespace='UNDOTBS1'
*.user_dump_dest='/u01/app/oracle/admin/oraaux/udump'
注意三个问题:一个是目录,笔者依然是遵照OFA的创建原则。所以将原来的oratest的目录对象修改为oraaux。二是对于db_file_convert和log_file_convert的设置。在Oracle中,数据库对于文件名称的理解是包括目录结构的,所以在这个过程中需要设置映射规则。最后是control_files参数从参数文件中删去,主要是考虑希望使用OMF自定义名称的方式(这样的策略在后面也引起一些问题)。
创建目录,使用root账号将需要的各种路径创建好。
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/admin/oraaux/adump
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/admin/oraaux/bdump
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/oradata/ORAAUX/controlfile
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/admin/oraaux/cdump
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/flash_recovery_area/ORAAUX/controlfile
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/admin/oraaux/cdump
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/admin/oraaux/udump
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/oradata/ORAAUX/onlinelog
[root@SimpleLinuxUp /]# mkdir -p /u01/app/oracle/flash_recovery_area/ORATEST/onlinelog
[root@SimpleLinuxUp /]# chown -R oracle:oinstall /u01
5、密码文件创建
密码文件是用于在不适用操作系统层面验证的时候,或者数据库不存在(只有实例启动nomount)状态下,进行系统登录验证的工具。
我们需要手工创建oratest和oraaux两个实例的密码文件。
[oracle@SimpleLinuxUp dbs]$ orapwd file=orapworatest password=oracle force=y
[oracle@SimpleLinuxUp dbs]$ orapwd file=orapworaaux password=oracle force=y
[oracle@SimpleLinuxUp admin]$ cd $ORACLE_HOME/dbs
[oracle@SimpleLinuxUp dbs]$ ls -l | grep orapw
-rw-r----- 1 oracle oinstall 1536 Mar 5 10:23 orapworaaux
-rw-r----- 1 oracle oinstall 1536 Mar 5 10:13 orapworatest
注意:对于密码文件的创建和定位,Oracle是有自己的规则的。这个和参数文件选择顺序很像。查找目录都是在$ORACLE_HOME/dbs目录,如果是linux环境,文件格式是orapw
6、启动auxiliary实例
使用参数文件initoraaux.ora和ORACLE_SID,可以将auxiliary数据库启动到nomount状态。
[oracle@SimpleLinuxUp dbs]$ export ORACLE_SID=oraaux
[oracle@SimpleLinuxUp dbs]$ sqlplus /nolog
SQL*Plus: Release 10.2.0.1.0 - Production on Wed Mar 5 09:04:10 2014
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> conn / as sysdba
Connected to an idle instance.
SQL> startup nomount pfile=initoraaux.ora
ORACLE instance started.
Total System Global Area 247463936 bytes
Fixed Size 1218772 bytes
Variable Size 83887916 bytes
Database Buffers 159383552 bytes
Redo Buffers 2973696 bytes
[oracle@SimpleLinuxUp dbs]$ ps -ef | grep pmon
oracle 2591 1 0 08:59 ? 00:00:00 ora_pmon_oratest
oracle 2642 1 0 09:04 ? 00:00:00 ora_pmon_oraaux
oracle 2670 2549 0 09:05 pts/0 00:00:00 grep pmon
此时,动态注册监听器状态如下。
[oracle@SimpleLinuxUp dbs]$ lsnrctl status
LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 05-MAR-2014 09:58:29
Copyright (c) 1991, 2005, Oracle. All rights reserved.
Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 10.2.0.1.0 - Production
Start Date 05-MAR-2014 09:07:36
Uptime 0 days 0 hr. 50 min. 53 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Log File /u01/app/oracle/product/10.2.0/db_1/network/log/listener.log
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=SimpleLinuxUp)(PORT=1521)))
Services Summary...
Service "ORAAUX_XPT" has 1 instance(s).
Instance "oraaux", status BLOCKED, has 1 handler(s) for this service...
Service "oraaux" has 1 instance(s).
Instance "oraaux", status BLOCKED, has 1 handler(s) for this service...
Service "oratest" has 1 instance(s).
Instance "oratest", status READY, has 1 handler(s) for this service...
Service "oratest_XPT" has 1 instance(s).
Instance "oratest", status READY, has 1 handler(s) for this service...
The command completed successfully
两个实例都可以被监听程序识别。
7、RMAN duplicate过程
下面进行最关键的duplicate过程,注意,我们是从auxiliary入手处理。
[oracle@SimpleLinuxUp dbs]$ export ORACLE_SID=oraaux
[oracle@SimpleLinuxUp dbs]$ rman nocatalog
Recovery Manager: Release 10.2.0.1.0 - Production on Wed Mar 5 10:27:49 2014
Copyright (c) 1982, 2005, Oracle. All rights reserved.
RMAN> connect target sys/oracle@oratest
connected to target database: ORATEST (DBID=3370560176)
using target database control file instead of recovery catalog
连接auxiliary数据库。
RMAN> connect auxiliary /
connected to auxiliary database: ORAAUX (not mounted)
启动duplicate过程。
RMAN> duplicate target database to oraaux;
Starting Duplicate Db at 05-MAR-14
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: sid=431 devtype=DISK
contents of Memory Script:
{
set until scn 578677;
set newname for datafile 1 to "/u01/app/oracle/oradata/ORAAUX/datafile/o1_mf_system_9k8m458j_.dbf";
set newname for datafile 2 to "/u01/app/oracle/oradata/ORAAUX/datafile/o1_mf_undotbs1_9k8m45bw_.dbf";
set newname for datafile 3 to "/u01/app/oracle/oradata/ORAAUX/datafile/o1_mf_sysaux_9k8m458q_.dbf";
set newname for datafile 4 to "/u01/app/oracle/oradata/ORAAUX/datafile/o1_mf_users_9k8m45c1_.dbf";
set newname for datafile 5 to "/u01/app/oracle/oradata/ORAAUX/datafile/o1_mf_example_9k8m458x_.dbf";
restore
check readonly
clone database
;
}
executing Memory Script
(篇幅原因,有省略……)
contents of Memory Script:
{
Alter clone database open resetlogs;
}
executing Memory Script
database opened
Finished Duplicate Db at 05-MAR-14
如果可以顺利完成脚本过程,就可以实现启动数据库oraaux。
[oracle@SimpleLinuxUp ~]$ sqlplus /nolog
SQL*Plus: Release 10.2.0.1.0 - Production on Wed Mar 5 11:55:44 2014
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> conn / as sysdba
Connected.
SQL> select status from v$instance;
STATUS
------------
OPEN
注意,此时实例还是使用pfile启动,没有spfile。
SQL> show parameter spfile;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
spfile string
SQL> create spfile from pfile;
File created.
重新启动,如果没有问题的话,就可以保证完成过程。
SQL> startup force;
ORACLE instance started.
Total System Global Area 247463936 bytes
Fixed Size 1218772 bytes
Variable Size 83887916 bytes
Database Buffers 159383552 bytes
Redo Buffers 2973696 bytes
ORA-00205: error in identifying control file, check alert log for more info
SQL> select status from v$instance;
STATUS
------------
STARTED
故障出现!
8、丢失的控制文件
从过程看,是启动在nomount之后数据库报错。在行为上,10g和11g有一些差异。如果是10g版本,Oracle会停止在错误发生之前的状态。在这个案例中,我们发现数据库停留在nomount状态。而11g环境中,系统多半会直接中断。
位置提示上,是控制文件出了问题。先看alert_log信息。
Wed Mar 5 11:59:41 2014
ALTER DATABASE MOUNT
Wed Mar 5 11:59:41 2014
ORA-00202: control file: '/u01/app/oracle/product/10.2.0/db_1/dbs/cntrloraaux.dbf'
ORA-27037: unable to obtain file status
Linux Error: 2: No such file or directory
Additional information: 3
Wed Mar 5 11:59:44 2014
ORA-205 signalled during: ALTER DATABASE MOUNT...
找不到文件!我们看系统给出的参数文件是什么内容。
SQL> show parameter control;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
control_file_record_keep_time integer 7
control_files string /u01/app/oracle/product/10.2.0 /db_1/dbs/cntrloraaux.dbf
这个目录显然是给定的非OFA策略路径。到目录中,我们也找不到文件。
[oracle@SimpleLinuxUp dbs]$ ls -l | grep cntrl
[oracle@SimpleLinuxUp dbs]$
比较麻烦的情况,数据库都在,控制文件启动前运行良好。但是信息没有写入到参数文件control_files中。如何解决?
冷静想来,我们在initoraaux.ora中,是没有定义control_files参数的。在创建auxiliary数据库的过程中,我们是看得到create control file脚本的,说明在这个过程中是有控制文件生成。如果没有定义control_files参数,Oracle应该是使用OMF策略,在数据库目录和Recovery Area中创建两个对象。
在关闭数据库前,我们使用了create spfile from pfile的方法,这个过程中,Oracle可能依据的是一个旧的原则(OFA之前),设置了$ORACLE_HOME/dbs目录中的一个不存在的控制文件。再次启动,失败报错。
当务之急是想办法解决,这个思路下,两个OFA目录中应该是有控制文件对象。经过查找,也确定正确。
--oradata目录
[oracle@SimpleLinuxUp dbs]$ cd /u01/app/oracle/oradata/ORAAUX/controlfile/
[oracle@SimpleLinuxUp controlfile]$ ls -l
-rw-r----- 1 oracle oinstall 7389184 Mar 5 11:59 o1_mf_9kf80kq1_.ctl
-rw-r--r-- 1 oracle oinstall 742 Mar 5 10:54 sqlnet.log
--flashback Recovery目录
[oracle@SimpleLinuxUp controlfile]$ cd /u01/app/oracle/flash_recovery_area/
[oracle@SimpleLinuxUp flash_recovery_area]$ ls
ORAAUX ORATEST
[oracle@SimpleLinuxUp flash_recovery_area]$ cd ORAAUX/
[oracle@SimpleLinuxUp ORAAUX]$ ls -l
total 12
drwxr-x--- 3 oracle oinstall 4096 Mar 5 11:54 archivelog
drwxr-xr-x 2 oracle oinstall 4096 Mar 5 11:54 controlfile
drwxr-x--- 2 oracle oinstall 4096 Mar 5 11:55 onlinelog
[oracle@SimpleLinuxUp ORAAUX]$ cd controlfile/
[oracle@SimpleLinuxUp controlfile]$ ls -l
-rw-r----- 1 oracle oinstall 7389184 Mar 5 11:59 o1_mf_9kf80kwj_.ctl
目录中的确存在控制文件对象,而且更可贵的是,时间戳相同,都是11:59。可以相信是相同的镜像。而且在OFA格式下,是不会存在混淆的。
下面需要做的,就是将spfile中的control_files参数修改掉。
SQL> alter system set control_files='/u01/app/oracle/oradata/ORAAUX/controlfile/o1_mf_9kf80kq1_.ctl','/u01/app/oracle/flash_recovery_area/ORAAUX/controlfile/o1_mf_9kf80kwj_.ctl' scope=spfile;
System altered.
重新启动数据库。
SQL> shutdown immediate;
ORA-01507: database not mounted
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 247463936 bytes
Fixed Size 1218772 bytes
Variable Size 83887916 bytes
Database Buffers 159383552 bytes
Redo Buffers 2973696 bytes
Database mounted.
Database opened.
SQL> show parameter control_files
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
control_files string /u01/app/oracle/oradata/ORAAUX /controlfile/o1_mf_9kf80kq1_.c tl, /u01/app/oracle/flash_reco very_area/ORAAUX/controlfile/o 1_mf_9kf80kwj_.ctl
修改成功!至此duplicate数据库创建成功,与oratest完全相同。
这个问题,可能还有不同的处理策略。首先,我们可以在控制文件创建上放弃OMF,就在initoraaux.ora中制定一个简单名称的控制文件。这样就可以避免OMF在duplicate过程中报错。第二种方法是在我们成功启动open数据库中,不使用create spfile from pfile,而是从memory中创建spfile。在11g中,支持从运行的数据库memory中将参数转化为spfile。如果有这个策略,也许就不会出现控制文件参数问题了。
--10g中
SQL> create spfile from memory;
create spfile from memory
*
ERROR at line 1:
ORA-00922: missing or invalid option
--11g中
SQL> create spfile='/tmp/res.ora' from memory;
File created.
最后,这个问题的根源也许和Oracle有一定关系。duplicate结束之后,是否需要将正确的OMF文件路径设置在control_files参数,而不是一个过去值。很大可能也是一个Bug。
9、结论
复制数据库进行测试,是我们经常需要面对的需求。实现的方法有很多,简单的有exp/imp(expdp/impdp),复杂的有DG standby等。使用duplicate方法,是一种比较简单的方法,值得我们学习掌握。