关于dbms_rectifier_diff包的基本用法参考:
http://www.eygle.com/archives/2005/01/eoadbms_rectifi.html
本文链接:
http://www.eygle.com/archives/2005/01/oeouoracleaeiao.html
实际上Oracle的dbms_rectifier_diff.DIFFERENCES过程,内部操作就是执行连个minus操作
把两边的差异记录下来,作为冲突解决的数据。
可是注意,如果在解决这个问题时你没有挂起复制,Oracle得到的数据可能是存在问题的。
而且,如果你不指定column list,那么两边的数据可能会因为某些特殊字段(如时间字段)的特殊处理而存在差异。
那么这时候手工介入不可避免。
我们首先先把两个重要参数的用法说明一下。
一个是WHERE_CLAUSE,另外一个是COLUMN_LIST。
WHERE_CLAUSE用于限定进行差异比较的范围,这可以极大的缩减结果集的数量,使用索引加快访问速度等。
比如我这里使用NUMGENDER=1,只比较性别为"女"这一部分用户数据。
COLUMN_LIST用于限定比较字段,如果你能通过某个字段,如主键等确定数据差异,那么你完全可以只比较单个字段。
而且显然可以轻易通过全索引扫描来完成比较,加快比较速度。
我这里使用NUMUSERID,用户ID来比较。
但是注意,这样的比较结果中将只包含NUMUSERID信息,当然我们可以轻易通过NUMUSERID和原表的比较补全MISSING_ROWS_TEST表的信息。
PHP code:
begin dbms_rectifier_diff.DIFFERENCES(
SNAME1 =>'HAWA',
ONAME1 =>'TEST',
REFERENCE_SITE =>'AVATAR.COOLYOUNG.COM.CN',
SNAME2 =>'HAWA',
ONAME2 =>'TEST',
COMPARISON_SITE =>'AUTHAA.COOLYOUNG.COM.CN',
WHERE_CLAUSE =>'NUMGENDER=1',
COLUMN_LIST =>'NUMUSERID',
MISSING_ROWS_SNAME =>'HAWA',
MISSING_ROWS_ONAME1 =>'MISSING_ROWS_TEST',
MISSING_ROWS_ONAME2 =>'MISSING_LOCATION_TEST',
MISSING_ROWS_SITE =>'AVATAR.COOLYOUNG.COM.CN',
MAX_MISSING =>500,
COMMIT_ROWS =>100
);
end;
/
这段代码供参考。
Ok,我们继续前面的讨论。
我们提到,如果存在差异,通常需要手工介入。
清楚了DIFFERENCES的原理,实际上我们完全可以手工来完成这个过程。
以下是我的手工操作步骤,目的是为了准确性及减轻数据库压力:
1.首先创建一个ID差异表
这个表不是必须的,这里是为了清晰PHP code:
SQL> create table hawa.prof as select NUMUSERID from hawa.hw_user where 1=0;
Table created.
Elapsed: 00:00:00.16
.
2.根据主键找到差异记录
注意这里取决于你的数据库产生差异的原因,我的差异由于初始数据不同步,即A全包含B并且,A>B。PHP code:
SQL> insert into hawa.prof
2 select * from
3 (
4 select NUMUSERID from hawa.HW_USERPROFILE
5 minus
6 select NUMUSERID from hawa.HW_USERPROFILE@authaa)
7 /
263 rows created.
Elapsed: 00:00:32.49
.
3.创建记录表PHP code:
SQL> create table hawa.missing_rows_hw_userprofile
2 as
3 select * from hawa.hw_userprofile where 1=0;
Table created.
Elapsed: 00:00:
SQL> create table hawa.MISSING_LOC_hw_userprofile (
2 present VARCHAR2(128),
3 absent VARCHAR2(128),
4 r_id ROWID);
Table created.
Elapsed: 00:00:00.04
.
4.根据差异信息查询到完整信息PHP code:
SQL> insert into hawa.missing_rows_hw_userprofile
2 select * from hawa.hw_userprofile where NUMUSERID in
3 (select * from hawa.prof);
263 rows created.
Elapsed: 00:00:00.06
SQL> commit;
Commit complete.
Elapsed: 00:00:00.02
.
5.构造位置信息
注意这里的方向信息及ROWID信息。PHP code:
SQL> insert into hawa.MISSING_LOC_hw_userprofile
2 select 'AVATAR.COOLYOUNG.COM.CN','AUTHAA.COOLYOUNG.COM.CN',rowid from hawa.missing_rows_hw_userprofile;
263 rows created.
Elapsed: 00:00:00.00
SQL> commit;
Commit complete.
Elapsed: 00:00:00.06
.
6.纠正数据冲突PHP code:
SQL> BEGIN DBMS_RECTIFIER_DIFF.RECTIFY(
2 SNAME1 =>'HAWA',
3 ONAME1 =>'HW_USERPROFILE',
4 REFERENCE_SITE =>'AVATAR.COOLYOUNG.COM.CN',
5 SNAME2 =>'HAWA',
6 ONAME2 =>'HW_USERPROFILE',
7 COMPARISON_SITE =>'AUTHAA.COOLYOUNG.COM.CN',
8 COLUMN_LIST =>NULL,
9 MISSING_ROWS_SNAME =>'HAWA',
10 MISSING_ROWS_ONAME1 =>'MISSING_ROWS_HW_USERPROFILE',
11 MISSING_ROWS_ONAME2 =>'MISSING_LOC_HW_USERPROFILE',
12 MISSING_ROWS_SITE =>'AVATAR.COOLYOUNG.COM.CN',
13 COMMIT_ROWS =>100
14 );
15 END;
16 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.53
.
7.验证结果PHP code:
SQL> select count(*) from hawa.HW_USERPROFILE;
COUNT(*)
----------
1746300
Elapsed: 00:00:02.22
SQL> select count(*) from hawa.HW_USERPROFILE@authaa;
COUNT(*)
----------
1746300
Elapsed: 00:00:00.21
SQL> select count(*) from hawa.HW_USERPROFILE;
COUNT(*)
----------
1746300
Elapsed: 00:00:00.59
SQL>select count(*) from hawa.HW_USERPROFILE@authaa;
COUNT(*)
----------
1746300
Elapsed: 00:00:00.20
SQL> select NUMUSERID from hawa.HW_USERPROFILE
2 minus
3 select NUMUSERID from hawa.HW_USERPROFILE@authaa ;
no rows selected
Elapsed: 00:00:23.51
SQL>
That's all.