相比Oracle i和Oracle iOracle g在数据库备份方面做出了极大的改善特别是作为Oracle最大可用性架构(MAA)一部分的真正应用集群(RAC)特性Oracle g现在创建一个备用数据库变得更加简单了因为恢复管理器(RMAN)支持直接从主数据库使用DUPLICATE DATABASE命令集通过网络克隆一个备用数据库只要目标数据库是活动的即可这意味着再也不用先生成再传输最后在备用数据库上通过复杂的手工方式还原和恢复主数据库的RMAN备份集了相反RMAN在主站点上自动生成一个转换脚本在内存中然后在备用站点上使用这个脚本管理克隆操作实际上不用DBA进行任何干预下文将集中精力讲解备用数据库实况克隆特性笔者的硬件基本情况是双核AMD Athlon 位CPU(Winchester )GB内存主机运行的是Windows xp系统运行VMWare Server 访问访问虚拟数据库服务器环境每个虚拟机使用个CPUM内存我选择Oracle Enterprise Linux (OEL) (Linux内核版本ELsmp)作为虚拟机客户端操作系统
每个VMWare虚拟机配置好后在每个虚拟机的/etc/hosts文件中添加合适的条目让主站点(training)和备用站点(gStdby)之间建立起网络连接然后在每个节点上都安装Oracle g数据库最后在主站点上创建好标准的g R种子数据库包括标准的示例方案这个数据库的ORACLE_SID是orcl接下来就可以开始执行实况克隆操作了
克隆前准备工作调整主数据库
在克隆主数据库到对应的备用环境中之前我需要对主数据库做一些调整下面的步骤未做特别说明没有先后顺序只要在发出DUPLICATE DATABASE命令前这些步骤都执行完了即可在克隆操作过程中应该没有什么让人意外的东西出现
强制记录所有的交易
大多数组织实施数据卫士配置的主要原因是保证所有交易都不丢失但遗憾的是默认情况下Oracle数据库是运行在NOFORCE LOGGING模式下的这意味着对对象的改变可能丢失因为他们的存储属性被设为NOLOGGING为了确保所有的改变都被记录下来我将执行ALTER DATABASE FORCE LOGGING命令这个命令需要在执行ALTER DATABASE ARCHIVELOG命令将数据库ARCHIVELOG模式前执行这些命令如清单所示
清单 将主数据库切换到ARCHIVELOG模式
–为归档日志文件设置一个合适的格式
ALTER SYSTEM SET log_archive_format = log_%s_%t_%rarc SCOPE=SPFILE;
–设置新的DB_UNIQUE_NAME参数它不能动态修改
ALTER SYSTEM SET db_unique_name = orcl SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE FORCE LOGGING;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
创建备用重做日志组
自从Oracle i R开始支持备用重做日志(standby redo log 即SRL)组开始Oracle就建议配置它SRL对于实时应用(Real Time Apply)特性是需要的或DBA想要实现重做日志串联目的时也需要除此之外它任然是备用数据库配置选项Oracle g另一个优点是如果SRL在主数据库上已经配置好那么DUPLICATE DATABASE命令将会在备用数据库上自动创建它们清单显示了我在主数据库上创建SRL的命令注意我也使用了多个重SRL文件保护整个SRL组避免数据丢失这一点和在线重做日志组类似
清单 在主数据库上创建备用重做日志文件
ALTER DATABASE
ADD STANDBY LOGFILE
/u/app/oracle/oradata/orcl/srllog
SIZE M
REUSE;
ALTER DATABASE
ADD STANDBY LOGFILE
/u/app/oracle/oradata/orcl/srllog
SIZE M
REUSE;
ALTER DATABASE
ADD STANDBY LOGFILE
/u/app/oracle/oradata/orcl/srllog
SIZE M
REUSE;
文件名转换
一般情况下备用数据库都是创建在与主数据库不同的主机上的否则在灾难中主备数据库都有可能受到危害最佳做法是将对应的备用数据库的目录和文件名都弄成一样但如果遇到挂载点不一样时目录名需要修改这个时候就需要使用DB_FILE_NAME_CONVERT和LOG_FILE_NAME_CONVERT初始化参数进行转换了
修改主站点初始化参数
在主数据库上设置下列初始化参数确保DUPLICATE DATABASE命令能够一样配置备用数据库我在清单中详细列出了这些初始化参数设置
()DB_UNIQUE_NAME
我通过这个参数为主数据库定义一个唯一的实例名这个参数值使得区分原始主数据库和备用数据库变得更加简单因为这是一个静态参数我在清单中已经将其设置为SCOPE=SPFILE它将在主数据库实例启动时生效
()LOG_ARCHIVE_CONFIG
这个参数控制主或备用数据库是否应该接受和/或发送来自远程源的归档重做日志它允许我们包含所有主备数据库因为它在配置中列出了所有数据库的DB_UNIQUE_NAME值我将其设置为目前我的数据卫士数据库orcl和stdby
()STANDBY_FILE_MANAGEMENT
我将这个参数设置问为auto了这样主数据库上发生什么操作备用数据库上就会跟着发生什么操作如主数据库上创建一个文件备用数据库上也将创建一个相同的文件删除主数据库上一个已有文件备用数据库上也做对应的删除如新增一个在线重做日志文件组或删除一个表空间
()LOG_ARCHIVE_DEST_n
这个控制是从主数据库上传输归档重做日志到物理备用数据库的关键参数我将设置两个归档目标
目标LOG_ARCHIVE_DEST_指定主数据库归档重做日志的物理位置注意我们使用了闪回恢复区作为目标
目标LOG_ARCHIVE_DEST_指定了对应的备用数据库实例(stdby)的网络服务地址这个参数确保归档重做日志自动传输到备用站点
对于这个归档重做日志传输参数我还可以指定另外两个指令
◆当数据库是以特定角色激活时指令VALID_FOR大大简化了重做日志传输时的类型当主备数据库角色不同时在传输重做日志时这是最关键的参数表列出了这个参数允许的值
表 VALID_FOR指令值
设置含义ALL_LOGFILES(默认)目标使用在线或备用重做日志文件ONLINE_LOGFILE目标仅适用于在线归档重做日志文件STANDBY_LOGFILE目标仅适用于备用重做日志文件ALL_ROLES当数据库以主或备用角色运行时(默认)目标都是有效的PRIMARY_ROLE当数据库以主角色运行时目标是有效的STANDBY_ROLE当数据库以备用角色运行时目标是有效的
◆也可以设置合适的重做日志传输模式(redo transport mode)值指定归档重做日志从主数据库传输到备用数据库表列出了这个指令允许的值
表 重做日志传输模式设置含义ASYNC在事务提交前可能不是所有的目标都接受了传输的重做日志(默认值)SYNC在事务提交前所有目标必须接受传输的重做日志AFFIRM仅当重做数据被写入到备用重做日志后目标才确认已收到含有SYNC含义NOAFFIRM当重做数据写入到备用重做日志前目标就可以确认收到含有ASYNC含义
网络配置修改
最后我需要确保主数据库和备用数据库之间能够通过网络通信唯一需要变化的就是在主数据库本地命名配置文件(TNSNAMESORA)中加上备用数据库的实例备用数据库的LISTENERORA配置文件也需要一个备用数据库实例的静态监听器这些变化如清单所示
清单 在主数据库上设置合适的初始化参数值
ALTER SYSTEM SET log_archive_dest_ = LOCATION=/u/app/oracle/flash_recovery_area/ORCL/ DB_UNIQUE_NAME=orcl VALID_FOR=(ALL_LOGFILESALL_ROLES);
ALTER SYSTEM SET log_archive_dest_state_ = ENABLE;
ALTER SYSTEM SET log_archive_dest_ = SERVICE=stdby ASYNC DB_UNIQUE_NAME=stdby VALID_FOR=(ONLINE_LOGFILEPRIMARY_ROLE);
ALTER SYSTEM SET log_archive_dest_state_ = ENABLE;
ALTER SYSTEM SET standby_file_management = AUTO;
ALTER SYSTEM SET log_archive_config = DG_CONFIG=(orclstdby);
清单 网络配置文件修改
#在主数据库实例上添加一个备用数据库条目
STDBY =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = gStdby)(PORT = ))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = stdby)
)
)
#使用备用数据库实例的静态引用设置备用数据库监听器
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = stdby)
(ORACLE_HOME = /u/app/oracle/product//db_)
(SID_NAME = stdby)
)
)
LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = gStdby)(PORT = ))
准备克隆准备备用站点
现在主站点已经准备好可以克隆了在对应的备用站点上也需要做一些对应的调整
创建必要的目录
需要为数据库控制文件数据文件在线重做日志文件和备用重做日志文件创建必要的目录我还为数据库的审核跟蹤创建了合适的目录
设置密码文件
因为主数据库要和备用数据库进行通信时需要使用远程认证我将会使用orapwd工具创建一个新的密码文件确保SYS的密码和主数据库匹配(注意我可能会直接从主数据库拷贝到备用数据库)
创建备用初始化参数文件
最后我需要创建一个初始化参数文件(PFILE)仅允许我启动备用数据库实例它只需要一个参数DB_NAME当DUPLICATE DATABASE命令脚本执行完毕后它将会创建一个服务端参数文件(SPFILE)它仅包括合适的初始化参数设置
在清单中我解释了这些命令和临时备用数据库初始化参数为了开启DUPLICATE DATABASE克隆操作我将启动备用站点的监听器然后使用前面创建的PFILE初始化参数文件将备用数据库实例启动到NOMOUNT状态
从主数据库的RMAN会话环境启动DUPLICATE DATABASE命令前面我已经提到过Oracle g中DUPLICATE DATABASE命令最引人注目的改变是它可以通过网络直接将主数据库克隆到备用数据库站点作为设置备用数据库的一部分我也可以为所有需要的初始化参数指定值DUPLICATE DATABASE将会在备用数据库上创建一个新的SPFILE
清单显示了使用DUPLICATE DATABASE命令进行克隆的完整语句注意我添加了下面这样一些额外的参数可能和主数据库的参数稍有不同
()DB_UNIQUE_NAME
我将这个参数的值设为stdby了
()CONTROL_FILES
我只为备用数据库创建了一个控制文件在克隆完毕后我会复制多个
()FAL_CLIENT和FAL_SERVER
这两个参数确定哪个数据库服务分别担任FAL(fetch archive log)客户端和服务器例如无论何时当主数据库和备用数据库之间的网络断掉后或如果备用数据库已经关闭相当长一段时间归档重做日志可能就不会传输到备用服务器上这种情况叫做归档日志空白(archive log gap)这两个FAL服务名确定了由哪个服务器(FAL_SERVER)维护所有归档重做日志组主列表由它为FAL_CLIENT提供可能发生的归档日志空白解决方案在我们的数据卫士设置中将备用服务器配置为FAL_CLIENT将主服务器配置为FAL_SERVER
()LOG_FILE_NAME_CONVERT
我已经使用这个参数将主数据库的归档重做日志和备用重做日志的目标做了翻译确保在克隆过程中RMAN能够自动在备用数据库上创建恰当的副本
()LOG_ARCHIVE_DEST_n
和主数据库一样我也设置了两个归档日志目标一个主目标LOG_ARCHIVE_DEST_和次要目标LOG_ARCHIVE_DEST_将来主备站点角色发生交换后将由次要目标中的归档重做日志传输到原始主数据库中
最后让我们开始克隆吧!首先在主数据库服务器上启动一个RMAN会话以target连接到主数据库以auxiliary连接到备用数据库
oracle@training> rman target / auxiliary sys/oracle@stdby
Recovery Manager: Release Production on Tue Apr ::
Copyright (c) Oracle All rights reserved
connected to target database: ORCL (DBID=)
connected to auxiliary database: STDBY (not mounted)
为了加快处理过程我将会通过ALLOCATE CHANNEL命令创建两个auxiliary通道和两个normal通道并在相同的RUN块中使用DUPLICATE DATABASE开始克隆下面是RMAN命令块所做的事情
使用主数据库服务器的参数文件作为模版为备用数据库创建了一个新的SPFILE但在DUPLICATE DATABASE运行块中的SET命令中做了适当的修改
然后关闭备用数据库再使用新的SPFILE启动到NOMOUNT模式
接下来创建主数据库控制文件的拷贝修改它让所有文件名都与备用数据库匹配拷贝新的控制文件到备用数据库上然后使用新的控制文件将数据库启动到MOUNT模式
然后在备用数据库上直接创建主数据库数据文件的镜像拷贝备份
最后使用主数据库上当前的归档重做日志在备用数据库上执行必要的恢复并将备用数据库置为管理恢复模式
我在清单中列出了克隆操作的结果它显示了RMAN命令的输出内容清单列出了克隆过程中产生的备用数据库的警告日志条目
清单 来自一个成功的备用数据库克隆操作的输出内容
[oracle@training ~]$ rman target / auxiliary sys/oracle@stdby
Recovery Manager: Release Production on Sat Apr ::
Copyright (c) Oracle All rights reserved
connected to target database: ORCL (DBID=)
connected to auxiliary database: STDBY (not mounted)
RMAN> RUN {
ALLOCATE CHANNEL d TYPE DISK;
ALLOCATE CHANNEL d TYPE DISK;
ALLOCATE AUXILIARY CHANNEL cnv TYPE DISK;
ALLOCATE AUXILIARY CHANNEL cnv TYPE DISK;
DUPLICATE TARGET DATABASE
FOR STANDBY
FROM ACTIVE DATABASE
DORECOVER
SPFILE
SET db_unique_name=stdby
SET control_files=/u/app/oracle/oradata/orcl/controlctl
SET log_file_name_convert=/u/app/oracle/oradata/orcl//u/app/oracle/oradata/stdby/
SET log_archive_dest_=location=/u/app/oracle/flash_recovery_area/STDBY/ valid_for=(ALL_LOGFILESALL_ROLES) db_unique_name=stdby
SET log_archive_dest_=service=orcl ASYNC valid_for=(ONLINE_LOGFILEPRIMARY_ROLE) db_unique_name=orcl
SET fal_client=stdby
SET fal_server=orcl
SET standby_file_management=AUTO
SET log_archive_config=dg_config=(orclstdby)
NOFILENAMECHECK;
}
> > > > > > > > > > > > > > > > > > > >
using target database control file instead of recovery catalog
allocated channel: d
channel d: SID= device type=DISK
allocated channel: d
channel d: SID= device type=DISK
allocated channel: cnv
channel cnv: SID= device type=DISK
allocated channel: cnv
channel cnv: SID= device type=DISK
Starting Duplicate Db at APR
contents of Memory Script:
{
backup as copy reuse
file /u/app/oracle/product//db_/dbs/orapworcl auxiliary format
/u/app/oracle/product//db_/dbs/orapwstdby file
/u/app/oracle/product//db_/dbs/spfileorclora auxiliary format
/u/app/oracle/product//db_/dbs/spfilestdbyora ;
sql clone alter system set spfile= /u/app/oracle/product//db_/dbs/spfilestdbyora;
}
executing Memory Script
Starting backup at APR
Finished backup at APR
sql statement: alter system set spfile= /u/app/oracle/product//db_/dbs/spfilestdbyora
contents of Memory Script:
{
sql clone alter system set db_unique_name =
stdby comment=
scope=spfile;
sql clone alter system set control_files =
/u/app/oracle/oradata/orcl/controlctl comment=
scope=spfile;
sql clone alter system set log_file_name_convert =
/u/app/oracle/oradata/orcl/ /u/app/oracle/oradata/stdby/ comment=
scope=spfile;
sql clone alter system set log_archive_dest_ =
location=/u/app/oracle/flash_recovery_area/STDBY/ valid_for=(ALL_LOGFILESALL_ROLES) db_unique_name=stdby comment=
scope=spfile;
sql clone alter system set log_archive_dest_ =
service=orcl ASYNC valid_for=(ONLINE_LOGFILEPRIMARY_ROLE) db_unique_name=orcl comment=
scope=spfile;
sql clone alter system set fal_client =
stdby comment=
scope=spfile;
sql clone alter system set fal_server =
orcl comment=
scope=spfile;
sql clone alter system set standby_file_management =
AUTO comment=
scope=spfile;
sql clone alter system set log_archive_config =
dg_config=(orclstdby) comment=
scope=spfile;
shutdown clone immediate;
startup clone nomount ;
}
executing Memory Script
sql statement: alter system set db_unique_name = stdby comment= scope=spfile
sql statement: alter system set control_files = /u/app/oracle/oradata/orcl/controlctl comment= scope=spfile
sql statement: alter system set log_file_name_convert = /u/app/oracle/oradata/orcl/ /u/app/oracle/oradata/stdby/ comment= scope=spfile
sql statement: alter system set log_archive_dest_ = location=/u/app/oracle/flash_recovery_area/STDBY/ valid_for=(ALL_LOGFILESALL_ROLES) db_unique_name=stdby comment= scope=spfile
sql statement: alter system set log_archive_dest_ = service=orcl ASYNC valid_for=(ONLINE_LOGFILEPRIMARY_ROLE) db_unique_name=orcl comment= scope=spfile
sql statement: alter system set fal_client = stdby comment= scope=spfile
sql statement: alter system set fal_server = orcl comment= scope=spfile
sql statement: alter system set standby_file_management = AUTO comment= scope=spfile
sql statement: alter system set log_archive_config = dg_config=(orclstdby) comment= scope=spfile
Oracle instance shut down
connected to auxiliary database (not started)
Oracle instance started
Total System Global Area bytes
Fixed Size bytes
Variable Size bytes
Database Buffers bytes
Redo Buffers bytes
contents of Memory Script:
{
backup as copy current controlfile for standby auxiliary format /u/app/oracle/oradata/orcl/controlctl;
sql clone alter database mount standby database;
}
executing Memory Script
Starting backup at APR
channel d: starting datafile copy
copying standby control file
output file name=/home/oracle/snapcf_orclf tag=TAGT RECID= STAMP=
channel d: datafile copy complete elapsed time: ::
Finished backup at APR
sql statement: alter database mount standby database
contents of Memory Script:
{
set newname for tempfile to
/u/app/oracle/oradata/orcl/tempdbf;
switch clone tempfile all;
set newname for datafile to
/u/app/oracle/oradata/orcl/systemdbf;
set newname for datafile to
/u/app/oracle/oradata/orcl/sysauxdbf;
set newname for datafile to
/u/app/oracle/oradata/orcl/undotbsdbf;
set newname for datafile to
/u/app/oracle/oradata/orcl/usersdbf;
set newname for datafile to
/u/app/oracle/oradata/orcl/exampledbf;
backup as copy reuse
datafile auxiliary format
/u/app/oracle/oradata/orcl/systemdbf datafile
auxiliary format
/u/app/oracle/oradata/orcl/sysauxdbf datafile
auxiliary format
/u/app/oracle/oradata/orcl/undotbsdbf datafile
auxiliary format
/u/app/oracle/oradata/orcl/usersdbf datafile
auxiliary format
/u/app/oracle/oradata/orcl/exampledbf ;
sql alter system archive log current;
}
executing Memory Script
executing command: SET NEWNAME
renamed tempfile to /u/app/oracle/oradata/orcl/tempdbf in control file
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
Starting backup at APR
channel d: starting datafile copy
input datafile file number= name=/u/app/oracle/oradata/orcl/sysauxdbf
channel d: starting datafile copy
input datafile file number= name=/u/app/oracle/oradata/orcl/systemdbf
output file name=/u/app/oracle/oradata/orcl/systemdbf tag=TAGT RECID= STAMP=
channel d: datafile copy complete elapsed time: ::
channel d: starting datafile copy
input datafile file number= name=/u/app/oracle/oradata/orcl/undotbsdbf
output file name=/u/app/oracle/oradata/orcl/sysauxdbf tag=TAGT RECID= STAMP=
channel d: datafile copy complete elapsed time: ::
channel d: starting datafile copy
input datafile file number= name=/u/app/oracle/oradata/orcl/exampledbf
output file name=/u/app/oracle/oradata/orcl/exampledbf tag=TAGT RECID= STAMP=
channel d: datafile copy complete elapsed time: ::
channel d: starting datafile copy
input datafile file number= name=/u/app/oracle/oradata/orcl/usersdbf
output file name=/u/app/oracle/oradata/orcl/undotbsdbf tag=TAGT RECID= STAMP=
channel d: datafile copy complete elapsed time: ::
output file name=/u/app/oracle/oradata/orcl/usersdbf tag=TAGT RECID= STAMP=
channel d: datafile copy complete elapsed time: ::
Finished backup at APR
sql statement: alter system archive log current
contents of Memory Script:
{
backup as copy reuse
archivelog like /u/app/oracle/flash_recovery_area/ORCL/log___arc auxiliary format
/u/app/oracle/flash_recovery_area/STDBY/log___arc ;
catalog clone archivelog /u/app/oracle/flash_recovery_area/STDBY/log___arc;
switch clone datafile all;
}
executing Memory Script
Starting backup at APR
channel d: starting archived log copy
input archived log thread= sequence= RECID= STAMP=
output file name=/u/app/oracle/flash_recovery_area/STDBY/log___arc RECID= STAMP=
channel d: archived log copy complete elapsed time: ::
Finished backup at APR
cataloged archived log
archived log file name=/u/app/oracle/flash_recovery_area/STDBY/log___arc RECID= STAMP=
datafile switched to datafile copy
input datafile copy RECID= STAMP= file name=/u/app/oracle/oradata/orcl/systemdbf
datafile switched to datafile copy
input datafile copy RECID= STAMP= file name=/u/app/oracle/oradata/orcl/sysauxdbf
datafile switched to datafile copy
input datafile copy RECID= STAMP= file name=/u/app/oracle/oradata/orcl/undotbsdbf
datafile switched to datafile copy
input datafile copy RECID= STAMP= file name=/u/app/oracle/oradata/orcl/usersdbf
datafile switched to datafile copy
input datafile copy RECID= STAMP= file name=/u/app/oracle/oradata/orcl/exampledbf
contents of Memory Script:
{
set until scn ;
recover
standby
clone database
delete archivelog
;
}
executing Memory Script
executing command: SET until clause
Starting recover at APR
starting media recovery
archived log for thread with sequence is already on disk as file /u/app/oracle/flash_recovery_area/STDBY/log___arc
archived log file name=/u/app/oracle/flash_recovery_area/STDBY/log___arc thread= sequence=
media recovery complete elapsed time: ::
Finished recover at APR
Finished Duplicate Db at APR
released channel: d
released channel: d