前言
日益增长的分布式应用需求要求实现更好分布式的软件环境不断推动着分布式技术的进步Oracle数据复制是实现分布式数据环境的一种技术通过在不同的物理站点拷贝数据来建立分布式数据环境它与分布式数据库不同在分布式数据库中虽然每个数据对象也对所有的站点可用但是特定的数据对象只存在于一个特定的站点中而数据复制实现所有的站点都有相同数据对象的可用拷贝
在一个典型的分布式商业应用中经常需要把个地区的数据备份到总部的数据库中一方面可以作为一种备份方式另一方面也方便总部应用中的综合统计这是Oracle数据复制中的简单应用本文将以这样一个例子讲述如何实现Oracle数据复制
实际情况是A公司总部在北京有三个营业部分别位于上海(ORACLESHANGHAICOM)杭州(ORACLEHANGZHOUCOM)和武汉(ORACLEWUHANCOM)三个营业部的软件系统相同数据库结构也相同现在需要把三个营业部的数据全部备份到总部的数据库中
准备工作
在进行复制之前需要准备的东西很多当然最基础就是网络必须畅通之后需要收集一些复制环境的基本信息
. 需要复制的数据库站点的数量
. 每个站点的Oracle版本号
. 每个需要复制的数据库的大小
. 每个数据库所使用的字符集
. 每个需要复制的数据所用的方案名
收集完环境信息可以开始建立总部的集中数据库集中数据库要求版本高于所有主战点的版本最好所有的数据库都是用相同的字符集建好库后为每个主站点的备份数据分别建一个表空间表空间大于需要复制的数据量至于预留以后的发展空间视实际情况而定
为每个主站点的对应复制数据建立方案如果各个主站点所使用的方案名不同在集中数据库站点分别建立名称相同的对应方案否则为各主站点的复制数据分别建立相应的方案名实际情况是后者各营业部的数据库都是用Oracle的方案名这里我们建立三个对应方案SHORACLHZORACL 和WHORACL所有数据库的版本都是i
基本概念
复制之前先解释一下复制中的几个概念
.主站点(Mater Site)在复制过程中提供数据源的站点如上图中的上海数据库站点
.实体化视图站点(Materialized View Site)实体化视图复制中的目标站点如上图中的北京数据库站点
.多主体站点复制(Multimaster Replication)复制环境中的站点都是主站点对复制的数据库对象有相同的管理权限
.实体化视图复制(Materialized View Replication) 一个主体站点提供源复制对象一个实体化视图站点拷贝主站点数据
.实体化视图(Materialized View)在实体化视图站点为每个复制表或者视图建立一个对应的表保存相应的数据该表只能通过Oracle的复制机制进行增删改数据的操作
. 快速刷新完全刷新和强制刷新复制过程中的三种刷新方式快速刷新只复制源数据对象的改变部分完全刷新每次都拷贝一遍源数据对象强制刷新是数据库的一个折衷方案如果快速刷新失败则使用完全刷新
. 主体组(Master Group)主体站点中被复制的源数据对象的集合
. 实体化视图组(Materialized View Site)实体化视图站点中复制对象的集合
. 实体化视图日志(Materialized View Log)实体化视图复制中使用快速刷新时记录主体源数据对象操作日志的表
同步复制和异步复制就不解释了本例采用每天一次的异步复制
进行复制
配置好本地服务名分别为上海站点SH杭州站点HZ武汉站点WH北京站点BJ进入没有登录的sqlplus让我们开始复制!
一.设置主站点
这里以上海主站点设置为例
.连接主站点创建复制管理员并授予相应的权限复制管理员是管理整个复制环境并创建复制对象的用户只有数据管理员可以建立主体组和实体化视图组
connect system/passwd@SH create user repadmin identified by repadmin; begin dbms_repcat_admingrant_admin_any_schema( username=>repadmin);
end;
/grant comment any table to REPADMIN; grant lock any table to REPADMIN;
后面的两个grant语句使复制管理员可以为任何表建立实体化视图日志如果想改用户可以使用视图管理器还需要下面的命令
grant select any dictionary to REPADMIN;
.注册传播方传播方会将主体站点的延迟事务队列推入其他主体站点或者实体化视图站点
begin dbms_defer_sysregister_purpagator(username=>repadmin);
end;
.调度清除作业该作业会定时清除延迟事务队列并用传播方将延迟事务推入其他主体站点或者实体化视图站点先更换用户
disconnect; connect repadmin/repadmin@SH; begin dbms_defer_sysschedule_purge( next_date=>sysdateinterval=>sysdate + delay_seconds=>);
end;
next_date下一次执行日期sysdate表示立即
interval间隔时段sysdate + 表示间隔一天sysdate+ /表示间隔一小时
delay_seconds当延迟队列没有延迟事件时停止被次清除操作的延迟时间
.为实体化视图站点建立复制代理创建复制代理用户并授予视图接受方权限复制代理是复制接收方连接主体站点的用户
disconnect; connect system/passwd@SH;
create user proxy_bjoracle identified by proxy_bjoracle;
begin dbms_repcat_adminregister_user_repgroup( user_name=>proxy_bjoracle privilege_type => proxy_snapadminlist_of_gnames => NULL);
end;
/grant select_catalog_role to proxy_bjoracle;
. 创建主体组
disconnect; connect repadmin/repadmin@SH; begin dbms_repcatcreate_master_repgroup(gname=>sh_rep);
end; /
. 向主体组中添加复制对象
a) 添加表
begin dbms_repcatcreate_master_repobject( gname=>sh_rep type=>TABLE oname=> CREDIT_CARD sname=>SHORACL use_existing_object=>TRUE copy_rows=>TRUE); end;b) 添加索引
begin dbms_repcatcreate_master_repobject( gname=>sh_rep type=>INDEX oname=> INDEX_CREDIT_CARD sname=>SHORACL use_existing_object=>TRUE copy_rows=>FALSE); end; /. 如果添加的表没有主键需要设置可以代替主键的列或者列的集合
begin dbms_repcatset_columns( sname => SHORACL oname => CREDIT_CARD column_list => CREDIT_CARD_ID); end; /. 在主体组中的数据对象可以被复制之前必须为他们生成复制支持该方法为复制创建必要的触发器包或者存储过程
begin dbms_repcatgenerate_replication_support( sname=>SHORACL oname=> CREDIT_CARD type=>TABLE min_communication=>TRUE); end; /. 为快速刷新创建实体化视图日志
create materialized view log on SHORACL CREDIT_CARD;
如果是没有主键的表示用一下语句
create materialized view log on SHORACL CREDIT_CARD with rowid excluding new values;.启动复制
begin dbms_repcatresume_master_activity( name=>sh_rep); end; /
二.设置实体化视图站点
.创建复制管理员并授予相应的权限
disconnect; connect system/passwd@BJ; create user mvadmin identified by mvadmin; begin dbms_repcat_admin grant_admin_any_schema(username=> mvadmin); end; /grant comment any table to mvadmin; grant lock any table to mvadmin; grant select any dictionary to mvadmin;.注册传播方
begin dbms_defer_sysregister_propagator( username => mvadmin); end; /
.公共数据库连接需要每个复制需要创建三个数据库连接公共数据库连接指定数据库的全局名称
create public database link ORACLSH using oracleshanghai com;
Using子句后跟的是全局数据库名或者是连接字符串
create public database link ORACLSH using (description= (address=(protocol=tcp)(host=)(port=)) (connect_data=(service_name=oracl))).建立清除延迟事务队列调度作业
disconnect; connect mvadmin/mvadmin@BJ; begin dbms_defer_sysschedule_purge( next_date => sysdate interval => /*:hr*/ sysdate + delay_seconds => rollback_segment => ); end;.建立复制管理员mvadmin的数据库连接
create database link ORACLSH connect to proxy_bjoracle identified by proxy_bjoralce Connect to Identified by 子句指明用什么用户连接远程数据库.建立复制调度数据库连接作业
begin dbms_defer_sysschedule_push( destination => orazjkinterval => /*:hr*/ sysdate + next_date => sysdatestop_on_error => false delay_seconds => parallelism => ); end; /.授予SHORACL用户(对应SHORACL方案)
相应的权限建立实体化视图
disconnect; connect system/passwd@BJ;
grant alter session to crm;
grant create cluster to crm;
grant create database link to crm;
grant create sequence to crm;
grant create session to crm;
grant create synonym to crm;
grant create table to crm;
grant create view to crm;
grant create procedure to crm;
grant create trigger to crm;
grant unlimited tablespace to crm;
grant create type to crm;
grant create any snapshot to crm;
grant alter any snapshot to crm;
.建立复制方案的数据库连接
disconnect; connect SHORACL/SHORACL@BJ;
create database link ORACLSH connect to ORACL identified by ORACL;
复制方案的数据库连接和复制管理员的数据库连接要和system用户间里的对应公共数据库连接使用相同的名字在调度连接时将使用公共数据库连接中指定的数据库全局名或者连接字符串
.建立实体化视图
disconnect; connect mvadmin/mvadmin@BJ;
create materialized view SHORACLCREDIT_CARD refresh fast wit h pr imar y key as sele ct * from ORA CL CREDIT_CARD@ORACLSH;
@后面是数据库连接名如果该表没有主键则使用rowid来刷新
create materialized view SHORACL CREDIT_CARD refresh fast with rowid as select * from ORACL CREDIT_CARD@ORACLSH;.为多个视图建立刷新组
begin dbms_refreshmake ( name => mvadminsh_refreshlist => next_date => sysdateinterval => sysdate + implicit_destroy => falserollback_seg => push_deferred_rpc => truerefresh_after_errors => false); end;.向刷新组中添加复制对象
begin dbms_refreshadd (name => mvadminsh_refreshlist => SHORACLCREDIT_CARD lax => true); end; /三.检查复制进程
.查看sysdba_jobs视图是否生成了足够的作业
经过以上的步骤应该有三个作业分别是清除作业调度作业和刷新作业查看视图的what字段是否有下面的内容
a) declare rc binary_integer; begin rc := sysdbms_defer_sys purge( delay_seconds=>); end;
b) declare rc binary_integer; begin rc := sysdbms_defer_sys push(destination=>ORACLSH stop_on_error=>FALSE delay_seconds=> parallelism=>);
end;
c) dbms_refreshrefresh(MVADMINSH_REFRESH);
如果排除其它系统作业本例中杭州和武汉的数据库复制建立之后将会有个作业(如果为每个复制分别建立刷新组的话)清除作业始终只有一个每个复制对应一个调度作业每个刷新组对应一个刷新作业
.查看job_queue_processes参数确保该参数不为零(数据库的默认值是零)如果该参数为零除非每次手工执行刷新否则系统不会自动刷新复制数据
.确保复制执行之后观察sysdba_jobs视图的failures字段如果复制在刷新过程中除错Oracle会自动在分钟之后再次尝试刷新失败之后再在分钟分钟分钟之后尝试刷新直到失败次数达到次或者间隔时间超过作业设置的间隔时间该作业将被标记为中断Oracle不再执行该作业要重新执行改作业使用dbms_job包的run过程
begin dbms_jobrun(job_no); end; /
job_no 是sysdba_jobs 的Job字段的值作业号在重新执行因出错而中断的作业前需要手工找到出错点并更正
总结
本文只是使用了Oracle高级复制中最简单的功能Oracle的高级复制还提供可更新视图和复杂的只读实体化视图复制当然并不是我们都要去用高级复杂强大的功能在具体应用的时候还要根据系统功能和性能需求选择适当的复制技术