1、前言
当我们使用OGG软件进行Oracle数据同步的时候,常常遇到因为数据冲突导致目标端复制进程abended的情况,不知道如何修复。下面我就对update,insert,delete操作造成数据冲突的情况进行复现和修复。
2、环境准备
Source端:linux 2.6.32-431 Oracle11.2.0.4.0 OGG19.1.0.0.4 OGG经典模式
用户:test
Target端:linux 4.1.12-112 Oracle19.3.0.0.0 OGG19.1.0.0.4 OGG集成模式
用户:test@pdb
如下测试均使用2个表,表数据从dba_objects进行复制, a表有主键列object_id, b表有object_id索引,但是object_id 没有非空约束,没有主键唯一约束
主键表a:alter table a add constraint dzl primary key (object_id);
非主键表b:create index yz on b(object_id);
3、表级最小补充日志测试
在使用ogg进行数据同步操作时,一定要记住要打开源端表级最小补充日志!很多人不清楚为什么打开了数据库级附加日志,还要开启表级附加日志。接下来,我在做数据冲突测试前,先举一个最小最小的例子,告诉大家表级附加日志的重要性!
在源端关闭表级附加日志:
Source:
SQL> alter table a drop supplemental log data (all) columns;
SQL> alter table b drop supplemental log data (all) columns;
SQL> select OWNER,TABLE_NAME from all_log_groups where TABLE_NAME='A';
no rows selected
SQL> select OWNER,TABLE_NAME from all_log_groups where TABLE_NAME='B';
no rows selected
发现a,b表都没开启表级最小补充日志。
现在对源端中b表进行update测试操作
Source:
SQL> update b set OBJECT_NAME='dzl' where OBJECT_NAME='TOKEN_SQ$';
SQL> commit;
我们先看看源端该表,看看有何字段,有何数据。
SQL> select OBJECT_NAME,OBJECT_ID,OWNER,STATUS from b where OBJECT_NAME='dzl';
OBJECT_NAME OBJECT_ID OWNER STATUS
-------------------- --------- -------------------- --------------------
dzl 80201 MDSYS VALID
–因为屏幕大小原因所有字段展示不完整,我随机选择四个字段进行数据展示
Target Ogg:
GGSCI (deng2) 82> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT Abended REPDEMO 00:00:00 00:00:17
目标端的复制进程Abended了!
立马查看复制进程报告:
GGSCI (deng2) 34> view report REPDEMO
2021-12-22 15:25:55 WARNING ogg-06439 No unique key is defined for table B. All viable columns will be used to represent the key, but may not guarantee uniqueness. KEYCOLS may be used to define the key.
2021-12-22 15:25:55 INFO ogg-02756 The definition for table TEST.B is obtained from the trail file.
2021-12-22 15:25:55 INFO ogg-06511 Using following columns in default map by name: OWNER, OBJECT_NAME, SUBOBJEC
T_NAME, OBJECT_ID, DATA_OBJECT_ID, OBJECT_TYPE, CREATED, LAST_DDL_TIME, TIMESTAMP, STATUS, TEMPORARY, GENERATED, SECONDARY, NAMESPACE, EDITION_NAME.
2021-12-22 15:25:55 INFO ogg-06510 Using the following key columns for Target table PDB.TEST.B: OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID, OBJECT_TYPE, CREATED, LAST_DDL_TIME, TIMESTAMP, STATUS, TEMPORARY, GENERATED, SECONDARY, NAMESPACE, EDITION_NAME.
2021-12-22 15:26:00 WARNING ogg-02544 Unhandled error (ORA-26787: 键为 ("CREATED", "DATA_OBJECT_ID", "EDITION_NAME", "GENERATED", "LAST_DDL_TIME", "NAMESPACE", "OBJECT_ID", "OBJECT_NAME", "OBJECT_TYPE", "OWNER", "SECONDARY", "STATUS", "SUBOBJECT_NAME", "TEMPORARY", "TIMESTAMP") = (, , , , , , , TOKEN_SQ$, , , , , , , ) 的行不存在 (在表 TEST.B 中)
ORA-01403: 未找到任何数据) while processing the record at SEQNO 36, RBA 7851 in Integrated mode. REPLICAT will retry
in Direct mode.15 10:25:24 WARNING ogg-01154 SQL error 1403 mapping TEST.A to PDB.TEST.A No data found.
发现复制进程因数据不完整,找寻不到该有数据而报错。
查看logdump:
log dump
GGSCI (deng2) 87> info REPDEMO
REPLICAT REPDEMO Last Started 2021-12-22 15:29 Status Abended
INTEGRATED
Checkpoint Lag 00:00:00 (updated 00:03:34 ago)
Log Read Checkpoint File /u01/ogg/dirdat/lt000000036
2021-12-22 15:13:45.755417 RBA 6539
Logdump 121 >n
2021/12/22 15:25:44.000.599 GGSUnifiedPKUpdate Len 324 RBA 7851
Name: TEST.B (TDR Index: 3)
After Image: Partition x0c G s
a300 0000 0000 0400 ffff 0000 0100 0d00 0000 0900 | ....................
544f 4b45 4e5f 5351 2402 0004 00ff ff00 0003 0004 | TOKEN_SQ$...........
00ff ff00 0004 0004 00ff ff00 0005 0004 00ff ff00 | ....................
0006 0015 00ff ff31 3930 302d 3031 2d30 313a 3030 | .......1900-01-01:00
3a30 303a 3030 0700 1500 ffff 3139 3030 2d30 312d | :00:00......1900-01-
3031 3a30 303a 3030 3a30 3008 0004 00ff ff00 0009 | 01:00:00:00.........
0004 00ff ff00 000a 0004 00ff ff00 000b 0004 00ff | ....................
Before Image Len 167 (x000000a7)
BeforeColumnLen 163 (x000000a3)
Column 0 (x0000), Len 4 (x0004)
ffff 0000 | ....
Column 1 (x0001), Len 13 (x000d)
0000 0900 544f 4b45 4e5f 5351 24 | ....TOKEN_SQ$
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 4 (x0004)
ffff 0000 | ....
Column 4 (x0004), Len 4 (x0004)
ffff 0000 | ....
Column 5 (x0005), Len 4 (x0004)
ffff 0000 | ....
Column 6 (x0006), Len 21 (x0015)
ffff 3139 3030 2d30 312d 3031 3a30 303a 3030 3a30 | ..1900-01-01:00:00:0
30 | 0
Column 7 (x0007), Len 21 (x0015)
ffff 3139 3030 2d30 312d 3031 3a30 303a 3030 3a30 | ..1900-01-01:00:00:0
30 | 0
Column 8 (x0008), Len 4 (x0004)
ffff 0000 | ....
logdump信息说明确实大量数据存在同步丢失。
再去查看一下discard文件,能查看具体的SQL语句和报错信息。(在ogg安装目录下dirrpt路径下。)
[oracle@deng2 dirrpt]$ cat REPDEMO.dsc
Oracle GoldenGate Delivery for Oracle process started, group REPDEMO discard file opened: 2021-12-22 15:33:10.845030
Current time: 2021-12-22 15:33:12
Discarded record from action ABEND on error 1403
No data found
Aborting transaction on /u01/ogg/dirdat/lt beginning at seqno 36 rba 7,851
error at seqno 36 rba 7851
Problem replicating TEST.B to PDB.TEST.B.
Record not found
Mapping problem with unified PK update record (Target format) SCN:9.1.1455...
*
OWNER = NULL
OBJECT_NAME = TOKEN_SQ$
000000: 54 4f 4b 45 4e 5f 53 51 24 |TOKEN_SQ$ |
SUBOBJECT_NAME = NULL
OBJECT_ID = NULL
DATA_OBJECT_ID = NULL
OBJECT_TYPE = NULL
CREATED = NULL
LAST_DDL_TIME = NULL
TIMESTAMP = NULL
STATUS = NULL
TEMPORARY = NULL
GENERATED = NULL
SECONDARY = NULL
NAMESPACE = NULL
EDITION_NAME = NULL
OWNER = NULL
OBJECT_NAME = dzl
000000: 64 7a 6c |dzl |
SUBOBJECT_NAME = NULL
OBJECT_ID = NULL
DATA_OBJECT_ID = NULL
OBJECT_TYPE = NULL
CREATED = NULL
LAST_DDL_TIME = NULL
TIMESTAMP = NULL
STATUS = NULL
TEMPORARY = NULL
GENERATED = NULL
SECONDARY = NULL
NAMESPACE = NULL
EDITION_NAME = NULL
*
Process Abending : 2021-12-22 15:33:17.164172
这样就很明显,数据是完全没有同步到目标端的,并且报出了执行update操作时报错,无法找到数据。
如果实际运维碰到了这样的情况,为什么这么多列的值都为空呢??大家就可以猜测到,怕是附加日志没有添加!这时候,我们去对对答案,验证下我们是否添加该表附加日志。
GGSCI (ce1 as ogg@oracle11g) 5> info trandata test.a
Logging of supplemental redo log data is disabled for table TEST.A.
哎!所以说呀,表级附加日志一定要添加!最少要开启最小补充日志,再进行ogg同步操作。
现在源端对a表,b表开启最小补充日志
Source Ogg:
GGSCI (ce1 as ogg@oracle11g) 22> add trandata test.a NOSCHEDULINGCOLS
GGSCI (ce1 as ogg@oracle11g) 23> info trandata test.a
Logging of supplemental redo log data is enabled for table TEST.A.
Columns supplementally logged for table TEST.A: "OBJECT_ID".
GGSCI (ce1 as ogg@oracle11g) 29> add trandata test.b NOSCHEDULINGCOLS
GGSCI (ce1 as ogg@oracle11g) 30> info trandata test.b
Logging of supplemental redo log data is enabled for table TEST.B.
Columns supplementally logged for table TEST.B: "CREATED", "DATA_OBJECT_ID", "EDITION_NAME", "GENERATED", "LAST_DDL_TIME", "NAMESPACE", "OBJECT_ID", "OBJECT_NAME", "OBJECT_TYPE", "OWNER", "SECONDARY", "STATUS", "SUBOBJECT_NAME", "TEMPORARY", "TIMESTAMP".
确认添加后,重启ogg复制进程:
Target Ogg:
GGSCI (deng2) 38> alter REPDEMO,begin now
GGSCI (deng2) 40> start REPDEMO
GGSCI (deng2) 42> info all
Program Status Group Lag at Chkpt Time Since Chkpts
MANAGER RUNNING
REPLICAT RUNNING REPDEMO 00:00:00 00:00:00
复制进程恢复RUNNING状态,修复完成。
再次对b表OBJECT_NAME字段进行update操作,看目标端ogg复制进程会不会abended。
Source:
SQL> update b set OBJECT_NAME='dzl' where OBJECT_NAME='HTMLDB_MAIL_LOG';
SQL> commit;
Target Ogg:
GGSCI (deng2) 13> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT RUNNING REPDEMO 00:00:00 00:00:08
再查看下logdump:
Logdump 514 >n
2021/12/24 14:30:13.426.353 GGSUnifiedPKUpdate Len 422 RBA 9931
Name: TEST.B (TDR Index: 3)
After Image: Partition x0c G e
d700 0000 0000 0a00 0000 0600 5055 424c 4943 0100 | ............PUBLIC..
1300 0000 0f00 4854 4d4c 4442 5f4d 4149 4c5f 4c4f | ......HTMLDB_MAIL_LO
4702 0004 00ff ff00 0003 0009 0000 0005 0038 3535 | G................855
3838 0400 0400 ffff 0000 0500 0b00 0000 0700 5359 | 88................SY
4e4f 4e59 4d06 0015 0000 0032 3031 332d 3038 2d32 | NONYM......2013-08-2
343a 3132 3a30 313a 3530 0700 1500 0000 3230 3133 | 4:12:01:50......2013
2d30 382d 3234 3a31 323a 3031 3a35 3008 0017 0000 | -08-24:12:01:50.....
Before Image Len 219 (x000000db)
BeforeColumnLen 215 (x000000d7)
Column 0 (x0000), Len 10 (x000a)
0000 0600 5055 424c 4943 | ....PUBLIC
Column 1 (x0001), Len 19 (x0013)
0000 0f00 4854 4d4c 4442 5f4d 4149 4c5f 4c4f 47 | ....HTMLDB_MAIL_LOG
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 9 (x0009)
0000 0500 3835 3538 38 | ....85588
Column 4 (x0004), Len 4 (x0004)
ffff 0000 | ....
Column 5 (x0005), Len 11 (x000b)
0000 0700 5359 4e4f 4e59 4d | ....SYNONYM
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 323a 3031 3a35 | ..2013-08-24:12:01:5
30 | 0
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 323a 3031 3a35 | ..2013-08-24:12:01:5
30 | 0
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 323a 3031 | ....2013-08-24:12:01
3a35 30 | :50
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 31 | ....1
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
After Image Len 203 (x000000cb)
Column 0 (x0000), Len 10 (x000a)
0000 0600 5055 424c 4943 | ....PUBLIC
Column 1 (x0001), Len 7 (x0007)
0000 0300 647a 6c | ....dzl
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 9 (x0009)
0000 0500 3835 3538 38 | ....85588
Column 4 (x0004), Len 4 (x0004)
ffff 0000 | ....
Column 5 (x0005), Len 11 (x000b)
0000 0700 5359 4e4f 4e59 4d | ....SYNONYM
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 323a 3031 3a35 | ..2013-08-24:12:01:5
30 | 0
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 323a 3031 3a35 | ..2013-08-24:12:01:5
30 | 0
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 323a 3031 | ....2013-08-24:12:01
3a35 30 | :50
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 31 | ....1
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
确实正常了!看到这里是不是有一些小伙伴看懵了?看不懂logdump展示的数据信息对不对?等下我会专门做个测试,来告诉下大家logdump究竟是展示什么数据信息的。
那不开启表级最小补充日志的情况下insert,delete操作能不能执行呢?
我们在源端b表关闭表级附加日志
Source:
SQL> alter table b drop supplemental log data (primary key,unique index) columns;
SQL> select OWNER,TABLE_NAME from all_log_groups where TABLE_NAME='b';
no rows selected
这个时候,我们尝试下insert操作。
SQL> insert into b (object_id) values(20211223);
SQL> commit;
Target:
SQL> select object_id from b where object_id=20211223;
OBJECT_ID
----------
20211223
哎,发现没有报错,那我们测试下delete操作呢?
Source:
SQL> delete from b where object_id=11111;
SQL> commit;
Target:
SQL> select * from b where object_id=11111;
no rows selected
也没有报错,能同步删除操作。
小结:源端表不开启最小补充日志的情况下,Insert操作和Delete操作可能能够同步,进程不报错。但是Update操作,是极可能不能同步的,并且ogg目标端复制进程会报错。
Oracle日志(redo log)一般用于实例恢复和介质恢复,但是如果需要靠日志还原完整的DML操作信息(比如Goldengate),默认记录的日志量是不够的。对于Insert、Delete命令,在默认情况下产生的重做记录足以表明被修改的行的每个字段在被修改前后的值是什么。但是对于UPDATE的操作,redo默认只记录了rowid以及被修改的字段信息,但GoldenGate还原这个事务时,是在另一个库中进行还原,这时组成ROWID的四个部分(对象ID,数据文件ID,块号,行号)中,极可能是与原库不相同的,所以,不能根据ROWID来进行还原和处理。而要在SQL层面根据某个键值来定位记录,所以还需要将主键或者其他字段的信息附加到日志中去。要往日志中增加这些额外字段信息的操作,就是开启附加日志。
参考链接:https://blog.csdn.net/weixin_45234802/article/details/106069978
所以接下来,全程打开表级最小补充日志!
首先,我们来对比下,开启表级最小补充日志后,主键表与非主键表分别进行update操作下的logdump。看看究竟有什么不同~
4、LOGDUMP测试
4.1.主键表+UPDATE
Source:
SQL> update a set OBJECT_NAME='dzl222' where OBJECT_NAME='WWV_MIG_FRM_TRG_PK';
SQL> commit;
接下来去目标端ogg查看logdump
Target logdump:
2021/12/23 17:47:50.340.199 GGSUnifiedUpdate Len 70 RBA 5631
Name: TEST.A (TDR Index: 3)
After Image: Partition x0c G s
2700 0000 0100 1600 0000 1200 5757 565f 4d49 475f | '...........WWV_MIG_
4652 4d5f 5452 475f 504b 0300 0900 0000 0500 3836 | FRM_TRG_PK........86
3237 3901 000a 0000 0006 0064 7a6c 3232 3203 0009 | 279........dzl222...
0000 0005 0038 3632 3739 | .....86279
Before Image Len 43 (x0000002b)
BeforeColumnLen 39 (x00000027)
Column 1 (x0001), Len 22 (x0016)
0000 1200 5757 565f 4d49 475f 4652 4d5f 5452 475f | ....WWV_MIG_FRM_TRG_
504b | PK
Column 3 (x0003), Len 9 (x0009)
0000 0500 3836 3237 39 | ....86279
After Image Len 27 (x0000001b)
Column 1 (x0001), Len 10 (x000a)
0000 0600 647a 6c32 3232 | ....dzl222
Column 3 (x0003), Len 9 (x0009)
0000 0500 3836 3237 39 | ....86279
4.2.非主键表+UPDATE
Source:
SQL> update b set OBJECT_NAME='dzl333' where OBJECT_NAME='WWV_MIG_FRM_TRG_PK';
SQL> commit;
Target logdump:
2021/12/23 19:06:15.341.652 GGSUnifiedPKUpdate Len 444 RBA 7255
Name: TEST.B (TDR Index: 4)
After Image: Partition x0c G s
e200 0000 0000 0f00 0000 0b00 4150 4558 5f30 3330 | ............APEX_030
3230 3001 0016 0000 0012 0057 5756 5f4d 4947 5f46 | 200........WWV_MIG_F
524d 5f54 5247 5f50 4b02 0004 00ff ff00 0003 0009 | RM_TRG_PK...........
0000 0005 0038 3632 3739 0400 0900 0000 0500 3836 | .....86279........86
3237 3905 0009 0000 0005 0049 4e44 4558 0600 1500 | 279........INDEX....
0000 3230 3133 2d30 382d 3234 3a31 313a 3539 3a32 | ..2013-08-24:11:59:2
3807 0015 0000 0032 3031 332d 3038 2d32 343a 3131 | 8......2013-08-24:11
Before Image Len 230 (x000000e6)
BeforeColumnLen 226 (x000000e2)
Column 0 (x0000), Len 15 (x000f)
0000 0b00 4150 4558 5f30 3330 3230 30 | ....APEX_030200
Column 1 (x0001), Len 22 (x0016)
0000 1200 5757 565f 4d49 475f 4652 4d5f 5452 475f | ....WWV_MIG_FRM_TRG_
504b | PK
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 9 (x0009)
0000 0500 3836 3237 39 | ....86279
Column 4 (x0004), Len 9 (x0009)
0000 0500 3836 3237 39 | ....86279
Column 5 (x0005), Len 9 (x0009)
0000 0500 494e 4445 58 | ....INDEX
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3539 3a32 | ..2013-08-24:11:59:2
38 | 8
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3539 3a32 | ..2013-08-24:11:59:2
38 | 8
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3539 | ....2013-08-24:11:59
3a32 38 | :28
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 34 | ....4
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
After Image Len 214 (x000000d6)
Column 0 (x0000), Len 15 (x000f)
0000 0b00 4150 4558 5f30 3330 3230 30 | ....APEX_030200
Column 1 (x0001), Len 10 (x000a)
0000 0600 647a 6c33 3333 | ....dzl333
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 9 (x0009)
0000 0500 3836 3237 39 | ....86279
Column 4 (x0004), Len 9 (x0009)
0000 0500 3836 3237 39 | ....86279
Column 5 (x0005), Len 9 (x0009)
0000 0500 494e 4445 58 | ....INDEX
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3539 3a32 | ..2013-08-24:11:59:2
38 | 8
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3539 3a32 | ..2013-08-24:11:59:2
38 | 8
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3539 | ....2013-08-24:11:59
3a32 38 | :28
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 34 | ....4
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
发现区别了吗?
下面我用图表的形式更直观的对比logdump展示数据信息区别~
| 主键表 update | 非主键表 update | |
|---|---|---|
| logdump before | Ogg trail文件中仅记录主键字段和操作字段的信息 | Ogg trail文件中会记录所有字段的信息 |
| logdump after | Ogg trail文件中仅记录主键字段和操作字段的信息 | Ogg trail文件中会记录所有字段的信息 |
5、模拟DML数据冲突测试
5.1. UPDATENOTFOUND
场景:对于a表源端修改一条记录,ogg同步到目标端。但这条记录在目标端不存在,从而发生update数据冲突,目标端复制进程Abended。
5.1.1.INSERTMISSINGUPDATES测试
官方文档很详细的告诉我们解决方式,目标端ogg复制进程增添INSERTMISSINGUPDATES | NOINSERTMISSINGUPDATES参数。
–那我就很好奇了,这个参数就能解决update数据冲突问题吗?啥情况能解决呢,啥情况又不能解决呢?接下来,就让我们从是否为主键列来分析。
–主键情况
报错复现
首先在目标端a表删除掉即将做测试的数据
Target:
SQL> delete from a where object_id=111;
SQL> commit;
--到源端修改刚刚删除掉的数据,并查看目标端ogg复制进程状态
Source:
SQL> update a set object_id=999999'where object_id=111;
SQL> commit;
Target Ogg:
GGSCI (deng2) 151> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT Abended REPDEMO 00:00:00 00:01:05
哎,果然Abended了!
查看复制进程报告:
2021-12-15 11:15:06 WARNING ogg-02544 Unhandled error (ORA-26787: 键为 ("OBJECT_ID") = (111) 的行不存在 (在表 TEST.A 中)
ORA-01403: 未找到任何数据) while processing the record at SEQNO 31, RBA 6374 in Integrated mode. REPLICAT will retryin Direct mode.
2021-12-15 11:15:06 WARNING ogg-01004 Aborted grouped transaction on PDB.TEST.A, Database error 1403 (No data found).
2021-12-15 11:15:06 WARNING ogg-01003 Repositioning to rba 6374 in seqno 31.
2021-12-15 11:15:06 WARNING ogg-01154 SQL error 1403 mapping TEST.A to PDB.TEST.A No data found.
2021-12-15 11:15:06 ERROR ogg-01296 Error mapping from TEST.A to PDB.TEST.A.
update目标端找不到操作数据报错。
报错处理
在目标端ogg复制进程添加INSERTMISSINGUPDATES参数
Target Ogg:
GGSCI (deng2) 167> edit params repdemo
replicat repdemo
USERID ogg@pdb, PASSWORD ogg
DBOPTIONS INTEGRATEDPARAMS(parallelism 6)
INSERTMISSINGUPDATES
MAP test.*, Target pdb.test.*;
重启复制进程后再次进行测试…
Source:
SQL> update a set object_id=12345678 where object_id=123456789;
SQL> commit;
Target:
SQL> select object_id from a where object_id=12345678;
OBJECT_ID
----------
12345678
貌似解决成功,现在再来看看非主键情况
非主键情况
采用b表,重复上述测试:
Target:
SQL> delete from b where object_id=12345678;
SQL> commit;
Source:
SQL> update b set object_id=122222222 where object_id=12345678;
SQL> commit;
接下来查看目标端能否查询更新数据。
Target:
SQL> select object_id from b where object_id=122222222;
OBJECT_ID
----------
122222222
也没问题!
于是得出结论:INSERTMISSINGUPDATES参数能让update在目标端找不到数据的情况下自动改成insert进行操作。
5.1.2.INSERTMISSINGUPDATES缺陷
但是这个参数会不会存在其他问题呢…??
我们查看下主键表a表更改OBJECT_ID=1234为OBJECT_ID=233333的时候其他字段的值,看看是否也进行了数据同步。
主键表
我们再对a表中的OBJECT_ID列,再次进行一次操作。
Target:
SQL> delete from a where OBJECT_ID=1234;
SQL> commit;
Source:
SQL> update a set OBJECT_ID=233333 where OBJECT_ID=1234;
SQL> commit;
我们来对比下源端和目标端a表OBJECT_ID=233333时,OWNER,OBJECT_TYPE和STATUS字段的值。
Source:
SQL> select object_id,owner,object_type,status from a where object_id=233333;
OBJECT_ID OWNER OBJECT_TYPE STATUS
-------------- -------------------- -------------------- --------------------
233333 SYS TYPE VALID
Target:
SQL> select object_id,owner,object_type,status from a where object_id=233333;
OBJECT_ID OWNER OBJECT_TYPE STATUS
---------- ------------------------------ ------------------- -------
233333
哎!发现只同步了主键表的update操作字段,其他字段并没有同步!
接下来,查看下logdump:
Logdump 603 >n
2021/12/02 14:27:55.517.222 Metadata Len 0 RBA 10433
Table Name: TEST.A (Ref TDR Index: 2)
Logdump 604 >n
2021/12/24 14:54:39.426.966 GGSUnifiedPKUpdate Len 30 RBA 10486
Name: TEST.A (TDR Index: 4)
After Image: Partition x0c G s
0c00 0000 0300 0800 0000 0400 3132 3334 0300 0a00 | ............1234....
0000 0600 3233 3333 3333 | ....233333
Before Image Len 16 (x00000010)
BeforeColumnLen 12 (x0000000c)
Column 3 (x0003), Len 8 (x0008)
0000 0400 3132 3334 | ....1234
After Image Len 14 (x0000000e)
Column 3 (x0003), Len 10 (x000a)
0000 0600 3233 3333 3333 | ....233333
发现不合理的地方了吗?Ogg只进行了OBJECT_ID的update同步操作。
这个时候,问题又来了,非主键表update操作,是否也会发生这样不合理的情况呢?
我们对b表再次进行上面的update冲突测试。
非主键表
Target:
SQL> delete from b where OBJECT_ID=12;
SQL> commit;
Source:
SQL> update b set OBJECT_ID=233333 where OBJECT_ID=12;
SQL> commit;
我们再来对比下源端和目标端b表OBJECT_ID=233333时,OWNER,OBJECT_TYPE和STATUS字段的值。
Source:
SQL> select object_id,owner,object_type,status from b where object_id=233333;
OBJECT_ID OWNER OBJECT_TYPE STATUS
-------------- -------------------- -------------------- --------------------
233333 SYS TABLE VALID
Target:
SQL> select object_id,owner,object_type,status from b where object_id=233333;
OBJECT_ID OWNER OBJECT_TYPE STATUS
---------- ------------------------------ ------------------- -------
233333 SYS TABLE VALID
哎,好奇怪!非主键表又能同步所有字段信息。赶紧查看下logdump,看看数据信息展示情况:
logdump:
Logdump 623 >n
2021/12/24 15:01:13.427.025 GGSUnifiedPKUpdate Len 402 RBA 10622
Name: TEST.B (TDR Index: 3)
After Image: Partition x0c G s
c500 0000 0000 0700 0000 0300 5359 5301 0008 0000 | ............SYS.....
0004 0046 4554 2402 0004 00ff ff00 0003 0006 0000 | ...FET$.............
0002 0031 3204 0005 0000 0001 0036 0500 0900 0000 | ...12........6......
0500 5441 424c 4506 0015 0000 0032 3031 332d 3038 | ..TABLE......2013-08
2d32 343a 3131 3a33 373a 3335 0700 1500 0000 3230 | -24:11:37:35......20
3133 2d30 382d 3234 3a31 313a 3337 3a33 3508 0017 | 13-08-24:11:37:35...
0000 0013 0032 3031 332d 3038 2d32 343a 3131 3a33 | .....2013-08-24:11:3
Before Image Len 201 (x000000c9)
BeforeColumnLen 197 (x000000c5)
Column 0 (x0000), Len 7 (x0007)
0000 0300 5359 53 | ....SYS
Column 1 (x0001), Len 8 (x0008)
0000 0400 4645 5424 | ....FET$
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 6 (x0006)
0000 0200 3132 | ....12
Column 4 (x0004), Len 5 (x0005)
0000 0100 36 | ....6
Column 5 (x0005), Len 9 (x0009)
0000 0500 5441 424c 45 | ....TABLE
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3337 | ....2013-08-24:11:37
3a33 35 | :35
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 31 | ....1
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
After Image Len 201 (x000000c9)
Column 0 (x0000), Len 7 (x0007)
0000 0300 5359 53 | ....SYS
Column 1 (x0001), Len 8 (x0008)
0000 0400 4645 5424 | ....FET$
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 10 (x000a)
0000 0600 3233 3333 3333 | ....233333
Column 4 (x0004), Len 5 (x0005)
0000 0100 36 | ....6
Column 5 (x0005), Len 9 (x0009)
0000 0500 5441 424c 45 | ....TABLE
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3337 | ....2013-08-24:11:37
3a33 35 | :35
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 31 | ....1
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
真的展示了所有字段数据信息,并进行了同步处理!
大家记得上面做的logdump测试结论吗?不记得的话我把logdump对比结果再拿出来。
| 主键表 update | 非主键表 update | |
|---|---|---|
| logdump before | Ogg trail文件中仅记录主键字段和操作字段的信息 | Ogg trail文件中会记录所有字段的信息 |
| logdump after | Ogg trail文件中仅记录主键字段和操作字段的信息 | Ogg trail文件中会记录所有字段的信息 |
现在知道为什么主键表只同步update操作字段而非主键表同步所有字段信息了吗?
但是,主键表同步字段不完全的bug要如何解决呢?
接下来给大家分享两种解决方式:
5.1.2.1.ADD TRANDATA ALLCOLS
第一种解决方式其实上面的提问已经告诉大家解决思路了,那就是对源端ogg配置抽取所有字段,
add trandata schema.table_name allcols
说明测试场景:
- ogg源端开启add trandata allcols
- ogg目标端复制进程增加参数INSERTMISSINGUPDATES
- 重复上述update数据冲突测试
因为要测试的是主键字段,所以我们使用a表进行测试。
Source Ogg:
GGSCI (ce1 as ogg@oracle11g) 34> add trandata test.a allcols
确认allcols参数是否生效:
GGSCI (ce1 as ogg@oracle11g) 46> info trandata test.a
Logging of supplemental redo log data is enabled for table TEST.A.
All columns supplementally logged for table TEST.A.
主键 + allcols
Target:
SQL> delete from a where object_id=6666;
SQL> commit;
Source:
SQL> update a set object_id=666666 where object_id=6666;
SQL> commit;
SQL> select object_id,owner,object_type,status from a where object_id=666666;
OBJECT_ID OWNER OBJECT_TYPE STATUS
---------- ------------------------------ ------------------- -------
666666 SYS INDEX VALID
Target:
SQL> select object_id,owner,object_type,status from a where object_id=666666;
OBJECT_ID OWNER OBJECT_TYPE STATUS
---------- ------------------------------ ------------------- -------
666666 SYS INDEX VALID
再查看下logdump:
Logdump 728 >n
2021/12/24 15:22:35.427.442 GGSUnifiedPKUpdate Len 436 RBA 11268
Name: TEST.A (TDR Index: 4)
After Image: Partition x0c G s
d700 0000 0000 0700 0000 0300 5359 5301 0015 0000 | ............SYS.....
0011 0057 5248 245f 5253 5243 5f50 4c41 4e5f 504b | ...WRH$_RSRC_PLAN_PK
0200 0400 ffff 0000 0300 0800 0000 0400 3636 3636 | ................6666
0400 0800 0000 0400 3636 3636 0500 0900 0000 0500 | ........6666........
494e 4445 5806 0015 0000 0032 3031 332d 3038 2d32 | INDEX......2013-08-2
343a 3131 3a33 393a 3131 0700 1500 0000 3230 3133 | 4:11:39:11......2013
2d30 382d 3234 3a31 313a 3339 3a31 3108 0017 0000 | -08-24:11:39:11.....
Before Image Len 219 (x000000db)
BeforeColumnLen 215 (x000000d7)
Column 0 (x0000), Len 7 (x0007)
0000 0300 5359 53 | ....SYS
Column 1 (x0001), Len 21 (x0015)
0000 1100 5752 4824 5f52 5352 435f 504c 414e 5f50 | ....WRH$_RSRC_PLAN_P
4b | K
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 8 (x0008)
0000 0400 3636 3636 | ....6666
Column 4 (x0004), Len 8 (x0008)
0000 0400 3636 3636 | ....6666
Column 5 (x0005), Len 9 (x0009)
0000 0500 494e 4445 58 | ....INDEX
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3339 3a31 | ..2013-08-24:11:39:1
31 | 1
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3339 3a31 | ..2013-08-24:11:39:1
31 | 1
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3339 | ....2013-08-24:11:39
3a31 31 | :11
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 34 | ....4
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
After Image Len 217 (x000000d9)
Column 0 (x0000), Len 7 (x0007)
0000 0300 5359 53 | ....SYS
Column 1 (x0001), Len 21 (x0015)
0000 1100 5752 4824 5f52 5352 435f 504c 414e 5f50 | ....WRH$_RSRC_PLAN_P
4b | K
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 10 (x000a)
0000 0600 3636 3636 3636 | ....666666
Column 4 (x0004), Len 8 (x0008)
0000 0400 3636 3636 | ....6666
Column 5 (x0005), Len 9 (x0009)
0000 0500 494e 4445 58 | ....INDEX
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3339 3a31 | ..2013-08-24:11:39:1
31 | 1
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3339 3a31 | ..2013-08-24:11:39:1
31 | 1
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3339 | ....2013-08-24:11:39
3a31 31 | :11
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 34 | ....4
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
嗯,主键表也同样抽取所有字段数据信息了!
哎!问题解决了!接下来就让我们看看第二种解决方式吧~
5.1.2.2.FETCHOPTIONS FETCHPKUPDATECOLS
第二种解决方式是在源端ogg抽取进程中添加下列参数FETCHOPTIONS FETCHPKUPDATECOLS。我们还是测试主键表看看这个参数能否解决update冲突所带来的其他字段不同步的情况。
说明测试场景:
- ogg源端抽取进程增加参数FETCHOPTIONS FETCHPKUPDATECOLS
- ogg目标端复制进程增加参数INSERTMISSINGUPDATES
- 重复上述update数据冲突测试
首先要关闭allcols参数,实现控制变量
Source Ogg:
GGSCI (ce1 as ogg@oracle11g) 4> delete trandata test.a
GGSCI (ce1 as ogg@oracle11g) 5> add trandata test.a NOSCHEDULINGCOLS
检测一下是否关闭成功:
GGSCI (ce1 as ogg@oracle11g) 9> info trandata test.a
Logging of supplemental redo log data is enabled for table TEST.A.
Columns supplementally logged for table TEST.A: "OBJECT_ID".
接着我们去配置ogg抽取进程,增加参数FETCHOPTIONS FETCHPKUPDATECOLS,开始测试
主键 + FETCHOPTIONS FETCHPKUPDATECOLS
Target:
SQL> delete from a where object_id=66;
SQL> commit;
Source:
SQL> update a set OBJECT_ID=123123 where OBJECT_ID=66;
SQL> commit;
SQL> select object_id,owner,object_type,status from a where object_id=123123;
OBJECT_ID OWNER OBJECT_TYPE STATUS
-------------- -------------------- -------------------- --------------------
123123 SYS INDEX VALID
Target:
SQL> select object_id,owner,object_type,status from a where object_id=123123;
OBJECT_ID OWNER OBJECT_TYPE STATUS
-------------- -------------------- -------------------- --------------------
123123 SYS INDEX VALID
哎!貌似也解决了!
再去看下logdump:
Logdump 815 >n
2021/12/24 15:33:33.427.710 GGSUnifiedPKUpdate Len 221 RBA 12060
Name: TEST.A (TDR Index: 5)
After Image: Partition x0c G s
0a00 0000 0300 0600 0000 0200 3636 0000 0700 0000 | ............66......
0300 5359 5301 000d 0000 0009 0049 5f55 4752 4f55 | ..SYS........I_UGROU
5032 0200 0400 ffff 0000 0300 0a00 0000 0600 3132 | P2................12
3331 3233 0400 0600 0000 0200 3636 0500 0900 0000 | 3123........66......
0500 494e 4445 5806 0015 0000 0032 3031 332d 3038 | ..INDEX......2013-08
2d32 343a 3131 3a33 373a 3335 0700 1500 0000 3230 | -24:11:37:35......20
3133 2d30 382d 3234 3a31 313a 3337 3a33 3508 0017 | 13-08-24:11:37:35...
Before Image Len 14 (x0000000e)
BeforeColumnLen 10 (x0000000a)
Column 3 (x0003), Len 6 (x0006)
0000 0200 3636 | ....66
After Image Len 207 (x000000cf)
Column 0 (x0000), Len 7 (x0007)
0000 0300 5359 53 | ....SYS
Column 1 (x0001), Len 13 (x000d)
0000 0900 495f 5547 524f 5550 32 | ....I_UGROUP2
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 10 (x000a)
0000 0600 3132 3331 3233 | ....123123
Column 4 (x0004), Len 6 (x0006)
0000 0200 3636 | ....66
Column 5 (x0005), Len 9 (x0009)
0000 0500 494e 4445 58 | ....INDEX
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3337 | ....2013-08-24:11:37
3a33 35 | :35
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 34 | ....4
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
哎,很奇怪!Ogg trail文件before update数据信息并不会记录全部字段,仅记录主键字段和操作字段信息。那么,严谨些,我们再测试下非主键情况下,logdump是否也是这样展示数据信息呢?
非主键+ FETCHOPTIONS FETCHPKUPDATECOLS
Target:
SQL> delete from b where object_id=66;
SQL> commit;
Source:
SQL> update b set object_id=123321 where object_id=66;
SQL> commit;
我们直接观察target logdump:
Logdump 866 >n
2021/12/02 15:22:54.233.090 Metadata Len 0 RBA 12392
Table Name: TEST.B (Ref TDR Index: 1)
Logdump 867 >n
2021/12/24 15:49:38.428.283 GGSUnifiedPKUpdate Len 414 RBA 12445
Name: TEST.B (TDR Index: 6)
After Image: Partition x0c G s
cb00 0000 0000 0700 0000 0300 5359 5301 000d 0000 | ............SYS.....
0009 0049 5f55 4752 4f55 5032 0200 0400 ffff 0000 | ...I_UGROUP2........
0300 0600 0000 0200 3636 0400 0600 0000 0200 3636 | ........66........66
0500 0900 0000 0500 494e 4445 5806 0015 0000 0032 | ........INDEX......2
3031 332d 3038 2d32 343a 3131 3a33 373a 3335 0700 | 013-08-24:11:37:35..
1500 0000 3230 3133 2d30 382d 3234 3a31 313a 3337 | ....2013-08-24:11:37
3a33 3508 0017 0000 0013 0032 3031 332d 3038 2d32 | :35........2013-08-2
Before Image Len 207 (x000000cf)
BeforeColumnLen 203 (x000000cb)
Column 0 (x0000), Len 7 (x0007)
0000 0300 5359 53 | ....SYS
Column 1 (x0001), Len 13 (x000d)
0000 0900 495f 5547 524f 5550 32 | ....I_UGROUP2
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 6 (x0006)
0000 0200 3636 | ....66
Column 4 (x0004), Len 6 (x0006)
0000 0200 3636 | ....66
Column 5 (x0005), Len 9 (x0009)
0000 0500 494e 4445 58 | ....INDEX
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3337 | ....2013-08-24:11:37
3a33 35 | :35
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 34 | ....4
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
After Image Len 207 (x000000cf)
Column 0 (x0000), Len 7 (x0007)
0000 0300 5359 53 | ....SYS
Column 1 (x0001), Len 13 (x000d)
0000 0900 495f 5547 524f 5550 32 | ....I_UGROUP2
Column 2 (x0002), Len 4 (x0004)
ffff 0000 | ....
Column 3 (x0003), Len 10 (x000a)
0000 0600 3132 3333 3231 | ....123321
Column 4 (x0004), Len 6 (x0006)
0000 0200 3636 | ....66
Column 5 (x0005), Len 9 (x0009)
0000 0500 494e 4445 58 | ....INDEX
Column 6 (x0006), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 7 (x0007), Len 21 (x0015)
0000 3230 3133 2d30 382d 3234 3a31 313a 3337 3a33 | ..2013-08-24:11:37:3
35 | 5
Column 8 (x0008), Len 23 (x0017)
0000 1300 3230 3133 2d30 382d 3234 3a31 313a 3337 | ....2013-08-24:11:37
3a33 35 | :35
Column 9 (x0009), Len 9 (x0009)
0000 0500 5641 4c49 44 | ....VALID
Column 10 (x000a), Len 5 (x0005)
0000 0100 4e | ....N
Column 11 (x000b), Len 5 (x0005)
0000 0100 4e | ....N
Column 12 (x000c), Len 5 (x0005)
0000 0100 4e | ....N
Column 13 (x000d), Len 5 (x0005)
0000 0100 34 | ....4
Column 14 (x000e), Len 4 (x0004)
ffff 0000 | ....
logdump before果然是抽取的所有字段数据信息!
那为什么allcols和FETCHPKUPDATECOLS参数可以解决update数据冲突导致同步字段不完全的bug呢?
Ogg对trail文件中After Image数据信息进行解析。发生update数据冲突,INSERTMISSINGUPDATES参数将update转换成insert进行操作。若没有allcols或者FETCHPKUPDATECOLS,trail文件中After Image数据信息仅为主键字段和操作字段的数据信息,当然只同步update操作字段和主键字段信息,别的信息不进行insert操作。而allcols和FETCHPKUPDATECOLS参数可以将trail文件中After Image数据信息记录所有字段,所以可以实现全字段同步。
针对上述测试进行小结,满足如下测试场景,观察如下:
- 源端表均已开启最小补充日志;
- 源端执行update table object_id 字段进行观察;
- 使用Logdump分析trail文件中捕获的数据字段信息!
| supplemental redo tables | allcols | FETCHPKUPDATECOLS | |
|---|---|---|---|
| before主键表 | Ogg trail文件中仅记录主键字段和操作字段的信息 | Ogg trail文件中会记录所有字段的信息 | Ogg trail文件中仅记录主键字段和操作字段的信息 |
| before非主键表 | Ogg trail文件中会记录所有字段的信息 | Ogg trail文件中会记录所有字段的信息 | Ogg trail文件中会记录所有字段的信息 |
| after 主键表 | Ogg trail文件中仅记录主键字段和操作字段的信息 | Ogg trail文件中会记录所有字段的信息 | Ogg trail文件中会记录所有字段的信息 |
| after 非主键表 | Ogg trail文件中会记录所有字段的信息 | Ogg trail文件中会记录所有字段的信息 | Ogg trail文件中会记录所有字段的信息 |
那update数据冲突问题解决了,我们再来看看insert和delete是否也会发生类似的情况呢?应该如何解决呢?
5.2. INSERTROWEXISTS
场景:对于a表源端增加一条记录,ogg同步到目标端。但这条记录在目标端已经存在,从而发生insert数据冲突,目标端复制进程Abended。
报错复现
Target:
SQL> insert into a (OBJECT_ID) values(1111);
SQL> commit;
Source:
SQL> insert into a (OBJECT_ID) values(1111);
SQL> commit;
查看Target Ogg进程是否Abended
GGSCI (deng2) 12> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT Abended REPDEMO 00:00:00 00:00:45
2021-12-16 09:27:45 WARNING ogg-02544 Unhandled error (ORA-26799: 违反了唯一约束条件 TEST.DZL (表 TEST.A, 列值 ("OBJECT_ID") = (1111))
ORA-00001: 违反唯一约束条件 (TEST.DZL)
ORA-00001: 违反唯一约束条件 (TEST.DZL)) while processing the record at SEQNO 32, RBA 5422 in Integrated mode. REPLIC
AT will retry in Direct mode.
2021-12-16 09:27:46 WARNING ogg-01004 Aborted grouped transaction on PDB.TEST.A, Database error 1 (OCI Error ORA-0
0001: unique constraint (TEST.DZL) violated (status = 1), SQL <INSERT INTO "TEST"."A"("OWNER","OBJECT_NAME","SUBOBJECT_NAME","OBJECT_ID","DATA_OBJECT_ID","OBJECT_TYPE","CREATED","LAST_DDL_TIME","TIMESTAMP","STATUS","TEMPORARY","GEN
ERATED","SECONDARY","NAMESPACE","EDITION_NAME")
VALUES (:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14)>).
从报告清晰地看出数据违反了唯一约束,处理insert已存在。那我们需要如何处理呢?
报错处理+IGNORE
这种情况,我们希望ogg做的操作是什么呢? 是不是希望ogg同步能跳过数据,不对其进行处理呀。
RESOLVECONFLICT(INSERTROWEXISTS,(DEFAULT,IGNORE))
下面文章就解释了这个问题:复制进程添加上述参数就可以解决。
参考链接:http://blog.itpub.net/704514/viewspace-764136
文章中提到不仅仅有IGNORE参数,还有OVERWRITE,两者区别是忽略和覆盖。OVERWRITE参数作用是使用新的数据对其进行覆盖!接下来我们一一进行测试。
Target:
SQL> insert into a (OBJECT_ID,OWNER,STATUS) values(99999,'dzl','N');
SQL> commit;
Source:
SQL> insert into a (OBJECT_ID,OWNER,STATUS) values(99999,'dzl','Y');
SQL> commit;
这时看看Target Ogg进程情况
GGSCI (deng2) 40> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT RUNNING REPDEMO 00:00:00 00:00:03
可以发现,目标端ogg的复制进程是RUNNING状态。接下来看看源端和目标端的数据情况。
Source:
SQL> select object_id,owner,status from a where OBJECT_ID=99999;
OBJECT_ID OWNER STATUS
---------- -------------------- --------------
99999 dzl Y
Target:
SQL> select object_id,owner,status from a where OBJECT_ID=99999;
OBJECT_ID OWNER STATUS
---------- ------------------------------ -------
99999 dzl N
可以看出,通过上述参数,已经解决了只同步OBJECT_ID字段的问题!并且也证实了博客中提到的IGNORE参数,忽略了数据冲突,不对其进行处理。那我们尝试下OVERWRITE参数,看看有什么不同~
报错处理+OVERWRITE
Target:
SQL> insert into a (OBJECT_ID,OWNER,STATUS) values(888888,'dzl','N');
SQL> commit;
Source:
SQL> insert into a (OBJECT_ID,OWNER,STATUS) values(888888,'dzl','Y');
SQL> commit;
接下来看看源端和目标端的数据情况,看看是否可以进行数据的覆盖~
Source:
SQL> select object_id,owner,status from a where OBJECT_ID=888888;
OBJECT_ID OWNER STATUS
---------- -------------------- --------------
888888 dzl Y
Target:
SQL> select object_id,owner,status from a where OBJECT_ID=888888;
OBJECT_ID OWNER STATUS
---------- ------------------------------ -------
888888 dzl Y
哎~ 数据是不是覆盖了!!!本来目标端我们设置的STATUS=N,经过ogg数据同步,STATUS更改成了Y。是不是很神奇呢~
总结:insert数据冲突解决方式是什么呢?
在目标端ogg复制进程增加RESOLVECONFLICT(INSERTROWEXISTS,(DEFAULT,IGNORE))
参数。而该参数中的IGNORE是同步操作忽略数据变化,OVERWRITE参数则是覆盖数据的变化~
那么最后我们再来看看delete数据冲突的情况吧~
5.3. DELETEROWEXISTS
场景:对于a表源端删除一条记录,ogg同步到目标端。但这条记录在目标端本身就不存在,从而发生delete数据冲突,目标端复制进程Abended。
报错复现
Target:
SQL> delete from a where object_id=888888;
SQL> commit;
Source:
SQL> delete from a where object_id=888888;
SQL> commit;
这时,咱去看看目标端ogg复制进程的状态。
GGSCI (deng2) 55> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT Abended REPDEMO 00:00:00 00:00:25
果不其然,它Abended了...查看报告
2021-12-16 10:17:47 WARNING ogg-02544 Unhandled error (ORA-26787: 键为 ("OBJECT_ID") = (888888) 的行不存在 (在表 TEST.A 中)
ORA-01403: 未找到任何数据) while processing the record at SEQNO 32, RBA 6487 in Integrated mode. REPLICAT will retry
in Direct mode.
2021-12-16 10:17:47 WARNING ogg-01919 Missing RESOLVECONFLICT for SQL error 1,403.
2021-12-16 10:17:47 WARNING ogg-01004 Aborted grouped transaction on PDB.TEST.A, Database error 1403 (No data foun
d).
2021-12-16 10:17:47 WARNING ogg-01003 Repositioning to rba 6487 in seqno 32.
2021-12-16 10:17:47 WARNING ogg-01154 SQL error 1403 mapping TEST.A to PDB.TEST.A No data found.
发现果然报错该同步删除操作的数据不存在...
那该如何解决呢?
报错处理
还是一样的,我们先问一下自己一个问题,这个情况下我们希望ogg做什么呢?是不是希望ogg能忽略这个操作,不作任何反应呀!
下面文章就解决了这个问题~
目标端ogg复制进程增加resolveconflict(deleterowmissing, (default,discard))参数。
参考链接:https://www.cnblogs.com/hxlasky/p/10904435.html
并且文章中提到,这个要是更新的不是主键的话,需要在源端为每个列加上补充日志,也就是上面提到的要打开数据库级全体字段补充日志。
接下来,我们开始测试。首先在目标端ogg复制进程增加上述参数。
Target:
SQL> delete from a where object_id=1111;
SQL> commit;
Source:
SQL> delete from a where object_id=1111;
SQL> commit;
这时我们来看看目标端ogg复制进程的状态,看看是否还是RUNNING。
GGSCI (deng2) 22> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT RUNNING REPDEMO 00:00:00 00:00:09
问题解决!!
总结:delete数据冲突解决方式是什么呢?
是在目标端ogg复制进程增加resolveconflict(deleterowmissing, (default,discard))参数。
6、补充学习HANDLECOLLISIONS
我最近看了几篇文章,也同样提到了数据冲突的问题,解决方式是HANDLECOLLISIONS和FETCHOPTIONS FETCHPKUPDATECOLS参数。我觉得很有意思,于是查阅官方文档了解了这两个参数,接下来做一个小小的学习测试。
环境:首先源端和目标端都还是运用到上述的a表和OBJECT_ID主键列去除掉目标端ogg复制进程中的上面测试所增添的参数,并重启复制进程。然后重复上面测试的操作。首先,我们先测试下insert数据冲突的情况。
6.1. INSERT
报错复现
Target:
SQL> insert into a (OBJECT_ID) values(2333333);
SQL> commit;
Source:
SQL> insert into a (OBJECT_ID) values(2333333);
SQL> commit;
查看目标端ogg复制进程的状态
GGSCI (deng2) 22> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT Abended REPDEMO 00:00:00 00:00:25
很显然,它Abended了。
查看复制进程报告,命令没有忘记吧~view report REPDEMO
2021-12-17 09:52:15 WARNING ogg-02544 Unhandled error (ORA-26799: 违反了唯一约束条件 TEST.DZL (表 TEST.A, 列值 ("OBJECT_ID") = (2333333))
ORA-00001: 违反唯一约束条件 (TEST.DZL)
ORA-00001: 违反唯一约束条件 (TEST.DZL)) while processing the record at SEQNO 33, RBA 3031 in Integrated mode. REPLICAT will retry in Direct mode.
2021-12-17 09:52:15 WARNING ogg-01004 Aborted grouped transaction on PDB.TEST.A, Database error 1 (OCI Error ORA-0
0001: unique constraint (TEST.DZL) violated (status = 1), SQL <INSERT INTO "TEST"."A" ("OWNER","OBJECT_NAME","SUBOBJ
ECT_NAME","OBJECT_ID","DATA_OBJECT_ID","OBJECT_TYPE","CREATED","LAST_DDL_TIME","TIMESTAMP","STATUS","TEMPORARY","GEN
ERATED","SECONDARY","NAMESPACE","EDITION_NAME") VALUES (:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14)>).
2021-12-17 09:52:15 WARNING ogg-01003 Repositioning to rba 3031 in seqno 33.
2021-12-17 09:52:15 WARNING ogg-01154 SQL error 1 mapping TEST.A to PDB.TEST.A OCI Error ORA-00001: unique constraint (TEST.DZL) violated (status = 1), SQL <INSERT INTO "TEST"."A" ("OWNER","OBJECT_NAME","SUBOBJECT_NAME","OBJECT_ID
","DATA_OBJECT_ID","OBJECT_TYPE","CREATED","LAST_DDL_TIME","TIMESTAMP","STATUS","TEMPORARY","GENERATED","SECONDARY","NAMESPACE","EDITION_NAME") VALUES (:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14)>.
报告很清晰,违反唯一约束条件。
报错处理
…然后呢,我们在目标端ogg复制进程增加HANDLECOLLISIONS参数,重启复制进程。重启复制进程的命令大家有没有忘记呢?
alter REPDEMO,begin now
然后在做相同测试:
Target:
SQL> insert into a (OBJECT_ID) values(23333332);
SQL> commit;
Source:
SQL> insert into a (OBJECT_ID) values(23333332);
SQL> commit;
去目标端进行检查,select一下
Target:
SQL> select OBJECT_ID from a where OBJECT_ID=23333332;
OBJECT_ID
----------
23333332
这样就测试完了吗?这样我们知道这个参数到底是忽略了数据冲突呢,还是将数据进行了覆盖呢,是不是不知道呀。所以我们是不是应该补充一列,观察数据是否变化呀~
Target:
SQL> insert into a (OBJECT_ID,STATUS) values(20212021,'N');
SQL> commit;
Source:
SQL> insert into a (OBJECT_ID,STATUS) values(20212021,'Y');
SQL> commit;
然后我们再到目标端进行校验,看看会是什么结果呢?
Target:
SQL> select OBJECT_ID,STATUS from a where OBJECT_ID=20212021;
OBJECT_ID STATUS
---------- -------
20212021 Y
哎,数据覆盖了!所以HANDLECOLLISIONS参数在insert情况下直观来看相当于RESOLVECONFLICT(INSERTROWEXISTS,(DEFAULT,OVERWRITE))参数。接下来,我们再测试下delete数据冲突的情况。
6.2. DELETE
报错复现
首先,删除掉目标端ogg复制进程中的HANDLECOLLISIONS参数,然后重启复制进程再进行测试。
Target:
SQL> delete from a where OBJECT_ID=20212021;
SQL> commit;
Source:
SQL> delete from a where OBJECT_ID=20212021;
SQL> commit;
查看目标端ogg复制进程状态,看看是否Abended。
GGSCI (deng2) 38> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT Abended REPDEMO 00:00:00 00:00:30
嗯,Abended了。
然后查看报告,查询Abended原因。
2021-12-17 10:26:51 WARNING ogg-02544 Unhandled error (ORA-26787: 键为 ("OBJECT_ID") = (20212021) 的行不存在 (在表TEST.A 中)
ORA-01403: 未找到任何数据) while processing the record at SEQNO 33, RBA 3838 in Integrated mode. REPLICAT will retryin Direct mode.
2021-12-17 10:26:51 WARNING ogg-01004 Aborted grouped transaction on PDB.TEST.A, Database error 1403 (No data found).
2021-12-17 10:26:51 WARNING ogg-01003 Repositioning to rba 3838 in seqno 33.
2021-12-17 10:26:51 WARNING ogg-01154 SQL error 1403 mapping TEST.A to PDB.TEST.A No data found.
很清晰的看出,源端进行delete操作同步,目标端找不到数据。
报错处理
在测试过insert数据冲突后,delete报错处理应该很简单了吧~到目标端ogg复制进程中增加HANDLECOLLISIONS参数,重启进程,再次测试。
Target:
SQL> delete from a where OBJECT_ID=2021;
SQL> commit;
Source:
SQL> delete from a where OBJECT_ID=2021;
SQL> commit;
再次查看目标端ogg中查看复制进程状态。
GGSCI (deng2) 61> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT RUNNING REPDEMO 00:00:00 00:00:04
问题是不是解决了。所以HANDLECOLLISIONS参数在delete数据冲突情况下直观上相当于resolveconflict(deleterowmissing, (default,discard))参数。
6.3. UPDATE
报错复现
首先一样的,注释掉目标端ogg复制进程中的HANDLECOLLISIONS,然后重启复制进程。进行测试:
Target:
SQL> delete from a where OBJECT_ID=111111;
SQL> commit;
Source:
SQL> select OBJECT_ID,OWNER,STATUS from a where OBJECT_ID=111111;
OBJECT_ID OWNER STATUS
---------- -------------------- --------------
111111 SYS VALID
SQL> update a set OBJECT_ID=20211202,STATUS='N' where OBJECT_ID=111111;
SQL> commit;
现在去Targetogg看一下复制进程状态,看是否Abended。
Targetogg:
GGSCI (deng2) 14> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT Abended REPDEMO 00:00:00 00:01:06
2021-12-18 09:42:41 WARNING ogg-02544 Unhandled error (ORA-26787: 键为 ("OBJECT_ID") = (111111) 的行不存在 (在表 TEST.A 中)
ORA-01403: 未找到任何数据) while processing the record at SEQNO 34, RBA 3031 in Integrated mode. REPLICAT will retryin Direct mode.
2021-12-18 09:42:41 WARNING ogg-01004 Aborted grouped transaction on PDB.TEST.A, Database error 1403 (No data found).
2021-12-18 09:42:41 WARNING ogg-01003 Repositioning to rba 3031 in seqno 34.
2021-12-18 09:42:41 WARNING ogg-01154 SQL error 1403 mapping TEST.A to PDB.TEST.A No data found.
报错目标端找不到数据,这都在预料之中。
报错处理
目标端ogg复制进程补上参数HANDLECOLLISIONS,重启复制进程。
Target:
SQL> delete from a where OBJECT_ID=20211;
SQL> commit;
Source:
SQL> select OBJECT_ID,OWNER,STATUS from a where OBJECT_ID=20211;
OBJECT_ID OWNER STATUS
---------- -------------------- --------------
20211 PUBLIC VALID
SQL> update a set OBJECT_ID=20211222,STATUS='N' where OBJECT_ID=20211;
SQL> commit;
Target:
SQL> select OBJECT_ID,OWNER,STATUS from a where OBJECT_ID=20211222;
OBJECT_ID OWNER STATUS
---------- ------------------------------ -------
20211222 PUBLIC N
哎,也处理好了!
那不是一个HANDLECOLLISIONS参数就解决了所有数据冲突问题了吗?为啥Oracle官方却对这个参数不是很待见呢,给出的建议是一般情况不要使用呢?
接下来我们来测试下无主键,无唯一索引的表test,看看这个参数到底有没有这么神。
6.4. HANDLECOLLISIONS弊端
6.4.1.数据重复
同样的,在目标端insert一条数据,模拟insert数据冲突,
Target:
SQL> select * from test;
ID NAME
---------- --------------------
1 mb
2 dzl
3 rf
4 111
Source:
SQL> select * from test;
ID NAME
---------- ----------------------------------------
4 111
1 mb
2 dzl
3 rf
Target:
SQL> insert into test values(5,'222');
SQL> commit;
Source:
SQL> insert into test values(5,'333');
SQL> commit;
这时,根据我们的经验,在目标端查询这个表中ID=5时,NAME的值应该是333,因为HANDLECOLLISIONS参数如果发生insert数据冲突,则会将源端插入的数据覆盖到目标端上。但事实真的如此吗?我们查询下目标端test表中ID=5时,NAME的值。
Target:
SQL> select * from test where ID=5;
ID NAME
---------- --------------------
5 222
5 333
为什么有两行呢?不应该像OVERWRITE参数一样用333替代222吗?
这不行的呀!这个测试说明这参数不经意间会造成数据重复!并且ogg并不给出报错或者提示!
参考链接:https://blog.csdn.net/oradbm/article/details/52104886?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-4.no_search_link&spm=1001.2101.3001.4242.3
上面博客详细写了HANDLECOLLISIONS作用以及弊端。
-
对于没有主键以及唯一索引的表
对于update缺失行情况,目标端会转化为insert语句进行插入。
对于delete缺失行情况,目标会会忽略操作。
对于insert发现重复行情况,目标端会仍然进行插入操作。(导致数据重复) ----不受HANDLECOLLISIONS参数影响,继续插入 -
对于存在主键
对于update缺失行情况,且抓取进程不使用FETCHOPTIONS FETCHPKUPDATECOLS参数,更新主键则目标端转化为insert操作,如果未更新主键则忽略。
对于delete缺失情况,则忽略,
对于insert发现重复行情况,转化成update语句,将重复列更新主键值为原来插入主键值。 -
对于存在唯一值索引
对于update缺失行情况,目标端会转化为insert语句进行插入。
对于delete缺失行情况,目标会会忽略操作。
对于insert发现重复行情况,目标端执行先delete操作然后再insert。
6.4.2.主键列镜像丢失
上述博客5.1.2.2中提到了这个FETCHOPTIONS FETCHPKUPDATECOLS参数。是不是很眼熟,没错,大家还记得这个参数是谁的吗?是ogg抽取进程参数。但这个参数在此处的作用与之前的作用是不同的噢!如果目标端ogg使用HANDLECOLLISIONS参数,则造成目标端更新数据会丢失非主键列的镜像。这个时候若要保证主键列在目标端更新成功,则需要在源端ogg抽取进程中添加参数FETCHOPTIONS FETCHPKUPDATECOLS。并且若要达到这个效果,该参数必须与目标端ogg复制进程HANDLECOLLISIONS一起使用才能生效噢!
小结:HANDLECOLLISIONS参数虽然能解决ogg目标端复制进程Abended的问题,但是可能会造成更严重的数据重复问题。我们不可能每次做数据迁移的时候都去查询该表是否存在主键,是否存在唯一索引;我们更不可能通过一个参数来控制insert/delete/update三种操作处理,这样太不灵活了。所以我们应该多使用本篇文档5.1-5.3介绍的参数,每一个参数都相对应一种操作,由此来进行数据冲突的控制。
7、总结
- 在使用ogg对Oracle数据库进行数据同步时,源端记得开启表级最小补充日志。
- 遇到数据冲突时,可以考虑上面讲到的参数,避免目标端复制进程Abended。
- HANDLECOLLISIONS参数一般情况不要使用,会造成数据重复的现象。
- 若目标端ogg复制进程使用了HANDLECOLLISIONS参数的情况下,源端ogg抽取进程要添加FETCHOPTIONS FETCHPKUPDATECOLS参数,由此保证主键列在目标端更新成功。




