Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1063411
  • 博文数量: 284
  • 博客积分: 8223
  • 博客等级: 中将
  • 技术积分: 3188
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-01 13:26
文章分类

全部博文(284)

文章存档

2012年(18)

2011年(33)

2010年(83)

2009年(147)

2008年(3)

分类: Oracle

2009-05-14 22:42:09

前言:

   本周二完成了高级复制的配置,剩下的几天,把高级复制的性能测试了下,遇到不少问题,总结下来。

一.测试

   复制硬件环境:ultra45两台;

   复制软件环境:solaris10,oracle9.2版本

   库环境:在数据库中各建立一张列数为1000的表(huge5),其中各列均为number类型,第一列名为deptno为primary key,其他各列名为smpxx(xx代表数字),配置多主复制(详见前日的)

   项目:

1. 双机在线, 单机插入65535条数据,对侧能够同步;

2. 双机在线, 同时插入不冲突的1000条数据,对侧能够同步;

3. 双机不在线,单机插入65535条数据,恢复网络后,对侧能够同步;

4. 双机不在线,各插入不冲突的1000 条数据,恢复网络后,对侧能够同步;

5. 双机不在线,各插入不冲突的10000条数据,全部重启后,恢复网络后,对侧能够同步;

6. 双机不在线,各插入主键相同的一条数据,(存在主键冲突),网络恢复后,复制挂起;

7. 双机不在线,一个机删除全部数据,另一台机删除部分数据,网络恢复后,复制挂起;

   完毕,发现oracle对于冲突的处理需要人为干预,一旦复制挂起,需要人工的使用命令进行清除:

1. 检查复制是否启动:

    在复制用户下: Select gname,status from sys.dba_repcat ;

    启动的事务应当显示N,表示工作正常。

    如发现当前复制组不正常,应使用下面命令启动复制组:

    begin dbms_repcat.resume_master_activity(gname=>’”SCOTT”’); End; 2. 检查复制是否挂起:

    如果两机上复制组均启动,仍不能启动复制,请检查复制是否挂起;

    复制用户下: Select job,failures,broken from dba_jobs;

    正常的事务其broken部分应为N,一旦复制挂起就会在broken部分显示Y。 处理复制挂起的步骤:

    在复制用户下,首先检查复制错误原因:

Select deferred_tran_id,error_msg from deferror;

    其次,删除错误信息:

Begin dbms_defer_sys.delete_error(deferred_tran_id=>’xxx’,destination=>NULL);end;

其中deferred_tran_id 为刚在查找错误原因中找到的deferred id;

    最后,重新推入事务:

    在复制用户下,执行 Exec dbms_job.run(xx); 其中xx表示在select job,failures,broken from dba_jobs步骤中发现的broken为Y的事务的job ID。 执行完毕后,请再次用select job,failures,broken from dba_jobs确认事务没有挂起。

二. 复制冲突机解决机制

    复制存在三种冲突,update、delete、唯一性冲突,oracle提供相应函数可重载这些处理,如果没有重载,在默认情况下,oracle9i的测试结果是复制会自动挂起,并在deferred队列中写入log。具体解决方案参考下面的文字;

三. 修改高级复制的配置过程,增加复制冲突解决机制的配置

要求:     global_names: TRUE

               Open_links:最小数5

修改命令:alter system set global_names=true;

查看参数:show parameter global_names;

2.       修改tnsnames.ora

使双机能够互相使用@访问:

如这里,测试双机环境如下,

主机1 test 域名 orcl  IP:10.144.15.200  

Oracle System用户密码:root

主机2 sun10  域名:sysdb  IP:10.144.15.237

Oracle System 用户密码为:nari

该文件位于$ORACLE_HOME/product/9.2.0/network/admin/,最终tnsnames.ora为:(其中,红色部分为修改部分)

/////////////////////////////////////////////////主机1test///////////////////////////////////////////////////////

ORCL =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = test)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = orcl)

    )

  )

 

INST1_HTTP =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = test)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVER = SHARED)

      (SERVICE_NAME = MODOSE)

      (PRESENTATION = )

    )

  )

 

EXTPROC_CONNECTION_DATA =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))

    )

    (CONNECT_DATA =

      (SID = PLSExtProc)

      (PRESENTATION = RO)

    )

  )

 

SYSDB =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.144.15.237)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = sysdb)

    )

  )

/////////////////////////////////////////////////主机2sun10///////////////////////////////////////////////////////

SYSDB =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = sun10)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = sysdb)

    )

  )

 

INST1_HTTP =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = sun10)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVER = SHARED)

      (SERVICE_NAME = MODOSE)

      (PRESENTATION = )

    )

  )

 

EXTPROC_CONNECTION_DATA =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))

    )

    (CONNECT_DATA =

      (SID = PLSExtProc)

      (PRESENTATION = RO)

    )

  )

 

ORCL =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.144.15.200)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = orcl)

    )

  )

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

使得test主机可以在sqlplus中通过

conn system/root@orcl访问自己,

conn system/nari@sysdb访问对侧。

使得

 

3.       在主机test上执行下面脚本:

a)         system用户登录并建立复制管理员rep

connect system/root@orcl;

create user rep identified by rep

default tablespace users

temporary tablespace temp;

b)        对复制管理员用户rep授予管理员权限;

Begin

dbms_repcat_admin.grant_admin_any_schema(username=>’rep’);

end;

/

grant comment any table to rep;

grant lock any table to rep;

//注册传播函数;

begin

dbms_defer_sys.register_propagator(username=>’rep’);

end;

/

Grant execute any procedure to rep;

c)        增加到sun10节点的公共链路;

Create public database link SYSDB using ‘SYSDB;

d)        登录复制管理员用户,建立私有链路;

connect rep/rep@ORCL

create database link SYSDB connect to rep identified by rep;

e)         每隔1分钟push一次任务将test节点上的事务推到sun10节点上去执行

Begin

dbms_defer_sys.schedule_push(

destination=>’SYSDB’,

       interval=>’sysdate+1/(60*24)’,

       next_date=>sysdate,

       stop_on_error=>FALSE,

       delay_seconds=>0,

       parallelism=>2);

END;

/

f)         注册接收者

Begin dbms_repcat_admin.register_user_repgroup(

Username=>’rep’,

Privilege_type=>’receiver’,

List_of_gnames=>NULL

);

end;

/

 

 

g)        每隔5分钟PURGE一次任务将本节点上已完成的事务退出队列

Begin dbms_defer_sys.schedule_purge(

next_date=>sysdate,

       interval=>’sysdate+5/(60*24)’,

       delay_seconds=>0,

       rollback_segment=>’’);

end;

/

h)        test主机上建立ktest用户

connect system/root@ORCL;

create user ktest identified by ktest default tablespace users temporary tablespace temp;

grant alter session to ktest;

grant create cluster to ktest;

grant create database link to ktest;

grant create sequence to ktest;

grant create session to ktest;

grant create synonym to ktest;

grant create table to ktest;

grant create view to ktest;

grant create procedure to ktest;

grant create trigger to ktest;

grant unlimited tablespace to ktest;

grant create type to ktest;

grant create any snapshot to ktest;

grant alter any snapshot to ktest;

i)          test主机上建立ktest下的dept表;

connect ktest/ktest@ORCL;

create table dept(

  deptno number primary key

);

commit;

 

4.       在主机sun10上执行下面脚本:

a)         system用户登录并建立复制管理员rep

connect system/root@SYSDB;

create user rep identified by rep

default tablespace users

temporary tablespace temp;

b)        对复制管理员用户rep授予管理员权限;

Begin

dbms_repcat_admin.grant_admin_any_schema(username=>’rep’);

end;

/

grant comment any table to rep;

grant lock any table to rep;

begin dbms_defer_sys.register_propagator(username=>’rep’);

end;

/

grant execute any procedure to rep;

c)        TEST节点建立公共链路;

Create public database link ORCL using ‘ORCL;

d)        以复制用户对ORCL节点建立私有链路;

conn rep/rep@SYSDB

create database link ORCL connect to rep identified by rep;

 

e)         每隔1分钟push一次任务将sun10节点上的事务推到test节点上去执行

Begin

dbms_defer_sys.schedule_push(

destination=>’orcl’,

       interval=>’sysdate+1/(60*24)’,

       next_date=>sysdate,

       stop_on_error=>FALSE,

       delay_seconds=>0,

       parallelism=>2);

END;

/

f)         每隔5分钟PURGE一次任务将本节点上已完成的事务退出队列

Begin dbms_defer_sys.schedule_purge(

next_date=>sysdate,

       interval=>’sysdate+5/(60*24)’,

       delay_seconds=>0,

       rollback_segment=>’’);

end;

/

g)        注册接收者

Begin dbms_repcat_admin.register_user_repgroup(

Username=>’rep’,

Privilege_type=>’receiver’,

List_of_gnames=>NULL

);

end;

/

 

h)        sun10主机上建立ktest用户

connect system/nari@SYSDB;

create user ktest identified by ktest default tablespace users temporary tablespace temp;

grant alter session to ktest;

grant create cluster to ktest;

grant create database link to ktest;

grant create sequence to ktest;

grant create session to ktest;

grant create synonym to ktest;

grant create table to ktest;

grant create view to ktest;

grant create procedure to ktest;

grant create trigger to ktest;

grant unlimited tablespace to ktest;

grant create type to ktest;

grant create any snapshot to ktest;

grant alter any snapshot to ktest;

i)          sun10主机上建立ktest下的dept表;

connect ktest/ktest@sysdb;

create table dept(

  deptno number primary key

);

commit;

 

 

5.       在主机test上执行下面脚本:

a)         rep用户登录;

conn rep/rep@ORCL;

b)        建立对称复制组“SCOTT

Begin dbms_repcat.create_master_repgroup(gname=>’SCOTT’,qualifier=>’’,group_comment=>’’);

End;

/

c)        DEPT表加入到对称复制组“SCOTT”中

Begin

dbms_repcat.create_master_repobject(gname=>’”SCOTT”’, type=>’TABLE’,

oname=>’DEPT’,sname=>’nari’,use_existing_object=>TRUE,

copy_rows=>TRUE);

End;

/

 

d)        把主数据库“SYSDB”加入到对称复制组“SCOTT”中

Begin

Dbms_repcat.add_master_database(gname=>’”SCOTT”’,master=>’sysdb’,use_existing_objects=>TRUE, copy_rows=>TRUE, propagation_mode=>’ASYNCHRONOUS’);

End;

/

(ORA-4052 查找远程对象SYS.SYS.SYSDB出错)

(ORA-23308:对象nari.DEPT不存在或无效 ORA-02055:分布式更新操作失效,要求回退:

遇到该问题后,新建表CC,新建复制组T,所有问题解决;原因在于建表过程,建表时,应使用目前说明的语句,不要使用alter 。。。modify语句,不能有NUMBER(2)这样的描述,先不要insert 数据进入)

e)         生成复制支持表DEPT

Begin dbms_repcat.generate_replication_support(sname=>’ktest’,

Oname=>’DEPT’,type=>’TABLE’,min_communication=>TRUE);

End;

/

f)         启动对称复制组SCOTT

Begin dbms_repcat.resume_master_activity(gname=>’”SCOTT”’);

End;

/

Commit;

执行完后,使用system用户登录系统并查询状态;

Conn system/root@orcl

Select gname,status from sys.dba_repcat ;

如果看到当前复制组的状态为NORMAL表明可以进行DML操作;

同时,如果工作正常的话,应该使用如下命令,看不到log

Select count(*) from sys.dba_repcatlog;

(如果为quiesced

execute dbms_repcat.resume_master_activity(’”SCOTT”’,true);

 

)

 

 

6.       执行下面脚本的主要目的是为了重载高级复制冲突解决机制:

a)         rep用户登录;

conn rep/rep@ORCL;

b)        停止复制组

begin

dbms_repcat.suspend_master_activity(gname=>'SCOTT');end;

/

 

c)        创建列组

begin

dbms_repcat.make_column_group(sname =>'ktest',oname=>'DEPT',column_group=>'cc',list_of_column_names=>'deptno');end;

/

 

d)        增加update冲突机制:DIScard

begin      

dbms_repcat.add_UPDATE_RESOLUTION(sname=>'ktest',oname=>'DEPT', column_group       =>'cc',sequence_no=>1,method=>'DISCARD', parameter_column_name=>'deptno');end;

/

e)         增加unique冲突机制:DIScard

新开终端在ktest用户下使用

Select constrain_name,table_name from user_constraints;

找到相应的constraint_name

再回到刚才的窗口继续输入

begin

dbms_repcat.add_unique_RESOLUTION(sname=>'ktest',oname=>'DEPT',constraint_name=>'SYS_C002663',sequence_no=>1,method=>'DISCARD',parameter_column_name=>'deptno');end;

/

(注意constraint_name使用刚查到的标识)

 

f)         增加delete冲突机制:DIScard

       先增加一个空函数rank

create or replace function rank(s float)

return number is

i number(10);

begin

i:=0;

return i;

end rank;

/

修改delete冲突机制:

begin

dbms_repcat.add_delete_RESOLUTION(sname=>'ktest',oname=>'DEPT',sequence_no=>1,parameter_column_name=>'deptno',function_name=>'rep.rank');end;

/

g)        重新生成复制支持表DEPT

Begin dbms_repcat.generate_replication_support(sname=>’ktest’,

Oname=>’DEPT’,type=>’TABLE’,min_communication=>TRUE);

End;

/

h)        启动对称复制组SCOTT

Begin dbms_repcat.resume_master_activity(gname=>’”SCOTT”’);

End;

/

Commit;

 

 

特别:

1)      如果想停止复制对称组运行:

execute  dbms_repcat.suspend_master_activity(gname=>’SCOTT’);注意,需要rep用户;

在执行复制使用,

Begin dbms_repcat.resume_master_activity(gname=>’”SCOTT”’);

End;

 

2)      如果想删除复制组:

execute  dbms_repcat.drop_master_repgroup(gname => 'SCOTT', drop_contents => false, all_sites => false);

 

3)  在复制组scott_mg里删除数据库对象。
execute dbms_repcat.drop_master_repobject ('testuser','dept','table');

 

4)   重新使同步组的状态由停顿(quiesced )改为正常(normal)
execute dbms_repcat.resume_master_activity('scott_mg',false);

 

5)      如果发现主机复制功能不正常应采取如下措施进行排查:

A. 检查复制是否启动:

 复制用户下:

 Select gname,status from sys.dba_repcat ;

正常启动的事务应当显示N,表示工作正常。

如发现当前复制组不正常,应使用下面命令启动复制组:

Begin dbms_repcat.resume_master_activity(gname=>’”SCOTT”’);

End;

 

B. 检查复制是否挂起:

如果两机上复制组均启动,仍不能启动复制,请检查复制是否挂起;

复制用户下:

Select job,failures,broken from dba_jobs;

正常的事务其broken部分应为N,一旦复制挂起就会在broken部分显示Y

处理复制挂起的步骤:

在复制用户下,首先检查复制错误原因:

Select deferred_tran_id,error_msg from deferror;

其次,删除错误信息:

Begin dbms_defer_sys.delete_error(deferred_tran_id=>’xxx’,destination=>NULL);end;

其中deferred_tran_id 为刚在查找错误原因中找到的deferred id

最后,重新推入事务:

在复制用户下,执行

Exec dbms_job.run(xx);

其中xx表示在select job,failures,broken from dba_jobs步骤中发现的brokenY的事务的job ID

执行完毕后,请再次用select job,failures,broken from dba_jobs确认事务没有挂起。

 

 

阅读(1324) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~