高级复制的初步研究
张彦星 整理
2006 年9 月
1. Replication 使用分布式数据库技术在多个站点之间共享数据。
2. Replicated Database 和Distributed Database 并不一样,在分布式数据库系统中数据在多个站点同时有效,但是一个表只会存在于一个站点中,而对于Replication 来说相同
的数据将同时存在于多个站点中。
3. 使用replication 的原因:
1) Availability:也就是提供了优秀的failover 保护
2) Performance:由于有多个server,所以可以将用户业务分布在不同的server 上
3) Disconnected computing:实体化视图允许用户在和master 断开后使用数据库的子集,在重新连接上master 之后再进行两者的同步。
4) Network load reduction:由于有多个server,所以可以减少master 的网络请求
5) Mass deployment:通过变量产生自定义的实体化视图以满足多种需求
4. 在不同的Oracle 发行版本之间以及不同操作系统的Oracle 之间都可以使用Advanced
Replication。
5. Replication 中的几个概念:
1) replication object:复制对象,指需要作复制的对象(object),包括表,索引,
存储过程等等。复制对象的更新遵循事务一致性规则(transactionally consistent
manner)。
2) replication groups:复制组,是复制对象(replication object)的集合称为group,
oracle 以replication group 的形式来管理复制。一个组可以包含多个模式的object,
一个模式也可以有多个组中的object,但是每个replication object 都只能属于一个
replication group。
3) replication sites:复制站点,包含两种类型,主体站点(master sites)和实
体化视图站点(materialized view sites)。一个site 可以担任一个replication
group 中的mater site 同时又担任另外一个replication group 中的materialized
view site,注意必须是另外一个组,而不能是同一个replication group。
4) scheduled links:一个数据库链接(database link),包含一个由用户定义的计划,
来将需要更新的事务推到其它的master sites,当创建scheduled link 的时候,oracle
将在本地任务队列中创建一个任务。
5) master definition site:主体定义站点,大部分的高级复制配置都需要在一个站
点上作,这个站点就是maserdef site。
6. Replication 环境的几种类型
1) Multimaster Replication
2) Materialized View Replication(也可以称为是Single Master Replication)
3) Multimaster and Materialized View Hybrid Configurations
Multimaster Replication 和Materialized View Replication 的区别在于:
前者必须是全表复制而后者可以是master 表的一部分
前者允许在每一个transaction 之后都进行复制,而后者是属于批处理复制
两者都使用scheduled links 进行数据同步操作。
Materialized View Replication 中的materialized view 可能有以下几种类型:
1) Read-Only Materialized Views:只读的实体化视图
2) Updatable Materialized Views:允许更新,同时允许将更新复制到master site
3) Writeable Materialized Views:允许更新,但是每次refresh 的时候,更新都会丢失
7. 介绍Multimaster Replication 中的复制方式
1) Asynchronous replication
在一个master 上发生的变化将在推后的时间内更新到其他的master 上
2) Synchronous replication
在一个master 上发生的变化将立刻更新到其他的master 上
3) Procedural replication
必须给每个site 上的包都生成一个wrapper,所有的数据变化应该通过包中的存储过程完成,当某个master 上的procedure 被调用,wapper 将保证其他site 中的存储过程也被调用(同步或者不同步)。将大量的数据操作放到一个procedure 中,然后对于procedure 的调用将被同步,用处在于在于有大数据量操作的时候可以减少网络负载。
多主体复制站点的配置步骤
以下操作如果不是明确指出,均在master 数据库中运行。
1。检查安装好的数据库是否支持高级复制:
SQL> select value from v$option where parameter='Advanced replication';
VALUE
----------------------------------------------------------------
TRUE
确保返回的结果是TRUE,如果是FALSE 则表示需要重新安装oracle 的高级复制部件。
2。确保数据库的初始化参数中global_name=true,同时因为高级复制依靠于JOB 来实现,
所以必须保证job_queue_processes 参数大于0,我们可以设置为10。
使用下面的命令更改:
alter system set golbal_name = true
alter system set job_queue_processes = 10
确保init.ora 中包含一下初始化参数定义:
global_names = true
open_links = 4 (备注:一个process 需要4 个link,如果我们创建了多个dblink,并且同时运行,那么可以把此参数设大,比如以下环境中我们应该设置为open_links = 8)
job_queue_processes = 10
3。用sysdba 权限分别登录master 和snap 数据库,检查双方的global_name,必须保证
两边的域名相同才可以建立正确的dblink。
select * from global_name;
假设显示结果是master.com,那么表示该数据库的域名是com。那么我们可以设置snap
库的global_name 是snap.com。
使用以下SQL 设置global_name:
alter database rename global_name to master.com;
4。创建一个PUBLIC DBLINK 连接到snap(此步骤可以省略)
CREATE PUBLIC DATABASE LINK "snap.com" USING '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.3.100)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=snap)))';
运行以下SQL 检查dblink 创建是否成功,如果结果返回snap 的global_name 则表示成功
SQL> select * from global_name@snap.com;
GLOBAL_NAME
---------------------------------------------------------------------------
SNAP.COM
5。创建repadmin 用户,用于管理高级复制
create user repadmin identified by repadmin default tablespace users temporary
tablespace temp;
execute dbms_defer_sys.register_propagator('repadmin');
grant execute any procedure to repadmin;
execute dbms_repcat_admin.grant_admin_any_repgroup('repadmin');
execute dbms_repcat_admin.grant_admin_any_schema(username => '"REPADMIN"');
grant comment any table to repadmin;
grant lock any table to repadmin;
grant select any dictionary to repadmin;
6。登录snap 数据库,重复上面的操作,创建public dblink 以及repadmin 用户
7。用repadmin 用户登录master,创建私有数据库连接
create database link "snap.com" connect to repadmin identified by repadmin;
如果第4 步省略了,没有创建公有数据库连接,则需要如下创建,在创建含有qualifier 的
多个数据库连接时也只能使用下面的方法:
create database link "snap.com@perday" connect to repadmin identified by repadmin
USING '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.3.100)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=snap)))';
create database link "snap.com@perhour" connect to repadmin identified by repadmin
USING '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.3.100)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=snap)))';
检查是否创建成功
SQL> select * from global_name@snap.com@perday;
GLOBAL_NAME
------------------------------------------------------------------------------
SNAP.COM
8。创建主体复制组,添加复制对象,操作的数据库将称为主体定义站点
创建每天复制一次的组
execute dbms_repcat.create_master_repgroup(gname => 'rep_gp_day',group_comment=> 'replcation perday',qualifier => '@PERDAY');
创建每小时复制一次的组
execute dbms_repcat.create_master_repgroup(gname => 'rep_gp_hour',group_comment=> 'replcation perhour',qualifier => '@PERHOUR');
备注:以下操作只以rep_gp_day 复制组为例,对于rep_gp_hour 复制组则应该作相应更改
再执行下面的操作。
检查执行结果
select * from dba_repsites;
--用spool 生成批量执行的SQL
set feedback off;
set pagesize 0;
set heading off;
set verify off;
set linesize 1000;
set trimspool on;
spool filename.sql;
select 'execute dbms_repcat.create_master_repobject(sname=>''test_user'',oname=>'''
|| table_name || ''',type=>''table'',use_existing_object=>true,gname=>''rep_gp_day'');'
CREATE_SQL from tabs;
select 'dbms_repcat.generate_replication_support(''test_user'',''' || table_name ||
''',''table'');' GEN_SQL from tabs;
spool off;
set feedback on;
set pagesize 9999;
set heading on;
set verify on;
根据不同的情况进行修改
检查复制组状态
select gname, master, status from dba_repgroup;
如果该复制组已经处于normal 状态,那么在添加复制对象之前必须先停顿复制组,既将同
步组的状态由正常(normal)改为停顿(quiesced )
execute dbms_repcat.suspend_master_activity (gname => 'rep_gp_day');
运行上面生成的spool 文件,批量执行创建复制对象和生成复制支持
如果是单独创建复制对象,则是手工执行下面的SQL
execute dbms_repcat.create_master_repobject(sname=>'test_user',oname=>'account',
type=>'table',use_existing_object=>true,gname=>'rep_gp_day',copy_rows => false);
execute dbms_repcat.generate_replication_support('test_user','account','table');
备注: 如果所有的主体站点都是在Oracle815 以上的版本, 那么设置
generate_replication_support 中的generate_80_compatible 参数为false,默认是true。
检查执行结果
select * from dba_repobject;
9。添加主体库,这一步操作必须要求dblink 工作正常
execute dbms_repcat.add_master_database(gname=>'rep_gp_day',master=>'snap.com@perday', use_existing_objects=>true, copy_rows=>false,propagation_mode => 'asynchronous');
select * from user_jobs;
execute dbms_repcat.resume_master_activity('rep_gp_day',false);
select gname, master, status from dba_repgroup;
如果上述的检查结果显示status 不是normal 的,那么运行:
execute dbms_repcat.resume_master_activity('rep_gp_day',true);
10。添加PUSH 的任务(执行间隔为1 天1 次),如果是一小时一次,则是1/24,如果是一
分钟一次则是1/1440
begin
dbms_defer_sys.schedule_push (
destination => 'snap.com@perday',
interval => 'sysdate + 1',
next_date => sysdate,
parallelism => 1,
delay_seconds => 50);
end;
/
添加PURGE 的任务(执行间隔为1 分钟1 次)
begin
dbms_defer_sys.schedule_purge (
next_date => sysdate,
interval => 'sysdate + 1/1440',
delay_seconds => 0,
rollback_segment => '');
end;
/
11。用repadmin 用户登录snap,创建私有数据库连接
create database link "master.com" connect to repadmin identified by repadmin;
create database link "master.com@perday" connect to repadmin identified by repadmin
USING '(DESCRIPTION = (ADDRESS_LIST = (ADDRESS= (PROTOCOL = TCP)(Host =
10.1.6.120)(Port = 1521)))(CONNECT_DATA = (SID = test1)(SERVER = DEDICATED)))';
create database link "master.com@perhour" connect to repadmin identified by repadmin
USING '(DESCRIPTION = (ADDRESS_LIST = (ADDRESS= (PROTOCOL = TCP)(Host =
10.1.6.120)(Port = 1521)))(CONNECT_DATA = (SID = test1)(SERVER = DEDICATED)))';
检查是否创建成功
SQL> select * from global_name@master.com@perday;
GLOBAL_NAME
--------------------------------------------------------------------------------
MASTER.COM
12。添加PUSH 和PURGE 的任务(执行间隔为1 天1 次),如果是一小时一次,则是1/24,
如果是一分钟一次则是1/1440
begin
dbms_defer_sys.schedule_push (
destination => 'master.com@perday',
interval => 'sysdate + 1',
next_date => sysdate,
parallelism => 1,
delay_seconds => 50);
end;
/
添加PURGE 的任务(执行间隔为1 分钟1 次)
begin
dbms_defer_sys.schedule_purge (
next_date => sysdate,
interval => 'sysdate + 1/1440',
delay_seconds => 0,
rollback_segment => '');
end;
/
至此,高级复制环境设置完毕。
物化视图复制站点的配置步骤
主站点:rep.yangtingkun
物化视图站点:yangtk.yangtingkun
主机名:yangtingkun
复制用户:yangtk
1. 检查初始化参数
复制对数据库的初始化参数限制不多,主要注意两点。
global_names 为TRUE 以及job_queue_process 大等0。
分别在主站点和物化视图站点执行下面两条sqlplus 命令,检查数据库初始化参数是否符合
要求。
show parameter global_names
show parameter job
如果初始化参数设置的不满足要求,可以通过下列语句动态修改。
alter system set global_names = true;
alter system set job_queue_processes = 20;
2. 检查全局数据库名称
两个数据库的db_domain 名称应该相同,只有db_name 不同。
通过下列语句检查主站点和物化视图站点的全局数据库名
select * from global_name;
如果全局数据库名设置不符合规范,可以通过如下语句动态修改。
alter database rename global_name to rep.yangtingkun;
alter database rename global_name to yangtk.yangtingkun;
3. 修改tnsnames.ora 文件,主站点和物化视图站点的参数文件中都添加下列内容
REP =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = yangtingkun)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = rep)
)
)
YANGTK =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = yangtingkun)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = yangtk)
)
)
4. 建立主体站点
--以system 用户连接到主站点
CONN system@rep
--建立复制管理用户repadmin 并授权
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 SELECT ANY DICTIONARY TO repadmin;
--注册传播用户并授权,这里使用了管理用户repadmin,也可以分别建立用户
BEGIN
DBMS_DEFER_SYS.REGISTER_PROPAGATOR (username => 'repadmin');
END;
/
--注册接收用户,这里使用了管理用户repadmin
BEGIN
DBMS_REPCAT_ADMIN.REGISTER_USER_REPGROUP (
username => 'repadmin',
privilege_type => 'receiver',
list_of_gnames => NULL);
END;
/
--建立物化视图站点复制管理员的代理用户,出于简单考虑,这里也使用repadmin 用户
BEGIN
DBMS_REPCAT_ADMIN.REGISTER_USER_REPGROUP (
username => 'repadmin',
privilege_type => 'proxy_snapadmin',
list_of_gnames => NULL);
END;
/
--设置代理刷新用户,并授权,这里仍然使用repadmin 用户
--对于repadmin 而言,不需要create session 权限
--但是这里如果新建用户的话,create session 权限则是必须的
GRANT CREATE SESSION TO repadmin;
GRANT SELECT ANY TABLE TO repadmin;
--设置清除延迟序列的job
--以复制管理员身份登陆到主站点
CONNECT repadmin/repadmin@rep
BEGIN
DBMS_DEFER_SYS.SCHEDULE_PURGE (
next_date => SYSDATE,
interval => 'SYSDATE + 1/24',
delay_seconds => 0);
END;
/
commit;
--多主站点的设置还需要多个站点间建立数据库链并建立调度机制
--但是对于物化视图复制的主体站点,则这些设置是不需要的
5. 设置物化视图站点
--以system 用户连接到物化视图站点
CONN system@yangtk
--建立物化视图管理员,并授权
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;
--建立传播者,并授权,这里使用mvadmin 用户,也可以建立单独的用户
BEGIN
DBMS_DEFER_SYS.REGISTER_PROPAGATOR (username => 'mvadmin');
END;
/
--建立刷新者,并授权,这里使用mvadmin 用户刷新物化视图
--对于mvadmin 而言,不需要create session 权限
--但是这里如果新建用户的话,create session 权限则是必须的
GRANT CREATE SESSION TO mvadmin;
GRANT ALTER ANY MATERIALIZED VIEW TO mvadmin;
--注册接受者
BEGIN
DBMS_REPCAT_ADMIN.REGISTER_USER_REPGROUP (
username => 'mvadmin',
privilege_type => 'receiver',
list_of_gnames => NULL);
END;
/
--建立PUBLIC 数据库链
CREATE PUBLIC DATABASE LINK rep.yangtingkun USING 'rep';
--建立到主站点上代理物化视图管理员的数据库链
--以物化视图管理员身份连接到物化视图站点
CONNECT mvadmin/mvadmin@yangtk
CREATE DATABASE LINK rep.yangtingkun CONNECT TO repadmin IDENTIFIED BY
repadmin;
--建立到主站点上复制管理员的数据库链
--以传播者身份登陆物化视图站点
--在本例中,这个数据库链与上面的数据库链相同,故省略。
--设置清除延迟序列的job
--如果物化视图站点只包括只读物化视图,这一步可以省略
BEGIN
DBMS_DEFER_SYS.SCHEDULE_PURGE (
next_date => SYSDATE,
interval => 'SYSDATE + 1/24',
delay_seconds => 0,
rollback_segment => '');
END;
/
--设置将修改推入到主站点的job
--如果物化视图站点只包括只读物化视图,这一步可以省略
BEGIN
DBMS_DEFER_SYS.SCHEDULE_PUSH (
destination => 'rep.yangtingkun',
interval => 'SYSDATE + 1/24',
next_date => SYSDATE,
stop_on_error => FALSE,
delay_seconds => 0,
parallelism => 0);
END;
/
--如果需要此物化视图站点作为主物化视图站点
--则还需要建立物化视图站点的代理物化视图管理用户以及代理刷新用户
--本例中从略
commit;
6. 建立主体组
--以复制管理员身份登陆复制站点
CONNECT repadmin/repadmin@rep
--建立名为rep_test 的复制组
BEGIN
DBMS_REPCAT.CREATE_MASTER_REPGROUP (
gname => 'rep_test');
END;
/
--将复制对象增加到复制组中
--主键所用的索引自动复制,其他索引需要明确添加到复制组中
BEGIN
DBMS_REPCAT.CREATE_MASTER_REPOBJECT (
gname => 'rep_test',
type => 'TABLE',
oname => 'test_rep',
sname => 'yangtk',
use_existing_object => TRUE,
copy_rows => FALSE);
END;
/
BEGIN
DBMS_REPCAT.CREATE_MASTER_REPOBJECT (
gname => 'rep_test',
type => 'INDEX',
oname => 'ind_test_rep_name',
sname => 'yangtk',
use_existing_object => TRUE,
copy_rows => FALSE);
END;
/
--生成复制支持
BEGIN
DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (
sname => 'yangtk',
oname => 'test_rep',
type => 'TABLE',
min_communication => TRUE);
END;
/
--开始复制
BEGIN
DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
gname => 'rep_test');
END;
/
commit;
7. 建立物化视图
--以复制用户连接到主站点
CONNECT yangtk@rep
--建立物化视图日志表,FAST 刷新方式必须要求建立物化视图日志,COMPLETE 则不需要
CREATE MATERIALIZED VIEW LOG ON yangtk.test_rep;
--如果被复制用户不存在则建立,并授予相应权限
--本例中,用户已存在,此步骤省略
/*
CONNECT system@yangtk
CREATE USER yangtk IDENTIFIED BY yangtk;
ALTER USER yangtk DEFAULT TABLESPACE users QUOTA UNLIMITED ON users;
ALTER USER yangtk TEMPORARY TABLESPACE temp;
GRANT
CREATE SESSION,
CREATE TABLE,
CREATE PROCEDURE,
CREATE SEQUENCE,
CREATE TRIGGER,
CREATE VIEW,
CREATE SYNONYM,
ALTER SESSION,
CREATE MATERIALIZED VIEW,
ALTER ANY MATERIALIZED VIEW,
CREATE DATABASE LINK
TO yangtk;
*/
--建立复制用户到主站点代理刷新者的数据库链
CONNECT yangtk@yangtk
CREATE DATABASE LINK rep.yangtingkun CONNECT TO repadmin IDENTIFIED BY
repadmin;
--建立物化视图组
--以物化视图管理员身份登陆物化视图站点
CONNECT mvadmin/mvadmin@yangtk
--物化视图组必须和复制站点上的复制组名称相同
BEGIN
DBMS_REPCAT.CREATE_MVIEW_REPGROUP (
gname => 'rep_test',
master => 'rep.yangtingkun',
propagation_mode => 'ASYNCHRONOUS');
END;
/
--创建刷新组
--对于只包含只读物化视图的站点,不需要此步骤
BEGIN
DBMS_REFRESH.MAKE (
name => 'mvadmin.rep_refresh',
list => '',
next_date => SYSDATE,
interval => 'SYSDATE + 1/24',
implicit_destroy => FALSE,
rollback_seg => '',
push_deferred_rpc => TRUE,
refresh_after_errors => FALSE);
END;
/
--创建物化视图
--对于只读物化视图,省略FOR UPDATE 语句
CREATE MATERIALIZED VIEW yangtk.test_rep
REFRESH FAST WITH PRIMARY KEY FOR UPDATE
AS SELECT * FROM yangtk.test_rep@rep.yangtingkun;
--将物化视图添加到物化视图组
--对于只读物化视图,此步骤可以省略
BEGIN
DBMS_REPCAT.CREATE_MVIEW_REPOBJECT (
gname => 'rep_test',
sname => 'yangtk',
oname => 'test_rep',
type => 'SNAPSHOT',
min_communication => TRUE);
END;
/
BEGIN
DBMS_REPCAT.CREATE_MVIEW_REPOBJECT (
gname => 'rep_test',
sname => 'yangtk',
oname => 'ind_test_rep_name',
type => 'INDEX',
min_communication => TRUE);
END;
/
--将物化视图添加到刷新组
BEGIN
DBMS_REFRESH.ADD (
name => 'mvadmin.rep_refresh',
list => 'yangtk.test_rep',
lax => TRUE);
END;
/
commit;
8. 主对象上建立测试对象脚本
create table test_rep (id number not null, name varchar2(100));
alter table test_rep add constraint pk_test_rep primary key (id);
create index ind_test_rep_name on test_rep (name);
insert into test_rep values (1, 'ytk');
insert into test_rep values (2, 'zhly');
commit;
阅读(2538) | 评论(0) | 转发(0) |