zoukankan      html  css  js  c++  java
  • Advanced Replication同步复制实验(基于Trigger&基于Materialized View)

    1. 高级复制和流复制介绍

    1.1 高级复制(Advanced Replication)

    高级复制也称为对称复制,分为多主体站点复制(Multiple Master Rplication)、物化视图站点复制(Materialized View Replication)和前两种的混合复制。高级复制主要是用在对称的、等同的数据库(仅限Oracle数据库之间)表之间的(单向或双向)的复制,以满足分布式应用的需求。多主体站点复制基于Oracle的触发器(Trigger)捕获DMLDDL操作,并将这些操作封装在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;

    总结

        

        高级复制(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

    原创内容,转载请注明链接,谢谢!

    http://blog.csdn.net/aaron8219/article/details/11707137

  • 相关阅读:
    MySQL存储过程中的3种循环【转载】
    单元样选择按钮
    JavaScript(jQuery)实现打印英文格式日期
    哈希算法
    Hello,Expression Blend 4 (含Demo教程和源码)
    Cocos2Dx for XNA类解析(2): CCDirector(上)
    github for Windows使用介绍
    Hello,Behavior
    Vue component+vuedraggable拖拽动态表单
    Vue Component
  • 原文地址:https://www.cnblogs.com/james1207/p/3322949.html
Copyright © 2011-2022 走看看