技术开发 频道

RMAN高级应用Duplicate创建副本数据库实战

    【IT168技术文档】
    经过前面的准备工作,大展拳脚的时刻终于来临了。在正在创建复制之前,我们先来描述一下需求,一个明确的、清晰的、可实现的需求更加有助于我们操作的实施,所以语言描述能力也是一项非常高超的技巧,下面大家看我举例,一个清晰的需求描述:NOCATALOG模式本地完整复制目标库JSSWEB到副本数据库JSSDUP。
  看看,都学着点吧,什么叫言简意赅,言简意赅就是NOCATALOG模式本地完整复制目标库JSSWEB到副本数据库JSSDUP。
  我们假设实例已创建(辅助实例的创建过程见第2章)。

1、连接并启动目标数据库(至少要启动到mount状态);
F:\oracle>set oracle_sid=jssweb

F:\oracle>sqlplus "/ as sysdba"

SQL*Plus: Release 10.2.0.1.0 - Production on 星期一 10月 22 16:13:04 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

已连接到空闲例程。

SQL> startup
ORACLE 例程已经启动。

Total System Global Area 113246208 bytes
Fixed Size 1247564 bytes
Variable Size 83887796 bytes
Database Buffers 20971520 bytes
Redo Buffers 7139328 bytes
数据库装载完毕。
数据库已经打开。
SQL>

2、连接并启动辅助实例到nomount状态;
F:\oracle>set oracle_sid=jssdup

F:\oracle>sqlplus "/ as sysdba"

SQL*Plus: Release 10.2.0.1.0 - Production on 星期一 10月 22 16:11:28 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

已连接到空闲例程。

SQL> startup nomount
ORACLE 例程已经启动。

Total System Global Area 285212672 bytes
Fixed Size 1248552 bytes
Variable Size 226493144 bytes
Database Buffers 50331648 bytes
Redo Buffers 7139328 bytes
SQL>

3、RMAN连接到目标数据库和辅助实例。
F:\oracle>set oracle_sid=jssweb
###目标数据库使用操作系统认证,所以首先设置SID
F:\oracle>rman target / auxiliary sys/verysafe:)@jssdup

恢复管理器: Release 10.2.0.1.0 - Production on 星期五 10月 19 15:03:10 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

连接到目标数据库: JSSWEB (DBID=3402005373)
已连接到辅助数据库: JSSDUP (未装载)

RMAN>

4、首先确认目标库存在可用备份。
RMAN> list backup;

使用目标数据库控制文件替代恢复目录

备份集列表
===================

BS 关键字 类型 LV 大小 设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
3 Full 443.16M DISK 00:00:51 19-10月-07
BP 关键字: 3 状态: AVAILABLE 已压缩: NO 标记: TAG20071022T161927
段名:D:\BACKUP\06IV54CF_1_1
备份集 3 中的数据文件列表
文件 LV 类型 Ckp SCN Ckp 时间 名称
---- -- ---- ---------- ---------- ----
1 Full 1326175 19-10月-07 F:\ORACLE\ORADATA\JSSWEB\SYSTEM01.DBF
2 Full 1326175 19-10月-07 F:\ORACLE\ORADATA\JSSWEB\UNDOTBS01.DBF
3 Full 1326175 19-10月-07 F:\ORACLE\ORADATA\JSSWEB\SYSAUX01.DBF
4 Full 1326175 19-10月-07 F:\ORACLE\ORADATA\JSSWEB\JSSWEB.DBF
5 Full 1326175 19-10月-07 F:\ORACLE\ORADATA\JSSWEB\USERS01.DBF

BS 关键字 类型 LV 大小 设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
4 Full 6.80M DISK 00:00:01 19-10月-07
BP 关键字: 4 状态: AVAILABLE 已压缩: NO 标记: TAG20071022T162023
段名:D:\BACKUP\C-3402005373-20071022-00
包括的控制文件: Ckp SCN: 1326175 Ckp 时间: 19-10月-07
包含的 SPFILE: 修改时间: 24-9月 -07

RMAN>

5、万事俱备,只欠Duplicate执行;    
RMAN> duplicate target database to jssdup; ####只需要执行这一行 启动 Duplicate Db 于 22-10月-07 分配的通道: ORA_AUX_DISK_1 通道 ORA_AUX_DISK_1: sid=39 devtype=DISK 内存脚本的内容: { set newname for datafile 1 to "F:\ORACLE\ORADATA\JSSDUP\SYSTEM01.DBF"; set newname for datafile 2 to "F:\ORACLE\ORADATA\JSSDUP\UNDOTBS01.DBF"; set newname for datafile 3 to "F:\ORACLE\ORADATA\JSSDUP\SYSAUX01.DBF"; set newname for datafile 4 to "F:\ORACLE\ORADATA\JSSDUP\JSSWEB.DBF"; set newname for datafile 5 to "F:\ORACLE\ORADATA\JSSDUP\USERS01.DBF"; restore check readonly clone database ; } 正在执行内存脚本 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 正在执行命令: SET NEWNAME 启动 restore22-10月-07 使用通道 ORA_AUX_DISK_1 通道 ORA_AUX_DISK_1: 正在开始恢复数据文件备份集 通道 ORA_AUX_DISK_1: 正在指定从备份集恢复的数据文件 正将数据文件00001恢复到F:\ORACLE\ORADATA\JSSDUP\SYSTEM01.DBF 正将数据文件00002恢复到F:\ORACLE\ORADATA\JSSDUP\UNDOTBS01.DBF 正将数据文件00003恢复到F:\ORACLE\ORADATA\JSSDUP\SYSAUX01.DBF 正将数据文件00004恢复到F:\ORACLE\ORADATA\JSSDUP\JSSWEB.DBF 正将数据文件00005恢复到F:\ORACLE\ORADATA\JSSDUP\USERS01.DBF 通道 ORA_AUX_DISK_1: 正在读取备份段 D:\BACKUP\06IV54CF_1_1 通道 ORA_AUX_DISK_1: 已恢复备份段 1 段句柄 = D:\BACKUP\06IV54CF_1_1 标记 = TAG20071022T161927 通道 ORA_AUX_DISK_1: 恢复完成, 用时: 00:01:06 完成 restore22-10月-07 sql 语句: CREATE CONTROLFILE REUSE SET DATABASE "JSSDUP" RESETLOGS NOARCHIVELOG MAXLOGFILES 16 MAXLOGMEMBERS 3 MAXDATAFILES 100 MAXINSTANCES 8 MAXLOGHISTORY 292 LOGFILE GROUP 1 ( 'F:\ORACLE\ORADATA\JSSDUP\REDO01.LOG' ) SIZE 20 M REUSE, GROUP 2 ( 'F:\ORACLE\ORADATA\JSSDUP\REDO02.LOG' ) SIZE 20 M REUSE, GROUP 3 ( 'F:\ORACLE\ORADATA\JSSDUP\REDO03.LOG' ) SIZE 20 M REUSE DATAFILE 'F:\ORACLE\ORADATA\JSSDUP\SYSTEM01.DBF' CHARACTER SET ZHS16GBK 内存脚本的内容: { switch clone datafile all; } 正在执行内存脚本 释放的通道: ORA_AUX_DISK_1 数据文件 2 已转换成数据文件副本 输入数据文件副本 recid=1 stamp=636654235 文件名=F:\ORACLE\ORADATA\JSSDUP\UNDOTBS01.DBF 数据文件 3 已转换成数据文件副本 输入数据文件副本 recid=2 stamp=636654235 文件名=F:\ORACLE\ORADATA\JSSDUP\SYSAUX01.DBF 数据文件 4 已转换成数据文件副本 输入数据文件副本 recid=3 stamp=636654235 文件名=F:\ORACLE\ORADATA\JSSDUP\JSSWEB.DBF 数据文件 5 已转换成数据文件副本 输入数据文件副本 recid=4 stamp=636654235 文件名=F:\ORACLE\ORADATA\JSSDUP\USERS01.DBF 内存脚本的内容: { recover clone database noredo , delete archivelog ; } 正在执行内存脚本 启动 recover 于 22-10月-07 分配的通道: ORA_AUX_DISK_1 通道 ORA_AUX_DISK_1: sid=39 devtype=DISK 完成 recover 于 22-10月-07 内存脚本的内容: { shutdown clone; startup clone nomount ; } 正在执行内存脚本 数据库已卸载 Oracle 实例已关闭 已连接到辅助数据库 (未启动) Oracle 实例已启动 系统全局区域总计 285212672 字节 Fixed Size 1248552 字节 Variable Size 226493144 字节 Database Buffers 50331648 字节 Redo Buffers 7139328 字节 sql 语句: CREATE CONTROLFILE REUSE SET DATABASE "JSSDUP" RESETLOGS NOARCHIVELOG MAXLOGFILES 16 MAXLOGMEMBERS 3 MAXDATAFILES 100 MAXINSTANCES 8 MAXLOGHISTORY 292 LOGFILE GROUP 1 ( 'F:\ORACLE\ORADATA\JSSDUP\REDO01.LOG' ) SIZE 20 M REUSE, GROUP 2 ( 'F:\ORACLE\ORADATA\JSSDUP\REDO02.LOG' ) SIZE 20 M REUSE, GROUP 3 ( 'F:\ORACLE\ORADATA\JSSDUP\REDO03.LOG' ) SIZE 20 M REUSE DATAFILE 'F:\ORACLE\ORADATA\JSSDUP\SYSTEM01.DBF' CHARACTER SET ZHS16GBK 内存脚本的内容: { set newname for tempfile 1 to "F:\ORACLE\ORADATA\JSSDUP\TEMP01.DBF"; switch clone tempfile all; catalog clone datafilecopy "F:\ORACLE\ORADATA\JSSDUP\UNDOTBS01.DBF"; catalog clone datafilecopy "F:\ORACLE\ORADATA\JSSDUP\SYSAUX01.DBF"; catalog clone datafilecopy "F:\ORACLE\ORADATA\JSSDUP\JSSWEB.DBF"; catalog clone datafilecopy "F:\ORACLE\ORADATA\JSSDUP\USERS01.DBF"; switch clone datafile all; } 正在执行内存脚本 正在执行命令: SET NEWNAME 临时文件 1 在控制文件中已重命名为 F:\ORACLE\ORADATA\JSSDUP\TEMP01.DBF 已将数据文件副本列入目录 数据文件副本 filename=F:\ORACLE\ORADATA\JSSDUP\UNDOTBS01.DBF recid=1 stamp=636654246 已将数据文件副本列入目录 数据文件副本 filename=F:\ORACLE\ORADATA\JSSDUP\SYSAUX01.DBF recid=2 stamp=636654246 已将数据文件副本列入目录 数据文件副本 filename=F:\ORACLE\ORADATA\JSSDUP\JSSWEB.DBF recid=3 stamp=636654246 已将数据文件副本列入目录 数据文件副本 filename=F:\ORACLE\ORADATA\JSSDUP\USERS01.DBF recid=4 stamp=636654247 数据文件 2 已转换成数据文件副本 输入数据文件副本 recid=1 stamp=636654246 文件名=F:\ORACLE\ORADATA\JSSDUP\UNDOTBS01.DBF 数据文件 3 已转换成数据文件副本 输入数据文件副本 recid=2 stamp=636654246 文件名=F:\ORACLE\ORADATA\JSSDUP\SYSAUX01.DBF 数据文件 4 已转换成数据文件副本 输入数据文件副本 recid=3 stamp=636654246 文件名=F:\ORACLE\ORADATA\JSSDUP\JSSWEB.DBF 数据文件 5 已转换成数据文件副本 输入数据文件副本 recid=4 stamp=636654247 文件名=F:\ORACLE\ORADATA\JSSDUP\USERS01.DBF 内存脚本的内容: { Alter clone database open resetlogs; } 正在执行内存脚本 数据库已打开 完成 Duplicate Db 于 22-10月-07 RMAN>   
 

 6、连接副本数据库看看
RMAN> host;

Microsoft Windows [版本 5.2.3790]
(C) 版权所有 1985-2003 Microsoft Corp.

F:\oracle>sqlplus jss/jss

SQL*Plus: Release 10.2.0.1.0 - Production on 星期一 10月 22 16:35:07 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

连接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> select *from tab where tname like 'JSS%' and rownum<9;

TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
JSSTMP_HC_ORC_BJ TABLE
JSSTMP_HC_ORD_PRODUCT_PACKAGE TABLE
JSSTMP_HC_ORD_PROD_PACK_ITEM TABLE
JSSTMP_HC_PRODUCT_BJ TABLE
JSSTMP_HC_PROJ_PROD_CLASS_BJ TABLE

SQL>
OK,数据都在。创建成功:)

    整体来看,这是个非常简单的示例,简单是简单在我们操作的步骤上,事实上duplicate就是一个具有强大功能的简单命令,就像是一堆积木,通过各种各样的灵活组合来实现各种各样的需求,比如你可以在执行duplicate命令时通过指定UNTIL TIME 来限定恢复数据所在时间。又比如你可以通过指定PFILE参数从客户端初始化参数文件启动辅助实例,取代在创建辅助实例里创建spfile的操作。又或者通过Set Newname指定某个数据文件的存储位置等等。其它诸如异地恢复啦,复制到asm啦之类都是以duplicate命令和辅助实例为主,几个相关命令和子句为辅的综合应用,复制就是这么简单。

    另外此章节中重点看看第5步,虽然我们只执行了duplicate一条命令,担你如果细细分析其执行日志的话能够得到的决不仅仅只是这些。比如执行日志第3行就看出是自动分配的通道,日志第5行开始则是将db_file_name_convert等参数转换为SET NEWNAME 命令,再接着往下看,发现有restore、clone database之类命令,看过“一步一步学RMAN”的朋友肯定还记的在该系列最后二章节中我们曾经实践过RMAN恢复备份到异机的操作。与本例对比的话操作方式有不少雷同,你完全可以把duplicate也看成是恢复操作,当然二者操作也有差异,比如duplicate命令更加简单,而且duplicate创建的副本数据库拥有独立的DBID,而RMAN手工恢复到异机创建的是与源库相同的DBID(当然duplicate也可以创建DBID与源库相同,比如standby数据库,这部分内容也许会出现在下下下下个系列中进行演示)。

    命令执行完不代表操作就完了,多看看执行日志,分析分析执行原理,综合融会才能够让你的认识有更高提升。


补充与附录:
一、跳过表空间(Skipping Tablespaces in RMAN DUPLICATE DATABASE)

    有时候,并非数据库的所有表空间都需要备份,比如你在创建副本数据库时,想跳过那些read-only或OFFLINE的表空间,这个简单,来来来,跟我一起做,左三圈右三圈脖子扭扭屁股扭扭,不是跳舞,是放松放松,你已经连续盯着屏幕这么久,而且都是看些蝌蚪儿字,要注意保护眼睛啊,黑黑~~~~

    要跳过只读表空间,在执行duplicate命令时指定SKIP READONLY子句即可。而对于离线表空间,在执行duplicate命令之前将其置为OFFLINE NORMAL状态即可,RMAN复制时会跳过只读或离线表空间的数据文件。如果某个表空间即不是readonly也并非offline,但你就是不想复制,表急,duplicate还有杀手锏。在执行duplicate命令时通过SKIP TABLESPACE XXX子句指定你要跳过的表空间,如果要跳过的表空间有多个,中间以,(逗号)分隔即可。

   当复制完成之后,通过查询副本数据库的v$datafile或DBA_DATA_FILES、DBA_TABLESPACES可以获取表空间以及数据文件的状态。

例如:   
SQL> select status,enabled,name from v$datafile; STATUS ENABLED NAME ------- ---------- -------------------------------------------------- SYSTEM READ WRITE F:\ORACLE\ORADATA\JSSDUP\SYSTEM01.DBF ONLINE READ WRITE F:\ORACLE\ORADATA\JSSDUP\UNDOTBS01.DBF ONLINE READ WRITE F:\ORACLE\ORADATA\JSSDUP\SYSAUX01.DBF ONLINE READ WRITE F:\ORACLE\ORADATA\JSSDUP\JSSWEB.DBF ONLINE READ WRITE F:\ORACLE\ORADATA\JSSDUP\USERS01.DBF

    对于readonly表空间,v$datafile中STATUS列会显示为OFFLINE,ENABLE列会显示为READ ONLY ,Name列会显示为MISSING xxx。
    对于offline表空间,v$datafile中STATUS列会显示为OFFLINE,ENABLE列会显示为DISABLED ,Name列会显示为MISSING xxx。


二、重命名副本数据库文件(Renaming Database Files in RMAN Duplicate Database)

1、创建过程中重命名控制文件
创建控制文件的语法与sql语句中的创建方法一致。如果手工选择控制文件名称的话,务必确认辅助实例的初始化参数中参数设置正确。

2、创建过程中重命名在线日志文件
有多种方式可以重命名在线日志文件,见下列诸条:
1). 执行duplicate命名时指定LOGFILE子句设置redo logs文件名。
2). 辅助实例初始化参数文件中设置LOG_FILE_NAME_CONVERT参数。该参数语法如下:
LOG_FILE_NAME_CONVERT = 'string1' , 'string2' , 'string3' , 'string4' , ...
将string1替换为string2,string3替换为string4,几乎无限组对。
3). 辅助实例中设置其它的初始化参数:DB_CREATE_FILE_DEST, DB_CREATE_ONLINE_DEST_n, or DB_RECOVERY_FILE_DEST。这些参数的作用类似于SQL语句:ALTER DATABASE ADD LOGFILE.
4). 如果副本数据库与目标库不在同一台机器上,并且副本数据库的在线日志文件路径与目标库相同,则运行duplicate命令时必须指定NOFILENAMECHECK参数以避免冲突提示。晕了吧,异机操作路径相同还必需指定NOFILENAMECHECK。此处oracle表现的很傻,它不知道你要恢复的路径是在另一台机器上,它只是认为要恢复到的路径怎么跟目标数据库表现的一样呢?会不会是要覆盖目标数据库啊,为了避免这种情形,于是它就报错。所以一旦异机恢复,并且路径相同,那么你必须通过指定NOFILENAMECHECK来避免oracle的自动识别。

提示:上述各方式是有优先级的,按照顺序序号最小的最先执行。如果你在操作过程中统统指定,则oracle会自动判断并以优先级最高的设置为准。

3、创建过程中重命名数据文件
这个方法也比较多:第三章第2节"不同路径结构的复制"时已经耗费了不少笔墨(o,是按键次数)并辅以各种脚本实例说明,什么,没看明白,拖出去关小黑屋反复杀死100遍。

4、跳过文件名检测NOFILENAMECHECK
这项操作主要是为了避免oracle错误的领会你的操作意图。
例如:
a库有两个数据文件:文件号1的文件f:\oracle\oradata\file1.dbf和文件号2的文件f:\oracle\oradata\file2.dbf,当你将其复制到另一台服务器的b库时:
RUN { SET NEWNAME FOR DATAFILE 1 TO f:\oracle\oradata\file2.dbf; SET NEWNAME FOR DATAFILE 2 TO f:\oracle\oradata\file1.dbf; DUPLICATE TARGET DATABASE TO newdb; }

    执行上面的脚本oracle会报错。虽然你通过set newname命令已经将数据文件重命名,不会有文件名重复的问题,但是由于此项操作是异机的同路径复制,oracle会以为file1.dbf和file2.dbf仍在使用(目标库的确在使用,但oracle分不清你当前操作的已经不是同一台服务器)。于是oracle会提示报错信息,针对这种情况,你必须DUPLICATE TARGET DATABASE TO newdb NOFILENAMECHECK避免oracle的理解。

再与第2项中的第4小项结合理解,你就能完全掌握NOFILENAMECHECK的奥妙所在:)

5、创建过程中重命名临时文件
    与重命名数据文件极其相似,不过如果希望通过SET NAME方式重命名临时文件路径的话,需要指明:SET NEWNAME FOR TEMPFILE,其它皆与之同,不详述。

0
相关文章