分类: 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/
/////////////////////////////////////////////////主机1:test///////////////////////////////////////////////////////
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)
)
)
/////////////////////////////////////////////////主机2:sun10///////////////////////////////////////////////////////
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用户登录系统并查询状态;
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步骤中发现的broken为Y的事务的job ID。
执行完毕后,请再次用select job,failures,broken from dba_jobs确认事务没有挂起。