有客户发现LOGMINER出来的UPDATE语句与生产端的原语句差别比较大,比如下面的语句,原语句是:
UPDATE F_XXX_BACKUP SET TALLY_REMARK = 'WIAO' WHERE ACCT_ID = :B1
而目标端从从archive log中解析出来sql_redo的语句变成了,源语句中的ACCT_ID条件没有了,反而多了BACKUP_ID等条件:
update "XXPAY"."F_XXX_BACKUP" set"TALLY_REMARK" = 'WIAO' where "BACKUP_ID" = '000000154720'and "TALLY_REMARK" = 'WIAO' and ROWID = 'AAAL8YAAKAAA9y2AAe';
问题分析
在源端,一条UPDATE语句可能是通过某个过滤条件进行的,而在逻辑复制环境下,不同数据库的ROWID是不同的,因此ROWID不能作为复制的唯一性约束条件。在这种情况下,如果UPDATE的表上面有PK,那么就会通过PK来复制数据。对于没有PK的环境,可以通过SUPPLEMENTAL LOGING指定的信息来实现唯一性约束。从表定义来看:

在表中ACCT_ID并不是唯一性的键值,因此
UPDATE F_XXX_BACKUP SET TALLY_REMARK = 'WIAO'WHERE ACCT_ID = :B1
这条语句可能修改1条或者多条数据库记录。而在REDO中记录的并不是SQL语句,而是在某条数据上的变更矢量。因此一条UPDATE语句,可能对应LOGMINER出来的多条记录。每条记录中包含的信息包括表名、SET列表中的OLD和NEW值,以及作为SUPPLEMENTAL LOG的的BACKUP_ID。在LOGMINER复原REDO语句的时候就会变成:
update "SFPAY"."F_XXX_BACKUP" set "TALLY_REMARK"= 'WIAO' where "BACKUP_ID" = '000000154720' and "TALLY_REMARK" = 'WIAO' and ROWID = 'AAAL8YAAKAAA9y2AAe';




