actiontech/dtle

Data types and values that affect full dump

LordofAvernus opened this issue · 6 comments

Data types and values that affect full dump

全量同步导致同步停止的数据类型

  • BINARY_DOUBLE 特殊类型值问题 fixed

       inf -inf nan
       增量过程将几个数值转换为NULL
    
  • DATE 时间格式问题 fixed

      replace into `TEST`.`DATE_COLUMNS`  values ('0',NULL),('1','0001-01-01T00:00:00Z'),('2','9999-12-31T00:00:00Z'),('3','2022-02-21T21:02:44Z')
    
  • TIMESTAMP 类型 fixed

       Error 1292: Incorrect datetime value: '0001-01-01T00:00:00Z' 时间格式. replace into `TEST`.`TIMESTAMP_COLUMNS`  
       values ('0',NULL),('1','0001-01-01T00:00:00Z'),('2','9999-12-31T23:59:59.999999999Z'),('3','2022-07- 
      04T18:30:25.650293Z'),('4','2022-07-04T18:30:25.659959Z'),('5','2022-07-04T10:30:25.670223Z'),('6','2022-02- 
     21T10:1
    
  • INTERVAL_DAY 时间格式问题 ignore

       driver 读取边界值数据异常,
       oracle 插入 SQL:  INSERT INTO TEST.INTERVAL_DAY_COLUMNS VALUES (2, INTERVAL '-999999999 23:59:59.999999999' DAY(9)    TO SECOND(9));
       MySQL插入 SQL: replace into `TEST`.`INTERVAL_DAY_COLUMNS`  values  ('2','+3294967297 233:197:197.3294967')
    
  • 数值类型的 9999999.99999 都失败了 fixed

       DECIMAL_COLUMNS,NUMBER_38_COLUMNS,DEC_COLUMNS 等
      Driver 查询不在int64范围内的数值(-9223372036854775808 ~ 9223372036854775807),结果会以float格式显示,丢失精度并且使用科学记数法返回,导致MySQL端无法插入科学记数法数据(1e28)
    
  • LONG 源端抽取不支持 ignore

     语法不支持: ORA-00997: illegal use of LONG datatype
     不考虑支持
    

超过int64长度的数值类型同步问题

  1. 方案

    当前使用的go-ora驱动数值类型的查询结果,均使用了int64来保存,当数值类型过大/过小时,无法同步正确数据.
    使用其他driver, 将"github.com/sijms/go-ora/v2" 替换为"github.com/godror/godror"
    
  2. 测试结论

    由于godror使用string来保存query number double等数值类型的结果,对于超过int64极限值以及小数位较多的数据都能正常保存。
    
  3. 遗留问题

     INTERVAL_DAY,INTERVAL_YERAR存在问题,驱动对于该类型的查询不够友好,存在一些问题
     例如:
        `INTERVAL_YERAR 类型-999999999-11 结果显示为 -999999999--11`
        `INTERVAL_DAY 同步结果直接以time.duration值展示,并且该类型受到int64长度限制,所以对于时间段过长的数据,依然会出现显示错误问题.`
    
  4. 特别关注点:

    godror连接Oracle 需要安装Oracle Full Client或Instant Client
    [驱动程序](https://www.oracle.com/database/technologies/instant-client/downloads.html)
    

 字符类型null值错误

CREATE TABLE ACTION_DB.CHAR_255_COLUMNS(col1 INT, col2 CHAR(255))
CREATE TABLE ACTION_DB.CHAR_2000_COLUMNS(col1 INT, col2 CHAR(2000))
CREATE TABLE ACTION_DB.CHARACTER_255_COLUMNS(col1 INT, col2 CHARACTER(255))
CREATE TABLE ACTION_DB.CHARACTER_2000_COLUMNS(col1 INT, col2 CHARACTER(2000))
CREATE TABLE ACTION_DB.NCHAR_255_COLUMNS(col1 INT, col2 NCHAR(255))
CREATE TABLE ACTION_DB.NCHAR_1000_COLUMNS(col1 INT, col2 NCHAR(1000))
CREATE TABLE ACTION_DB.NCHAR_VARYING_COLUMNS(col1 INT, col2 NCHAR VARYING(2000))
CREATE TABLE ACTION_DB.NVARCHAR2_COLUMNS(col1 INT, col2 NVARCHAR2(2000))
CREATE TABLE ACTION_DB.VARCHAR_COLUMNS(col1 INT, col2 VARCHAR(4000))
CREATE TABLE ACTION_DB.VARCHAR2_COLUMNS(col1 INT, col2 VARCHAR2(4000))

oracle
INSERT INTO ACTION_DB.CHAR_255_COLUMNS VALUES (0, NULL);
MySQL全量(实际)
'COL2': ‘’
MySQL增量(预期)
'COL2': null

目标端数据类型错误
oracle建表

CREATE TABLE ACTION_DB.INTEGER_COLUMNS(col1 INT, col2 INTEGER)
CREATE TABLE ACTION_DB.INT_COLUMNS(col1 INT, col2 INT)

MySQL 验证:

SELECT DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, DATETIME_PRECISION FROM COLUMNS WHERE TABLE_SCHEMA='ACTION_DB' AND TABLE_NAME='<oracle_type>' AND COLUMN_NAME='COL2';

MySQL全量(实际)
{'DATA_TYPE': 'double', 'CHARACTER_MAXIMUM_LENGTH': None, 'NUMERIC_PRECISION': 22, 'NUMERIC_SCALE': None, 'DATETIME_PRECISION': None}
MySQL增量(预期)
('DATA_TYPE', 'int'), ('CHARACTER_MAXIMUM_LENGTH', None), ('NUMERIC_PRECISION', 10), ('NUMERIC_SCALE', 0), ('DATETIME_PRECISION', None)


CREATE TABLE ACTION_DB.SMALLINT_COLUMNS(col1 INT, col2 SMALLINT)

MySQL全量(实际)
{'DATA_TYPE': 'double', 'CHARACTER_MAXIMUM_LENGTH': None, 'NUMERIC_PRECISION': 22, 'NUMERIC_SCALE': None, 'DATETIME_PRECISION': None}
MySQL增量(预期)
('DATA_TYPE', 'decimal'), ('CHARACTER_MAXIMUM_LENGTH', None), ('NUMERIC_PRECISION', 38), ('NUMERIC_SCALE', 0), ('DATETIME_PRECISION', None)]

INTERVA_xxx数据错误

CREATE TABLE ACTION_DB.INTERVAL_YEAR_COLUMNS(col1 INT, col2 INTERVAL YEAR(9) TO MONTH)
CREATE TABLE ACTION_DB.INTERVAL_DAY_COLUMNS(col1 INT, col2 INTERVAL DAY(9) TO SECOND(9))
INSERT INTO ACTION_DB.INTERVAL_YEAR_COLUMNS VALUES (1, INTERVAL '999999999-11' YEAR(9) TO MONTH)

MySQL全量(实际)
'COL2': '999999999-11'
MySQL增量(预期)
'COL2': '+999999999-11'

INSERT INTO ACTION_DB.INTERVAL_DAY_COLUMNS VALUES (1, INTERVAL '999999999 23:59:59.999999999' DAY(9) TO SECOND(9))

MySQL全量(实际)
'COL2': '-4549241255539769345'
MySQL增量(预期)
'COL2': '+999999999 23:59:59.999999999'

  1. INTERVA_xxx类型未能完全支持(受限于godror driver)
  2. INT/INTEGER/SMALLINT 由于oracle内部存储结构为number,当前的获取建表语句得到的结果 无法与真正执行的建表语句一致.故同步的表结构与增量有差异(增量从日志读取的建表语句,基本与真实建表语句一致).
  3. 字符类型的的NULL值与空值,需要额外判断,已处理
    https://actiontech.github.io/dtle-docs-cn/5/5.4_columns_mapping.html