前言
日益增长的分布式应用需求要求实现更好分布式的软件环境,不断推动着分布式技术的进步。Oracle数据复制是实现分布式数据环境的一种技术,通过在不同的物理站点拷贝数据来建立分布式数据环境。它与分布式数据库不同,在分布式数据库中,虽然每个数据对象也对所有的站点可用,但是特定的数据对象只存在于一个特定的站点中。而数据复制实现所有的站点都有相同数据对象的可用拷贝。
在一个典型的分布式商业应用中经常需要把个地区的数据备份到总部的数据库中,一方面可以作为一种备份方式,另一方面也方便总部应用中的综合统计。这是Oracle数据复制中的简单应用,本文将以这样一个例子,讲述如何实现Oracle数据复制。
实际情况是,A公司总部在北京,有三个营业部分别位于上海(ORACLE.SHANGHAI.COM)、杭州(ORACLE.HANGZHOU.COM)和武汉(ORACLE.WUHAN.COM)。三个营业部的软件系统相同,数据库结构也相同。现在需要把三个营业部的数据全部备份到总部的数据库中。
准备工作
在进行复制之前需要准备的东西很多,当然最基础就是网络必须畅通,之后需要收集一些复制环境的基本信息:
1. 需要复制的数据库站点的数量。
2. 每个站点的Oracle版本号。
3. 每个需要复制的数据库的大小。
4. 每个数据库所使用的字符集。
5. 每个需要复制的数据所用的方案名。
收集完环境信息,可以开始建立总部的集中数据库,集中数据库要求版本高于所有主战点的版本,最好所有的数据库都是用相同的字符集。建好库后为每个主站点的备份数据分别建一个表空间,表空间大于需要复制的数据量,至于预留以后的发展空间视实际情况而定。
为每个主站点的对应复制数据建立方案,如果各个主站点所使用的方案名不同,在集中数据库站点分别建立名称相同的对应方案。否则为各主站点的复制数据分别建立相应的方案名。实际情况是后者,各营业部的数据库都是用Oracle的方案名,这里我们建立三个对应方案:SHORACL、HZORACL 和WHORACL。所有数据库的版本都是9i。
基本概念
复制之前先解释一下复制中的几个概念:
1.主站点(Mater Site):在复制过程中提供数据源的站点。如上图中的上海数据库站点。
2.实体化视图站点(Materialized View Site):实体化视图复制中的目标站点。如上图中的北京数据库站点。
3.多主体站点复制(Multimaster Replication):复制环境中的站点都是主站点,对复制的数据库对象有相同的管理权限。
4.实体化视图复制(Materialized View Replication): 一个主体站点提供源复制对象,一个实体化视图站点拷贝主站点数据。
5.实体化视图(Materialized View):在实体化视图站点为每个复制表或者视图建立一个对应的表保存相应的数据,该表只能通过Oracle的复制机制进行增删改数据的操作。
6. 快速刷新、完全刷新和强制刷新:复制过程中的三种刷新方式。快速刷新只复制源数据对象的改变部分;完全刷新每次都拷贝一遍源数据对象;强制刷新是数据库的一个折衷方案,如果快速刷新失败则使用完全刷新。
7. 主体组(Master Group):主体站点中被复制的源数据对象的集合。
8. 实体化视图组(Materialized View Site):实体化视图站点中复制对象的集合。
9. 实体化视图日志(Materialized View Log):实体化视图复制中使用快速刷新时记录主体源数据对象操作日志的表。
同步复制和异步复制就不解释了,本例采用每天一次的异步复制。
进行复制
配置好本地服务名分别为:上海站点:SH,杭州站点:HZ,武汉站点:WH,北京站点:BJ,进入没有登录的sqlplus,让我们开始复制!
一.设置主站点。
这里以上海主站点设置为例。
1.连接主站点,创建复制管理员并授予相应的权限,复制管理员是管理整个复制环境并创建复制对象的用户。只有数据管理员可以建立主体组和实体化视图组。
| connect system/passwd@SH create user repadmin identified by repadmin; begin dbms_repcat_admin.grant_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; |
2.注册传播方,传播方会将主体站点的延迟事务队列推入其他主体站点或者实体化视图站点。
begin dbms_defer_sys.register_purpagator(username=>’repadmin’); |
3.调度清除作业,该作业会定时清除延迟事务队列并用传播方将延迟事务推入其他主体站点或者实体化视图站点。先更换用户:
| disconnect; connect repadmin/repadmin@SH; begin dbms_defer_sys.schedule_purge( next_date=>sysdate,interval=>’sysdate + 1’,delay_seconds=>0); end; |
next_date:下一次执行日期,sysdate表示立即。
interval:间隔时段,sysdate + 1表示间隔一天,sysdate+ 1/24表示间隔一小时。
delay_seconds:当延迟队列没有延迟事件时停止被次清除操作的延迟时间。
4.为实体化视图站点建立复制代理。创建复制代理用户并授予视图接受方权限。复制代理是复制接收方连接主体站点的用户:
| disconnect; connect system/passwd@SH; create user proxy_bjoracle identified by proxy_bjoracle; begin dbms_repcat_admin.register_user_repgroup( user_name=>’proxy_bjoracle, privilege_type => ’proxy_snapadmin’,list_of_gnames => NULL); end; /grant select_catalog_role to proxy_bjoracle; |
5. 创建主体组。
| disconnect; connect repadmin/repadmin@SH; begin dbms_repcat.create_master_repgroup(gname=>’sh_rep’); end; / |
6. 向主体组中添加复制对象
a) 添加表:
| begin dbms_repcat.create_master_repobject( gname=>’sh_rep’, type=>’TABLE’, name=>’ CREDIT_CARD’ sname=>’SHORACL’ use_existing_object=>TRUE, copy_rows=>TRUE); end; |
b) 添加索引
| begin dbms_repcat.create_master_repobject( gname=>’sh_rep’, type=>’INDEX’, name=>’ INDEX_CREDIT_CARD’ sname=>’SHORACL’ use_existing_object=>TRUE, copy_rows=>FALSE); end; / |
7. 如果添加的表没有主键需要设置可以代替主键的列或者列的集合
| begin dbms_repcat.set_columns( sname => ’SHORACL’, name => ’ CREDIT_CARD ’, column_list => ’ CREDIT_CARD_ID’); end; / |
8. 在主体组中的数据对象可以被复制之前,必须为他们生成复制支持。该方法为复制创建必要的触发器、包或者存储过程:
| begin dbms_repcat.generate_replication_support( sname=>’SHORACL’, name=>’ CREDIT_CARD’, type=>’TABLE’, min_communication=>TRUE); end; / |
9. 为快速刷新创建实体化视图日志:
create materialized view log on SHORACL. CREDIT_CARD; |
如果是没有主键的表示用一下语句:
| create materialized view log on SHORACL. CREDIT_CARD with rowid excluding new values; |
10.启动复制:
begin dbms_repcat.resume_master_activity( name=>’sh_rep’); end; / |
二.设置实体化视图站点。
1.创建复制管理员并授予相应的权限:
| 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; |
2.注册传播方:
begin dbms_defer_sys.register_propagator( username => ’mvadmin’); end; / |
3.公共数据库连接。需要每个复制需要创建三个数据库连接。公共数据库连接指定数据库的全局名称:
create public database link ORACLSH using ’oracle.shanghai. com’; |
Using子句后跟的是全局数据库名或者是连接字符串。
| create public database link ORACLSH using ’(description= (address=(protocol=tcp)(host=127.0.0.1)(port=1521)) (connect_data=(service_name=oracl)))’ |
4.建立清除延迟事务队列调度作业:
| disconnect; connect mvadmin/mvadmin@BJ; begin dbms_defer_sys.schedule_purge( next_date => sysdate, interval => ’/*1:hr*/ sysdate + 1’, delay_seconds => 0, rollback_segment => ’’); end; |
5.建立复制管理员mvadmin的数据库连接:
| create database link ORACLSH connect to proxy_bjoracle identified by proxy_bjoralce Connect to ... Identified by ...子句指明用什么用户连接远程数据库 |
6.建立复制调度数据库连接作业:
| begin dbms_defer_sys.schedule_push( destination => ’ora92zjk’,interval => ’/*1:hr*/ sysdate + 1’, next_date => sysdate,stop_on_error => false, delay_seconds => 0,parallelism => 0); end; / |
7.授予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; |
8.建立复制方案的数据库连接:
| disconnect; connect SHORACL/SHORACL@BJ; create database link ORACLSH connect to ORACL identified by ORACL; |
复制方案的数据库连接和复制管理员的数据库连接要和system用户间里的对应公共数据库连接使用相同的名字,在调度连接时将使用公共数据库连接中指定的数据库全局名或者连接字符串。
9.建立实体化视图:
| disconnect; connect mvadmin/mvadmin@BJ; create materialized view SHORACL.CREDIT_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; |
10.为多个视图建立刷新组:
| begin dbms_refresh.make ( name => ’mvadmin.sh_refresh’,list => ’’, next_date => sysdate,interval => ’sysdate + 1’, implicit_destroy => false,rollback_seg => ’’, push_deferred_rpc => true,refresh_after_errors => false); end; |
11.向刷新组中添加复制对象:
| begin dbms_refresh.add (name => ’mvadmin.sh_refresh’,list => ’SHORACL.CREDIT_CARD ’,lax => true); end; / |
三.检查复制进程。
1.查看sys.dba_jobs视图是否生成了足够的作业。
经过以上的步骤应该有三个作业分别是清除作业、调度作业和刷新作业,查看视图的what字段是否有下面的内容:
| a) declare rc binary_integer; begin rc := sys.dbms_defer_sys. purge( delay_seconds=>0); end; b) declare rc binary_integer; begin rc := sys.dbms_defer_sys. push(destination=>’ORACLSH’, stop_on_error=>FALSE, delay_seconds=>0, parallelism=>0); end; c) dbms_refresh.refresh(’"MVADMIN"."SH_REFRESH"’); |
如果排除其它系统作业本例中杭州和武汉的数据库复制建立之后将会有7个作业(如果为每个复制分别建立刷新组的话),清除作业始终只有一个。每个复制对应一个调度作业,每个刷新组对应一个刷新作业。
2.查看job_queue_processes参数,确保该参数不为零(数据库的默认值是零),如果该参数为零,除非每次手工执行刷新,否则系统不会自动刷新复制数据。
3.确保复制执行之后,观察sys.dba_jobs视图的failures字段。如果复制在刷新过程中除错,Oracle会自动在1分钟之后再次尝试刷新,失败之后再在2分钟、4分钟、8分钟..之后尝试刷新,直到失败次数达到16次或者间隔时间超过作业设置的间隔时间,该作业将被标记为中断,Oracle不再执行该作业。要重新执行改作业使用dbms_job包的run过程:
begin dbms_job.run(job_no); end; / |
job_no 是sys.dba_jobs 的Job字段的值,作业号。在重新执行因出错而中断的作业前,需要手工找到出错点,并更正。
总结
本文只是使用了Oracle高级复制中最简单的功能,Oracle的高级复制还提供可更新视图和复杂的只读实体化视图复制,当然并不是我们都要去用高级复杂强大的功能,在具体应用的时候,还要根据系统功能和性能需求,选择适当的复制技术。
1、数据库支持高级复制功能
您可以用system身份登录数据库,查看v$option视图,如果其中Advanced replication为TRUE,则支持高级复制功能;否则不支持。
2、数据库初始化参数要求
①、db_domain = test.com.cn
指明数据库的域名(默认的是WORLD),这里可以用您公司的域名。
②、global_names = true
它要求数据库链接(database link)和被连接的数据库名称一致。
现在全局数据库名:db_name+”.”+db_domain
③、有跟数据库job执行有关的参数
job_queue_processes = 1 定义SNP进程的启动个数为n。系统缺省值为0,正常定义范围为0~36,根据任务的多少,可以配置不同的数值。
job_queue_interval = 60 定义系统每隔N秒唤醒该进程一次。系统缺省值为60秒,正常范围为1~3600秒。事实上,该进程执行完当前任务后,就进入睡眠状态,睡眠一段时间后,由系统的总控负责将其唤醒。
distributed_transactions = 10
open_links = 4
如果修改了以上这几个参数,需要重新启动数据库以使参数生效。
数据库名 ying orcl
数据库域名 test.com.cn test.com.cn
数据库sid号 ying orcl
Listener端口号 1521 1521
服务器ip地址 10.10.3.76 10.10.3.74
2、改数据库全局名称,建公共的数据库链接。
①、用system身份登录ying数据库
alter database rename global_name to ying.test.com.cn
用system身份登录orcl数据库:
alter database rename global_name to orcl.test.com.cn
②、用system身份登录ying数据库
create public database link ying.test.com.cn using 'ying';
select * from global_name@ying.test.com.cn
用system身份登录orcl数据库:
create public database link orcl.test.com.cn using 'orcl'
select * from global_name@orcl.test.com.cn
3、建立管理数据库复制的用户repadmin,并赋权。
①、用system身份登录ying数据库
create user repadmin identified by repadmin default tablespace users temporary tablespace temp
begin
dbms_defer_sys.register_propagator('repadmin');
end;
grant execute any procedure to repadmin;
begin
dbms_repcat_admin.grant_admin_any_repgroup('repadmin');
end;
grant comment any table to repadmin;
grant lock any table to repadmin;
②、同样用system身份登录orcl数据库,运行以上的命令,管理数据库复制的用户repadmin,并赋权。
create user repadmin identified by repadmin default tablespace users temporary tablespace temp
begin
dbms_defer_sys.register_propagator('repadmin');
end;
grant execute any procedure to repadmin;
begin
dbms_repcat_admin.grant_admin_any_repgroup('repadmin');
end;
grant comment any table to repadmin;
grant lock any table to repadmin;
*********************************************************************
说明:repadmin用户名和密码可以根据用户的需求自由命名。
*********************************************************************
4、在数据库复制的用户repadmin下创建私有的数据库链接。
①、用repadmin身份登录ying数据库
create database link orcl.test.com.cn connect to repadmin identified by repadmin;
select * from global_name@orcl.test.com.cn; --测试
②、用repadmin身份登录orcl数据库
create database link ying.test.com.cn connect to repadmin identified by repadmin;
select * from global_name@ying.test.com.cn; --测试
5、创建或选择实现数据库复制的用户和对象,给用户赋权,数据库对象必须有主关键字。
假设我们用Oracle里举例用的water用户,t_file_all表。
①、用internal身份登录ying数据库,创建water用户并赋权
SQL>create user water identified by water default tablespace water temporary tablespace water;
SQL>grant connect, resource to water;
SQL>grant execute on sys.dbms_defer to water;
②、用water身份登录ying数据库,创建表t_file_all
③、如果数据库对象没有主关键字,可以运行以下SQL命令添加:
alter table t_file_all add (constraint t_file_all_key primary key (t_file_all_id));
④、在ying数据库water用户下创建主关键字的序列号,范围避免和orcl的冲突。
⑤、在ying数据库water用户下插入初始化数据
⑥、在orcl数据库那边同样运行以上①,②,③
⑦、在orcl数据库water用户下创建主关键字的序列号,范围避免和water的冲突。
⑧、在beijing数据库scott用户下插入初始化数据
6、创建要复制的组water_t_file_all,加入数据库对象,产生对象的复制支持
①、用repadmin身份登录ying数据库,创建主复制组water_t_file_all
begin
dbms_repcat.create_master_repgroup('water_t_file_all');
end;
②、在复制组scott_mg里加入数据库对象
begin
dbms_repcat.create_master_repobject
(sname=>'water',oname=>'t_file_all',
type=>'table',use_existing_object=>true,
gname=>'water_t_file_all'
);
end;
*******************************
参数说明:
sname 实现数据库复制的用户名称
oname 实现数据库复制的数据库对象名称
(表名长度在27个字节内,程序包名长度在24个字节内)
type 实现数据库复制的数据库对象类别
(支持的类别:表,索引,同义词,触发器,视图,过程,函数,程序包,程序包体)
use_existing_object true表示用主复制节点已经存在的数据库对象
gname 主复制组名
*******************************
③、对数据库对象产生复制支持
begin
dbms_repcat.generate_replication_support('water','t_file_all','table');
end;
(说明:产生支持water用户下t_file_all表复制的数据库触发器和程序包)
④、确认复制的组和对象已经加入数据库的数据字典
select gname, master, status from dba_repgroup --测试
select * from dba_repobject --测试
7、创建主复制节点
①、用repadmin身份登录ying数据库,创建主复制节点
begin
dbms_repcat.add_master_database
(gname=>'water_t_file_all',
master=>'orcl.test.com.cn',
use_existing_objects=>true,
copy_rows=>false,
propagation_mode => 'asynchronous');
end;
**********************************************
参数说明:
gname 主复制组名
master 加入主复制节点的另一个数据库
use_existing_object true表示用主复制节点已经存在的数据库对象
copy_rows false表示第一次开始复制时不用和主复制节点保持一致
propagation_mode 异步地执行
***********************************************
select * from user_jobs; --测试是否在复制任务中
8、使同步组的状态由停顿(quiesced )改为正常(normal)
①、用repadmin身份登录ying数据库,运行以下命令
begin
dbms_repcat.resume_master_activity('water_t_file_all',false);
end;
--不行用该命令
begin
dbms_repcat.resume_master_activity('water_t_file_all',true);
end;
--测试同步是否正常(status为normal)
select gname, master, status from dba_repgroup
9、创建复制数据库的时间表,我们假设用固定的时间表:1分钟复制一次。
①、用repadmin身份登录ying数据库,运行以下命令
begin
dbms_defer_sys.schedule_push (
destination => 'orcl.test.com.cn',
interval => 'sysdate + 1/(60*24)', --每隔1分钟
next_date => sysdate);
end;
/
begin
dbms_defer_sys.schedule_purge (
next_date => sysdate,
interval => 'sysdate + 1/(60*24)',
delay_seconds => 0,
rollback_segment => '');
end;
②、用repadmin身份登录orcl数据库,运行以下命令
begin
dbms_defer_sys.schedule_push (
destination => 'ying.test.com.cn',
interval => 'sysdate + 1/(60*24)', --每隔1分钟
next_date => sysdate);
end;
/
begin
dbms_defer_sys.schedule_purge (
next_date => sysdate,
interval => 'sysdate + 1/(60*24)', --每隔1分钟
delay_seconds => 0,
rollback_segment => '');
end;
10、添加或修改两边数据库的记录,跟
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12122734/viewspace-429481/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/12122734/viewspace-429481/
1168

被折叠的 条评论
为什么被折叠?



