Advanced Replication同步复制实验(基于Trigger&基于Materialized View)
1. 高级复制和流复制介绍
1.1 高级复制(Advanced Replication)
高级复制也称为对称复制,分为多主体站点复制(Multiple Master Rplication)、物化视图站点复制(Materialized View Replication)和前两种的混合复制。高级复制主要是用在对称的、等同的数据库(仅限Oracle数据库之间)表之间的(单向或双向)的复制,以满足分布式应用的需求。多主体站点复制基于Oracle的触发器(Trigger)捕获DML和DDL操作,并将这些操作封装在Remote Procedure Calls(RPCs)里,并借助Deferred Transaction Queue来传递RPCs并在目标数据库利用Internal Trigger执行传递过来的RPCs从而实现了数据的同步,如果仅仅是高级复制环境中的只读物化视图环境,那么会直接利用解析物化视图日志的方式来实现数据的同步,而不用DTQ来传递RPCs,基于这一特点,高级复制对网络的稳定性和传输速度要求较高,配置也稍显麻烦。另外一点要特别注意,就是物化视图复制方式不支持DDL的变更同步。
1.2 流复制(Stream)
流复制是Oracle 10g新推出的同步技术,基于logminer(数据库必须运行在Archive Log模式),通过Oracle Advanced Queue来实现数据的同步复制,可以实现表,用户,数据库级别的同步,而高级复制支持的对象仅为表,索引,同义词,触发器,视图,过程,函数,程序包,程序包体等。Stream相对高级复制而言配置简单,通过oracle gateway还可用于异构平台和异构数据库的数据同步,这是高级复制做不到的。
2. 基于触发器的用户表复制
环境:11.2.0.3+oel 5.7
主体站:host:zlm 192.168.1.55 sid:zlm11g/global name:zlm11g/net service name:zlm11g
复制站:host:adrep 192.168.1.65 sid:strmtarget/global name:target/net service name:target
以下操作如不指定目标端,即表示在源端操作
2.1 建立高级复制管理用户表空间,用户,并赋予权限
--source
SQL> conn sys/oracle@zlm11g as sysdba
SQL> create tablespace reptbs datafile '/u01/app/oracle/oradata/zlm11g/rep_tbs.dbf' size 20m reuse autoextend on maxsize unlimited;
SQL> create user repadmin identified by oracle default tablespace reptbs temporary tablespace temp quota unlimited on reptbs;
SQL> exec dbms_repcat_admin.grant_admin_any_schema('repadmin');
SQL> exec dbms_defer_sys.register_propagator('repadmin')
--target
SQL> conn system/oracle@target
SQL> create tablespace reptbs datafile '/u01/app/oracle/oradata/strmtarget/rep_tbs.dbf' size 20m reuse autoextend on maxsize unlimited;
SQL> create user repadmin identified by oracle default tablespace reptbs temporary tablespace temp quota unlimited on reptbs;
SQL> exec dbms_repcat_admin.grant_admin_any_schema('repadmin');
SQL> exec dbms_defer_sys.register_propagator('repadmin')
2.2 创建复制SCHEMA及复制表
--source
SQL> conn system/oracle@zlm11g
SQL> create user repuser identified by repuser default tablespace reptbs temporary tablespace temp quota unlimited on reptbs;
SQL> grant resource,connect to repuser;
SQL> conn repuser/repuser@zlm11g;
SQL> create table rptest(id number primary key,name varchar2(20));
--target
SQL> conn system/oracle@target
SQL> create user repuser identified by repuser default tablespace reptbs temporary tablespace temp quota unlimited on reptbs;
SQL> grant resource,connect to repuser;
SQL> conn repuser/repuser@target
SQL> create table rptest(id number primary key,name varchar2(20));
2.3 创建dblink
--source
SQL> conn repadmin/oracle@zlm11g
SQL> alter system set job_queue_process=10 --11g默认是1000,也可以不用设置
SQL> alter system set global_names = true; --11g默认是false,需要设置
SQL> create database link target connect to repadmin identified by oracle using 'target';
SQL> col db_link for a15
SQL> select owner,db_link from dba_db_links;
OWNER DB_LINK
------------------------------ ---------------
STRMADMIN TARGET
REPADMIN TARGET
SQL> select name from v$database@target;
NAME
---------
STRMTARG --目标端的db_name
--target
SQL> conn repadmin/oracle@target
SQL> alter system set job_queue_process=10
SQL> alter system set global_names = true;
SQL> create database link zlm11g connect to repadmin identified by oracle using 'zlm11g';
SQL> col db_link for a15
SQL> select owner,db_link from dba_db_links;
OWNER DB_LINK
------------------------------ ---------------
STRMADMIN STRMTARGET
REPADMIN ZLM11G
2.4 创建复制组
SQL> conn repadmin/oracle@zlm11g
SQL> exec dbms_repcat.create_master_repgroup('rep_gp');
SQL> select gname,master,status from dba_repgroup where gname='REP_GP';
GNAME MASTER STATUS
--------------- --------------- ---------
REP_GP Y QUIESCED
2.5 添加复制对象(此处是表)
SQL> exec dbms_repcat.create_master_repobject(sname=>'repuser',oname=>'rptest',type=>'table',use_existing_object=>true,gname=>'rep_gp',copy_rows=>false);
SQL> select sname,oname,status,gname from dba_repobject where gname='REP_GP';
SNAME ONAME STATUS GNAME
------------------------------ ------------------------------ ---------- ------------------------------
REPUSER RPTEST VALID REP_GP
2.6 对复制对象启动复制支持
SQL> exec dbms_repcat.generate_replication_support('repuser','rptest','table');
SQL> select sname,oname,status,gname from dba_repobject where gname='REP_GP';
SNAME ONAME STATUS GNAME
------------------------------ ------------------------------ ---------- ------------------------------
REPUSER RPTEST VALID REP_GP
REPUSER RPTEST$RP VALID REP_GP
REPUSER RPTEST$RP VALID REP_GP
启用复制支持以后会多出ONAME=’%ONAME$RP’的两行内容,并且目标端也的dba_repobject也会生成相应内容,源端执行复制之前的内容是空的
2.7 添加复制主体节点
SQL> exec dbms_repcat.add_master_database(gname=>'rep_gp',master=>'target',
use_existing_objects=>true,copy_rows=>false,propagation_mode=>'synchronous');
SQL> col gname format a15
SQL> col dblink format a15
SQL> col masterdef for a15
SQL> col master format a15
SQL> select gname,dblink,masterdef,master from dba_repsites where gname='REP_GP';
GNAME DBLINK MASTERDEF MASTER
--------------- --------------- --------------- ---------------
REP_GP ZLM11G Y Y
REP_GP TARGET N Y
2.8 登录主体复制节点(目标端)查看复制站点信息和复制对象信息
SQL> conn repadmin/oracle@target
SQL> select gname,dblink,masterdef,master from dba_repsites where gname='REP_GP';
GNAME DBLINK MASTERDEF MASTER
--------------- --------------- --------------- ---------------
REP_GP TARGET N Y
REP_GP ZLM11G Y Y
SQL> select sname,oname,status,gname from dba_repobject where gname='REP_GP';
SNAME ONAME STATUS GNAME
------------------------------ ------------------------------ ---------- ---------------
REPUSER RPTEST VALID REP_GP
REPUSER RPTEST$RP VALID REP_GP
REPUSER RPTEST$RP VALID REP_GP
2.9 主体定义站启动复制
SQL> exec dbms_repcat.resume_master_activity('rep_gp');
2.10 测试复制同步(DML)
2.10.1 主体定义站测试用户修改测试表
SQL> conn repuser/repuser@zlm11g
Connected.
SQL> insert into rptest values(1,'aaron8219');
1 row created.
SQL> commit;
Commit complete.
2.10.2 主体站登录测试用户验证测试表同步
SQL> conn repuser/repuser@target
Connected.
SQL> select * from rptest;
ID NAME
---------- --------------------
1 aaron8219
可以看到,表数据可以已经同步
这里还碰到了一个小插曲,就是原先没有先在主体站(target端)先创建dblink,等创建完复制组,复制对象,启用复制支持,创建复制站后,发现不能同步,再去补创建dblink后,删除复制组,复制对象后依然不见效,复制定义主站对表进行操作时,皆会报如下错误:
SQL> insert into rptest values(3,'zhao');
insert into rptest values(3,'zhao')
*
ERROR at line 1:
ORA-24277: invalid database link "REPUSER"."RPTEST$RP"."REP_INSERT"
ORA-02063: preceding line from TARGET
SQL> delete from rptest;
delete from rptest
*
ERROR at line 1:
ORA-24277: invalid database link "REPUSER"."RPTEST$RP"."REP_DELETE"
ORA-02063: preceding line from TARGET
[oracle@zlm ~]$ oerr ora 24277
24277, 00000, "invalid database link %s "
// *Cause: The database link did not exist.
// *Action: Make sure the database link name is correct.
查看了一下,关于这个报错,是因为dblink名字不对,可能和之前没有立即在target端创建到主体定义站的dblink,之后才创建有关。删除dblink后重新再两端创建dblink,再把复制组,复制对象过程重新再走一遍,问题解决。
2.11 测试复制同步(DDL)
2.11.1 修改表结构
如果要做ddl同步,需要把复制组先挂起,做ddl后重新生成复制支持,然后把组resume
SQL> conn repadmin/oracle@zlm11g
SQL> exec dbms_repcat.suspend_master_activity('rep_gp');
SQL> exec dbms_repcat.alter_master_repobject(sname => 'repuser',oname => 'rptest',type => 'table',ddl_text =>'alter table repuser.rptest add(city varchar(10))');
SQL> exec dbms_repcat.generate_replication_support(sname => 'repuser',oname => 'rptest',type => 'table',min_communication => true,generate_80_compatible => false);
SQL> select gname,master,status from dba_repgroup where gname='REP_GP';
SQL> select sname,oname,status,gname from dba_repobject where gname='REP_GP';
2.11.2 验证结果
SQL> conn repuser/repuser@zlm11g
Connected.
SQL> set lin 30 pages 200
SQL> desc rptest
Name Null? Type
----------------- -------- ------------
ID NOT NULL NUMBER
NAME VARCHAR2(20)
CITY VARCHAR2(10)
SQL> conn repuser/repuser@target
Connected.
SQL> set lin 30 pages 200
SQL> desc rptest
Name Null? Type
----------------- -------- ------------
ID NOT NULL NUMBER
NAME VARCHAR2(20)
CITY VARCHAR2(10)
可以看到,修改表结构的DDL操作也已经同步过来了
SQL> show user
USER is "REPUSER"
SQL> insert into rptest values(2,'zlm','shanghai');
insert into rptest values(2,'zlm','shanghai')
*
ERROR at line 1:
ORA-23326: object group
"PUBLIC"."REP_GP" is quiesced
SQL> !
[oracle@zlm ~]$ oerr ora 23326
23326, 00000, "object group \"%s\".\"%s\" is quiesced"
// *Cause: Either suspend_master_activity has been called before the object
// group has resumed normal operation or a (deferred) rpc operation
// was attempted while the object group was quiesced.
// *Action: If suspend_master_activity has been called and a
// resume_master_activity request is pending, wait until it
// completes, and then reinvoke suspend_master_activity.
// Otherwise, resume database activity with the resume_master_activity
// call.
[oracle@zlm ~]$ exit
exit
SQL> conn repadmin/oracle@zlm11g
Connected.
SQL> exec dbms_repcat.resume_master_activity('rep_gp');
PL/SQL procedure successfully completed.
SQL> select gname,master,status from dba_repgroup where gname='REP_GP';
GNAME MASTER STATUS
--------------- --------------- ---------
REP_GP Y NORMAL
SQL> conn repuser/repuser@zlm11g
Connected.
SQL> insert into rptest values(2,'zlm','shanghai');
1 row created.
SQL> commit;
Commit complete.
SQL> conn repuser/repuser@target
SQL> set lin 120 pages 200
SQL> select * from rptest;
ID NAME CITY
---------- -------------------- ----------
2 zlm shanghai
1 aaron8219
2.12 清除操作
如果实验中遇到不能同步,可以删除以下对象后重新做一遍(通常只需删除复制组,对象会一并删除)
删除用户
SQL> drop user repadmin cascade;
SQL> drop user repuser cascade;
删除复制对象
SQL> exec dbms_repcat.drop_master_repobject(sname=>'repuser',oname =>'rptest',
type=>'table');
删除复制组
SQL> exec dbms_repcat.drop_master_repgroup(gname=>'rep_gp',all_sites=>true);
检查错误的管理请求
SQL> select * from dba_repcatlog where status ='ERROR';
3. 基于物化视图的复制
3.1 源端赋予复制用户权限
SQL> conn system/oracle@zlm11g
SQL> grant comment any table to repuser;
SQL> grant lock any table to repuser;
SQL> grant execute any procedure to repuser;
SQL> grant create any table to repuser;
SQL> grant create materialized view to repuser;
3.2 源端创建测试表
SQL> conn repuser/repuser@zlm11g
SQL> create table mvtest(id number(5) primary key);
SQL> begin
for i in 1..5 loop
insert into mvtest values(i);
end loop;
end;
/
3.3 源端创建物化视图日志
SQL> create materialized view log on mvtest with primary key including new values;
3.4 目标端赋予复制用户权限
SQL> conn system/oracle@target
SQL> grant create database link to repuser;
SQL> grant create materialized view to repuser;
SQL> grant execute any procedure to repuser;
3.5 目标端创建物化视图
3.5.1 创建DBlink
SQL> conn repuser/repuser@target
SQL> alter system set global_names = true;
SQL> create database link zlm11g connect to repuser identified by repuser using 'zlm11g';
SQL> select db_link,owner from all_db_links;
DB_LINK OWNER
--------------- ------------------------------
ZLM11G REPUSER
3.5.2 创建测试表
SQL> create table mvtest as select * from repuser.mvtest@zlm11g where 1=2;
SQL> desc mvtest;
Name Null? Type
----------------------- -------- ----------------
ID NOT NULL NUMBER(5)
SQL> select * from mvtest;
no rows selected
3.5.3 创建物化视图
SQL> create materialized view mvtest
on prebuilt table
refresh force with primary key
on demand
as select * from repuser.mvtest@zlm11g;
3.6 全量刷新
SQL> exec dbms_mview.refresh('mvtest','complete');
3.7 验证目标端数据
SQL> conn repuser/repuser@target
SQL> select * from mvtest;
ID
----------
1
2
3
4
5
SQL> conn repuser/repuser@zlm11g
SQL> insert into mvtest values(6);
1 row created.
SQL> commit;
Commit complete.
SQL> conn repuser/repuser@target
SQL> select * from mvtest;
ID
----------
1
2
3
4
5
源端新插入的一条记录并没有同步过来,目标端再执行一次全量刷新
SQL> conn repuser/repuser@target
SQL> exec dbms_mview.refresh('mvtest','complete');
SQL> select * from mvtest;
ID
----------
1
2
3
4
5
6
又一次同步了mvtest表的数据,以上是最简单的基于手动的刷新物化视图,另外还可以配置job,让物化视图定期刷新。注意,物化视图复制并不支持DDL的复制
查看源端复制用户基表中的物化视图日志
SQL> select * from repuser.mlog$_mvtest;
查看目标物化视图的刷新情况
SQL> select mview_name,owner from user_mviews;
SQL> select * from user_jobs;
SQL> select * from dba_jobs_running;
查看物化视图所在的基表最后被成功刷新的时间
SQL> select master,log_table,current_snapshots from dba_snapshot_logs;
4 总结
高级复制(Advanced Replication)可以说是Oracle最早的HA技术了,最早出现于Oracle 7e,之后的8i,9i继续沿用,一直到10g,出现了流技术(Stream),高级复制技术才逐渐开始被取代,虽然一直到11g,还是可以使用AR技术,但其弊端是显而易见的,由于它的复制机制是基于Oracle的内部对象触发器(Trigger),他会严格控制事务的一致性,对于开发人员而言,也许是不错的特性,但是对于DBA来说,可谓是麻烦重重,一旦事务之间互相请求的资源被别的事务所占用,往往会造成等待,更严重的就是产生死锁,造成数据库hang住。虽然如此,高级复制技术的物化视图,还是有一定的利用价值的,因为它并不通过内部触发器来控制对象的复制,这样就可以把容易消耗资源的查询分散到物化视图上,通过查询实时更新的物化视图来获取需要的报表数据,这对于提高数据库性能是由一定积极作用的。
-------------------------------------------------------------------------------------------------------
By aaron8219 Chinaunix Blog:http://blog.chinaunix.net/uid/24612962.html
原创内容,转载请注明链接,谢谢!
Advanced Replication同步复制实验(基于Trigger&基于Materialized View)的更多相关文章
- 烂泥:mysql5.5主从同步复制配置
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 在上篇文章<烂泥:学习mysql数据库主从同步复制原理>中,我们介绍了有关mysql主从复制的基本原理.在这篇文章中,我们来实际测试下mys ...
- mysql5.5主从同步复制配置
在上篇文章<烂泥:学习mysql数据库主从同步复制原理>中,我们介绍了有关mysql主从复制的基本原理.在这篇文章中,我们来实际测试下mysql5.5的主从同步复制功能. 注意mysql5 ...
- Centos7.5部署MySQL5.7基于GTID主从复制+并行复制+半同步复制+读写分离(ProxySQL) 环境- 运维笔记 (完整版)
之前已经详细介绍了Mysql基于GTID主从复制的概念,原理和配置,下面整体记录下MySQL5.7基于GTID主从复制+并行复制+增强半同步复制+读写分离环境的实现过程,以便加深对mysql新特性GT ...
- 实现mysql的读写分离(mysql-proxy)____1(mysql的主从复制,基于gtid的主从复制,半同步复制,组复制)
主从复制原理: 从库生成两个线程,一个I/O线程,一个SQL线程: i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中:主库会生成一个 log ...
- MySQL全同步复制基于GR集群架构实现(Centos7)
目录 一. 理论概述 概述 二. 部署 向组加入新节点 测试 三.总结 一. 理论概述 概述 本案例操作的是针对于MySQL的复制类型中的全同步复制,对几种复制类型简单总结下: 异步复制:MySQL默 ...
- MySQL 5.7 基于GTID主从复制+并行复制+半同步复制
环境准备 IP HOSTNAME SERVICE SYSTEM 192.168.131.129 mysql-master1 mysql CentOS7.6 192.168.131.130 mysql- ...
- InnoSQL HA Suite的实现原理与配置说明 InnoSQL的VSR功能Virtual Sync Replication MySQL 5.5版本引入了半同步复制(semi-sync replicaiton)的功能 MySQL 5.6支持了crash safe功能
InnoSQL HA Suite的实现原理与配置说明 InnoSQL的VSR功能Virtual Sync Replication MySQL 5.5版本引入了半同步复制(semi-sync repl ...
- PostgreSQL Replication之第五章 设置同步复制(1)
到目前为止,我们已经处理了基于文件的复制(或日志传送)和简单的基于流复制的设置.在两种情况中,在master上事务被提交之后,数据被提交,由slave接收.在master提交和slave实际上完全地接 ...
- 【3.1】【mysql基本实验】mysql复制(主从复制/异步复制/半同步复制,一主一从)
关键词:mysql复制(异步复制),mysql异步复制 核心原理: mysql 复制流程原理 一个事务在 mysql异步复制中的流程与生命周期 一个事务,在传统半同步的复制流程 #mysql主从基本实 ...
随机推荐
- 浅谈C中的指针和数组(二)
原文转载地址:http://see.xidian.edu.cn/cpp/html/475.html 在原文的基础上增加自己的想法作为修改 很多初学者弄不清指针和数组到底有什么样的关系.我现在就告诉你: ...
- 【phpcms-v9】如何实现在含有子栏目的栏目下添加内容?
对于题目的解释: 假设现在有一个一级栏目 为:栏目1 其下有二级栏目 :栏目1=>栏目11,栏目1=>栏目12,栏目1=>栏目13 同时栏目1下有文章列表 : 栏目1-----文章 ...
- Linux网络管理——子网掩码
1. 网络基础 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB",&q ...
- 随意记的一点 js 笔记
1. 给未经声明的变量赋值在严格模式下会导致抛出 ReferenceError 错误(意思是,所有变量都必须用 var 去定义,不能在函数内部定义全局变量): 2. 在严格模式下,不能定义名为 eva ...
- this的用法this.name=name 这个什么意思
public Employee(string name, string alias){ // Use this to qualify the fields, name and alias: this. ...
- WEB开发之如何改善PHP开发方式
改善PHP开发方式一般可以分为以下几种实现方式: 1.组织和样式 找出一种适合你的组织方法和编码样式,并且一直坚持下去,这样的话,你的代码的组织和布局会变得十分有条理.我们不应该轻视代码的组织 ...
- php部分学习笔记
[web 开发分为]1. 静态web 开发(html 页面) 如果我们的一个页面,始终是一成不变的,则就是属于静态web 开发,一般讲用html 技术就ok2. 动态web 开发 比如: 我们需要发帖 ...
- XML实例入门2
工具:notepad++.VS2008(MSXML6.0) 来自msdn的例子(经过修改,因为升级到MSXML6.0,有些关键字不太一样了), 需要文件books.xml,books.vsd(博客只支 ...
- MYSQL 关闭服务的过程
服务器关闭进程可以概括为: 1. 启动关闭进程 2. 服务器根据需要创建关闭线程 3. 服务器停止接收新连接 4. 服务器终止当前的活动 5. 存储引擎被停掉或关闭 6. ...
- 查看linux版本的三种常用方法
1) 登录到服务器执行 lsb_release -a ,即可列出所有版本信息,例如: [root@3.5.5Biz-46 ~]# lsb_release -a LSB Version: 1.3 Dis ...