首页 » OceanBase, ORACLE 9i-23ai » Oracle Logminer中的invalid row_id “AAAAAAAAAAAAAAAAAA”

Oracle Logminer中的invalid row_id “AAAAAAAAAAAAAAAAAA”

最近有个客户在做迁移oracle到Oceanbase时,使用的是原厂的OMS数据迁移同步工具,在迁移或数据同步完数据库发现数据存在差异, 应该是一种基于logminer的log stream形式,发现一张表含有Lob字段在logminer的视图中对应的rowid只有update,没有insert, 经过事务xid的查找发现insert所对应的是ROW_ID为”AAAAAAAAAAAAAAAAAA”,显然这是一个无效的rowid, 如果是基于rowid那同步数据就可能丢失了。我发现oracle11g和23c这方面还有点差异,简单记录。

环境11.2.0.4

create table anbob.TEST_LOG
(
id number
, fullname varchar2(50)
, age number
, description clob
);

CREATE TABLE anbob.TEST (
  ID INTEGER,
  COL1 VARCHAR2(4000),
  COL2 INTEGER
);

select dbms_flashback.get_system_change_number from dual;

insert into anbob.TEST_LOG(id,fullname,age) values(1,'anbob builder',35);

update  anbob.TEST_LOG set description=to_clob('anbob.com') where id=1;

INSERT INTO anbob.TEST_LOG(id,fullname,age,description) values(2,'anbob builder',35, DBMS_RANDOM.STRING('U', 10));
commit;

INSERT INTO anbob.TEST (ID, COL1, COL2) VALUES (0, 'TEXT', 1);

commit;

select dbms_flashback.get_system_change_number from dual;

exec DBMS_LOGMNR.ADD_LOGFILE('+DATA/rac11g/onlinelog/group_2.261.1164470467', DBMS_LOGMNR.NEW);

EXECUTE DBMS_LOGMNR.START_LOGMNR(STARTSCN=>24334811738, ENDSCN=>24334811859, -
OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG +  -
DBMS_LOGMNR.COMMITTED_DATA_ONLY + DBMS_LOGMNR.NO_ROWID_IN_STMT + DBMS_LOGMNR.NO_SQL_DELIMITER);

Note:

创建了一个包含lob的表test_lob和一个不含LOB的test表做为对比。

查看操作日志

SQL> r
  1  SELECT
  2  scn,start_scn,timestamp,xid,operation,table_name, row_id,sql_redo
  3  FROM V$LOGMNR_CONTENTS
  4  where SEG_OWNER='ANBOB' OR XID in('BD0B0400E0210000','C10B180009220000')
  5* ORDER BY 1 asc

            SCN       START_SCN TIMESTAMP           XID              OPERATION       TABLE_NAME      ROW_ID                               SQL_REDO
--------------- --------------- ------------------- ---------------- --------------- --------------- ------------------------------------ ----------------------------------------------------------------------
    24334811772     24334811772 2024-11-22 16:52:21 C10B180009220000 START                           AAAAAAAAAAAAAAAAAA                   set transaction read write
    24334811772     24334811772 2024-11-22 16:52:21 C10B180009220000 INSERT          TEST_LOG       AAAAAAAAAAAAAAAAAA                   insert into "ANBOB"."TEST_LOG"("ID","FULLNAME","AGE","DESCRIPTION") v
                                                                                                                                          alues ('1','anbob builder','35',EMPTY_CLOB())

    24334811774     24334811772 2024-11-22 16:52:21 C10B180009220000 UPDATE          TEST_LOG       AAAd5rAAEAAEXYdAAA                   update "ANBOB"."TEST_LOG" set "DESCRIPTION" = NULL where "ID" = '1' a
                                                                                                                                          nd "FULLNAME" = 'anbob builder' and "AGE" = '35'

    24334811781     24334811772 2024-11-22 16:52:27 C10B180009220000 UPDATE          TEST_LOG       AAAAAAAAAAAAAAAAAA                   update "ANBOB"."TEST_LOG" set "DESCRIPTION" = EMPTY_CLOB() where "ID"
                                                                                                                                           = '1' and "FULLNAME" = 'anbob builder' and "AGE" = '35'

    24334811782     24334811772 2024-11-22 16:52:27 C10B180009220000 UPDATE          TEST_LOG       AAAd5rAAEAAEXYdAAA                   update "ANBOB"."TEST_LOG" set "DESCRIPTION" = 'anbob.com' where "ID"
                                                                                                                                          = '1' and "FULLNAME" = 'anbob builder' and "AGE" = '35'

    24334811814     24334811772 2024-11-22 16:52:53 C10B180009220000 INSERT          TEST_LOG       AAAAAAAAAAAAAAAAAA                   insert into "ANBOB"."TEST_LOG"("ID","FULLNAME","AGE","DESCRIPTION") v
                                                                                                                                          alues ('2','anbob builder','35',EMPTY_CLOB())

    24334811814     24334811772 2024-11-22 16:52:53 C10B180009220000 UPDATE          TEST_LOG       AAAd5rAAEAAEXYdAAB                   update "ANBOB"."TEST_LOG" set "DESCRIPTION" = 'BESVGEYSJO' where "ID"
                                                                                                                                           = '2' and "FULLNAME" = 'anbob builder' and "AGE" = '35'

    24334811820     24334811772 2024-11-22 16:52:59 C10B180009220000 COMMIT                          AAAAAAAAAAAAAAAAAA                   commit
    24334811847     24334811847 2024-11-22 16:53:08 BD0B0400E0210000 START                           AAAd5uAAAAAAAAAAAA                   set transaction read write
    24334811847     24334811847 2024-11-22 16:53:08 BD0B0400E0210000 INSERT          TEST            AAAd5uAAEAAEXY9AAA                   insert into "ANBOB"."TEST"("ID","COL1","COL2") values ('0','TEXT','1')
    24334811851     24334811847 2024-11-22 16:53:11 BD0B0400E0210000 COMMIT                          AAAAAAAAAAAAAAAAAA                   commit

11 rows selected.

Note:
1,对于事务操作start,commit,rollback 对应的rowid 都是AAAAAAAAAAAAAAAAAA
2,  对于lob列的insert 不带lob col分自动分为2条,先insert lobcol= EMPTY_CLOB(),  再update lobcol=null, 第1个insert  row_id=AAAAAAAAAAAAAAAAAA
3,  对于lob列的update同样分为2条, 先update lobcol= EMPTY_CLOB(),  再update lobcol=具体值, 第1个update  row_idAAAAAAAAAAAAAAAAAA
4,对于clob列的insert 带lob col分自动分为2条,先insert lobcol= EMPTY_CLOB(),  再update lobcol=null,第1个insert  row_id=AAAAAAAAAAAAAAAAAA
5,  并不是所有insert 对应的rowid都是AAAAAAAAAAAAAAAAAA, 对于不含lob的表 insert row_id为实际rowid.

Oralce 23c 测试

create table anbob.testtable
   (
   id number
, fullname varchar2(50)
   , age number
   , description clob
   );

Table created.

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER
------------------------
               820499821

SQL> insert into anbob.testtable(id,fullname,age) values(1,'anbob builder',35);
1 row created.

SQL> update  anbob.testtable set description=to_clob('anbob.com') where id=1;
1 row updated.

SQL> commit;
Commit complete.

SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
               820500013

SQL>EXECUTE DBMS_LOGMNR.START_LOGMNR(STARTSCN=>820499821, ENDSCN=>820500013, -
 OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG +  -
 DBMS_LOGMNR.COMMITTED_DATA_ONLY + DBMS_LOGMNR.NO_ROWID_IN_STMT + DBMS_LOGMNR.NO_SQL_DELIMITER);

PL/SQL procedure successfully completed.

NOTE:
1, 23c不支持ORA-44609: CONTINOUS_MINE is desupported for use with DBMS_LOGMNR.START_LOGMNR.
2, 23c这里并没有做DBMS_LOGMNR.ADD_LOGFILE,看来已经可以自动查找

查看23c的logminer日志

SELECT
  scn,start_scn,timestamp,xid,operation,table_name, row_id,sql_redo
  FROM V$LOGMNR_CONTENTS
  where SEG_OWNER='ANBOB' OR XID='0A0020004CC60200'
  ORDER BY xid asc,sequence# asc
  /

       SCN  START_SCN TIMESTAMP           XID              OPERATION                        TABLE_NAME                     ROW_ID             SQL_REDO
---------- ---------- ------------------- ---------------- -------------------------------- ------------------------------ ------------------ ----------------------------------------
 820499858  820499858 2024-11-23 00:18:37 0A0020004CC60200 START                                                           AAAsPAAAAAAAAAAAAA set transaction read write
 820499858  820499858 2024-11-23 00:18:37 0A0020004CC60200 INSERT                           TESTTABLE                      AAAsPAAAdAAAKc8AAA insert into "ANBOB"."TESTTABLE"("ID","FU
                                                                                                                                              LLNAME","AGE","DESCRIPTION") values ('1'
                                                                                                                                              ,'anbob builder','35',NULL)

 820499988  820499858 2024-11-23 00:19:04 0A0020004CC60200 UPDATE                           TESTTABLE                      AAAsPAAAdAAAKc8AAA update "ANBOB"."TESTTABLE" set "DESCRIPT
                                                                                                                                              ION" = 'anbob.com' where

 820500008  820499858 2024-11-23 00:19:12 0A0020004CC60200 COMMIT                                                          AAAAAAAAAAAAAAAAAA commit

Note:
在23c中默认对于含有lob的列表DML并没有拆分为2条,没有先EMPTY_CLOB()。

注意: 对于基于日志的数据同步,还是要研究数据库不同版本的日志内容变化,这里11g和23c的不同还隐藏一个11g使用的是basefile,而23c是SECUREFILE, 和存储属性是否有没有关系?12c和19c又是什么样?时间关系请自行测试。

 

 

还有更多异构数据迁移问题隐藏在项目中,如果您有国产化改造咨询需求,可以考虑联系我们(www.anbob.com首页的联系方式)

打赏

, , ,

目前这篇文章还没有评论(Rss)

我要评论