文档中心MogDBMogDB StackUqbar

文档:v2.0

支持的版本:

使用MTK迁移Informix到openGauss/MogDB

下载带DB2字样的程序包进行迁移

支持版本

  • 12.10

驱动

Informix ODBC(CSDK)

不支持。未适配成功。

DB2 ODBC

支持。参考DB2

Port allow remote connections from DRDA clients

注意事项

空字符串和NULL问题

空字符串和NULL问题,Informix NULL != ''

  • openGauss A 模式下和 Informix 不一样,需要处理数据。当列的属性为 not null 时转为" ",允许为 NULL 时转为 NULL

  • openGauss PG 模式下和 Informix 一样,NULL != '' 无需处理;

  • openGauss B 模式下和 Informix 一样,NULL != '' 无需处理。

序列

informix 的序列是一张表,只是表上只有一个自增列

  • 最后值

    无法批量获取最后值。为保证性能没有遍历序列获取current值。批量获取最后的cache值,所以迁移后会比之前大。

  • 分区表不支持,只能迁移为普通表;
  • 外部表不支持;
  • 统一处理为bigint类型加默认序列,并调整序列开始值为源库最后值。

表数据

  • 支持中文,UTF8字符集

    # jdbc 中文字符测试
    jdbc:informix-sqli://localhost:19088/sysadmin:INFORMIXSERVER=dev;NEWCODESET=utf8,8859-1,819;CLIENT_LOCALE=en_US.utf8;DB_LOCALE=en_US.utf8;

列对应

Informix column type DB Length SCALE openGauss column type data_precision data_scal
BIGINT 0 0 bigint 0 0
BIGSERIAL 0 0 bigint + sequence.nextval 0 0
BLOB 0 0 bytes/blob 0 0
BOOLEAN 0 0 bool 0 0
BYTE 0 0 bytes/blob 0 0
CHAR 10 0 char 10 0
VARCHAR 10 0 VARCHAR 10 0
CLOB 0 0 text/clob 010 0
DATE 10 0 date 0 0
DATETIME 4879 0 timestamp 0 0
DECIMAL 16 255 numeric 32 16
FLOAT 17 0 float 0 0
FLOAT 17 0 float 0 0
INT8 19 0 INT8 0 0
INTEGER 10 0 INTEGER 0 0
INTERVAL 1350 0 INTERVAL 0 0
LVARCHAR 100 0 VARCHAR 0 0
MONEY 16 2 MONEY 0 0
NVARCHAR 100 2 VARCHAR 0 0
SMALLFLOAT 7 2 float 0 0
SMALLINT 0 0 SMALLINT 0 0
TEXT 0 2 TEXT 0 0
VARCHAR 100 2 VARCHAR 100 0
BSON 0 0 不支持 0 0
VARIABLE U 0 0 不支持 0 0
IDSSECURIT 0 0 不支持 0 0
IDSSECURITYLABEL 0 0 不支持 0 0
OPAQUE 0 0 不支持 0 0
DISTINCT 0 0 不支持 0 0
LIST 0 0 不支持 0 0
MULTISET 0 0 不支持 0 0
ROW 0 0 不支持 0 0
Named ROW 0 0 不支持 0 0

datetime/interval 类型存在多种组合方案。部分组合方案存在数据问题

datetime/interval 具体类型根据公式 (length * 256) + (first_qualifier * 16) + last_qualifier 反推计算得出 syscolumns-storing-column-length

interval first_qualifier 的精度根据具体 Field qualifier的长度反推计算得出

BIGSERIAL

openGauss统一处理为bigint类型加默认序列

DATETIME

  • 具体毫米级精度无法计算得出。会寻找解决方案

  • month/day/hour/minute/second/fraction to x 非完整时间类型

    • datetime hour to second 02:00:00

    • datetime month to day

      在 informix 可以存储年份数据,展示为 05-27,迁移到 openGauss timestamp 类型会变成 1200-05-27 00:00:00

DECIMAL

  • DECIMAL(p) Floating Point

    未指定precision的时候默认是16。可以插入总长度为16的浮点数。openGauss/MogDB不支持这种。

    scale 默认为 255,是特殊数据。

    Specifying precision is optional.

    If you specify no precision (p), DECIMAL is treated as DECIMAL(16), a floating-point decimal with a precision of 16 places.

    DECIMAL(p) has an absolute exponent range between 10-130 and 10124.

    DECIMAL --> DECIMAL(16) --> DECIMAL(32,16) ?

    • informix

      drop table tab_decimal;
      create table tab_decimal (
          col_decimal decimal,
          col_decimal_16 decimal(16),
          col_decimal_17 decimal(17),
          col_decimal_16_0 decimal(16,0),
          col_decimal_17_0 decimal(17,0),
          col_decimal_30_20 decimal(30,20),
          col_decimal3_2 decimal(3,2)
      );
      insert into tab_decimal values (1234567891011121.12345678910111213,1234567891011121.12345678910111213,1234567891011121.12345678910111213,1234567891011121.12345678910111213,1234567891011121.12345678910111213,1234567890.12345678910111213,1.23);
      insert into tab_decimal values (1.12345678910111213,1.12345678910111213,1.12345678910111213,1234567890.12345678910111213,1.12345678910111213,1234567890.12345678910111213,1.23);
      insert into tab_decimal values (12345678.12345678,12345678.12345678,12345678.12345678,1234567890.12345678910111213,12345678.12345678,1234567890.12345678910111213,1.23);
      insert into tab_decimal values (123456789.12345678,123456789.12345678,123456789.12345678,1234567890.12345678910111213,123456789.12345678,1234567890.12345678910111213,1.23);
      select * from tab_decimal;
    • openGauss

      CREATE TABLE mtk.tab_decimal (
          col_decimal DECIMAL(32,16),
          col_decimal_16 DECIMAL(32,16),
          col_decimal_17 DECIMAL(34,17),
          col_decimal_16_0 DECIMAL(16),
          col_decimal_17_0 DECIMAL(17),
          col_decimal_30_20 DECIMAL(30,20),
          col_decimal3_2 DECIMAL(3,2)
      )
  • DECIMAL (p,s) Fixed Point

    和 openGauss/MogDB一致。

INTERVAL

  • 存在 interval 类型在报告里展示不准的场景

    interval day(8) to day 这种类型可能存在显示不准情况。

  • interval second to fraction

    在Informix展示为 120.010,迁移到openGauss后,interval类型会变成 00:02:00.010

    MTK根据标准的 interval day to second 格式00 00:00:00.000进行数据转换。

MONEY

未指定precision的时候默认是16.2。可以插入总长度为16的浮点数。openGauss/MogDB不支持指定精度。可用DECIMAL替代,存在四舍五入问题。

  • informix

    create table tab_money (
        col_money      money,
        col_money_30_20 money(30,20),
        col_money_2    money(3,2)
    );

    Unlike the DECIMAL data type, the MONEY data type is always treated as a fixed-point decimal number.

    The database server defines the data type MONEY(p) as DECIMAL(p,2).

    If the precision and scale are not specified, the database server defines a MONEY column as DECIMAL(16,2).

  • openGauss

    CREATE TABLE mtk.tab_money (
        col_money      money NULL,
        col_money_30_20 money NULL,
        col_money_2    money NULL
    )

列默认值

  • 列默认存在问题。只支持部分语法转换迁移;

  • interval 列默认值;

  • datetime 列默认值;

    • current --> current_timestamp

    • datetime hour to second '08:00:00' 非正常时间默认不会被迁移

      tk_start_time datetime hour to second default  datetime (08:00:00) hour to second  --> tk_start_time timestamp

索引

  • 不支持函数索引

约束

  • 检查约束存在语法转换问题

    ALTER TABLE mtk.tab_ph_task1 ADD CONSTRAINT CHECK ((tk_name [1,1] != ' ' )) CONSTRAINT c271_149;
    -- (?is)interval\s*\(\s*([^\(\),]+)\)\s+(YEAR|MONTH|DAY|HOUR|MINUTE|SECOND|FRACTION)\s+TO\s+(YEAR|MONTH|DAY|HOUR|MINUTE|SECOND|FRACTION\(\d+\))
    ALTER TABLE mtk.tab_ph_task1 ADD CONSTRAINT CHECK ((tk_frequency > interval(  0 00:00:00) day to second )) CONSTRAINT tab_ph_task1_constr2

视图

  • 无语法转换迁移

函数

  • 只查询不支持语法转换

存储过程

  • 只查询不支持语法转换

触发器

  • 只查询不支持语法转换

同义词

部分SQL语句

系统视图

  • systables 表/序列/视图
    • 分区表自增列的值在第一个分区上记录,不在表上记录
  • syscolumns 列信息
  • syssequences 序列
  • sysmaster:sysactptnhdr 序列最后值
  • sysmaster:sysptnhdr 序列最后值 table contains information about partition headers
  • sysfragments 分区
  • sysdbspaces 表空间
  • sysmaster:sysptnext 表空间相关
  • sysconstraints 约束
  • sysobjstate 对象状态
  • sysreferences 外键约束
  • syschecks 检查约束
  • sysviews 视图
  • SYSSYNTABLE 同义词关系表
  • systriggers 触发器
  • systrigbody 触发器定义表
  • sysprocedures 存储过程/函数
  • sysprocbody 存储过程/函数定义

序列信息

-- 一个序列为一个表,此表只含有自增列
-- 表中含有自增列也当作序列进行查询
-- 序列的最后值为最后的cache值
-- 分区表自增列的信息在第一个分区上
SELECT T.OWNER
    , T.TABNAME
    , T.TABID
    , C.COLNAME
    , T.PARTNUM
    , INFORMIX.SCHEMA_COLTYPENAME(C.COLTYPE, C.EXTENDED_ID)::VARCHAR(10) COLTYPENAME
    , NVL(S.SEQID, 0) as SEQID
    , NVL(S.START_VAL, 1) as START_VAL
    , NVL(S.INC_VAL, 1)   as INC_VAL
    , NVL(S.MIN_VAL, 1)   as MIN_VAL
    , nvl(S.MAX_VAL, '')  as MAX_VAL
    , NVL(S.cycle, 0)     as cycle
    , NVL(S.cache, 1)     as cache
    , NVL(S.order, 1) as order
    -- D.CUR_SERIAL4
    , D.SERIALV as CUR_SERIAL4
    , D.CUR_SERIAL8
    , D.CUR_BIGSERIAL
    --,T.PARTNUM,F.PARTN,DECODE(T.PARTNUM,0,F.PARTN,T.PARTNUM)
FROM
  INFORMIX.SYSCOLUMNS C
  JOIN INFORMIX.SYSTABLES T ON C.TABID = T.TABID
LEFT JOIN INFORMIX.SYSFRAGMENTS F ON F.TABID = T.TABID AND F.EVALPOS=0 AND F.FRAGTYPE='T'
LEFT JOIN INFORMIX.SYSSEQUENCES S ON T.TABID=S.TABID
-- LEFT JOIN SYSMASTER:SYSACTPTNHDR D ON DECODE(T.PARTNUM,0,F.PARTN,T.PARTNUM) =D.PARTNUM
LEFT JOIN SYSMASTER:SYSPTNHDR D ON DECODE(T.PARTNUM,0,F.PARTN,T.PARTNUM) =D.PARTNUM
WHERE
  INFORMIX.SCHEMA_ISAUTOINCR(C.COLTYPE)= 'YES'
  and t.tabtype in ('T', 'Q');

表信息

select t.tabid,
       t.owner,
       t.tabname,
       c.name,
       --t.partnum,
       --t.rowsize,
       --t.ncols,
       t.nrows,
       --t.npused,
       -- d.cur_serial4,
       d.serialv as cur_serial4,
       d.cur_serial8,
       d.cur_bigserial,
       f.strategy,
       f1.exprtext,
       f2.strategy,
       f2.exprtext
from INFORMIX.SYSTABLES t
left join informix.sysfragments f on f.tabid = t.tabid and f.evalpos = -3 and F.FRAGTYPE = 'T'
left join informix.sysfragments f1 on f1.tabid = t.tabid and f1.evalpos = -2 and F1.FRAGTYPE = 'T'
left join informix.sysfragments f2 on f2.tabid = t.tabid and f2.evalpos = 0 and F2.FRAGTYPE = 'T'
-- left join sysmaster:sysactptnhdr d on d.partnum = DECODE(t.partnum,0,f2.partn,t.partnum)
left join sysmaster:sysptnhdr d on d.partnum = DECODE(t.partnum,0,f2.partn,t.partnum)
-- left join sysmaster:sysptnext pt on t.partnum=pt.pe_partnum
left join sysmaster:sysdbspaces c on sysmaster:partdbsnum(t.partnum)= c.dbsnum
where
  t.tabtype = 'T'

列信息

select
    t.owner,
    t.tabname,
    c.colno,
    c.colname,
    informix.schema_isautoincr(coltype) auto_increment,
    informix.schema_nullable(coltype)   nullable,
    informix.schema_coltypename(c.coltype, c.extended_id)::varchar(10) coltypename, informix.schema_precision(c.coltype,c.extended_id,c.collength) precision,
    informix.schema_numscale(c.coltype,c.collength) numscale,
    -- informix.schema_datetype(c.coltype,c.collength) datetype,
    -- pt.cur_serial4,
    pt.serialv as cur_serial4,
    pt.cur_serial8,
    pt.cur_bigserial,
    d.type,
    d.default
from
  informix.syscolumns c
join informix.systables t on c.tabid = t.tabid
left join informix.sysdefaults d on c.tabid = d.tabid and c.colno = d.colno
left join informix.sysfragments f on f.tabid = t.tabid and f.evalpos=0 and f.fragtype='T'
-- left join sysmaster:sysactptnhdr pt on decode(t.partnum,0,f.partn,t.partnum) =pt.partnum
left join sysmaster:sysptnhdr pt on decode(t.partnum,0,f.partn,t.partnum) =pt.partnum
where c.colno > 0

索引信息

-- 函数索引没有找到列信息
-- SYSINDICES.indexkeys
-- <procid>(colno,colno)[opclassid],<procid>(colno,colno)[opclassid] --> 5 [1], <661>(2, 4) [1]
-- procid 可为空. colno [opclassid] --> 2 [1], 1 [1]
-- desc (tk_name desc,tk_type desc); -2 [1], -4 [1]
-- (tk_name desc,toupper1(tk_name,tk_type) desc  -2 [1], <661>(-2, 4) [1]
select t.tabid,t.owner,t.tabname,i.owner as idxowner,i.idxname,
    i.idxtype,
    i.clustered,
    c.colname,
    i.part1,
    i.part2,
    i.part3,
    i.part4,
    i.part5,
    i.part6,
    i.part7,
    i.part8,
    i.part9,
    i.part10,
    i.part11,
    i.part12,
    i.part13,
    i.part14,
    i.part15,
    i.part16
from sysindexes i join systables t on t.tabid = i.tabid
left join syscolumns c on c.tabid = i.tabid
and c.colno in (abs(part1), abs(part2), abs(part3), abs(part4), abs(part5), abs(part6), abs(part7), abs(part8), abs(part9), abs(part10),abs(part11), abs(part12), abs(part13), abs(part14), abs(part15), abs(part16))
where not exists (
    select
        c.idxname
    from
        sysconstraints c
    where
        c.tabid = i.tabid
        and c.idxname = i.idxname
        and c.idxname is not null
    )
and t.owner = 'mtk'

约束信息

select tab.tabid,
    tab.owner,
    tab.tabname,
    constr.constrname,
    constr.constrtype,
    -- chk.seqno,
    chk.checktext,
    c1.colname,
    -- constr.constrid,
    constr.idxname,
    rt.owner as r_owner,
    rt.tabname as r_cons_tab,
    rc.constrname as r_cons_name,
    r.updrule AS update_rule,
    r.delrule AS delete_rule,
    s.state,
    i.part1,
    i.part2,
    i.part3,
    i.part4,
    i.part5,
    i.part6,
    i.part7,
    i.part8,
    i.part9,
    i.part10,
    i.part11,
    i.part12,
    i.part13,
    i.part14,
    i.part15,
    i.part16
from sysconstraints constr
join sysobjstate s on s.tabid=constr.tabid and s.name=constr.constrname  and s.objtype='C'
join systables tab on tab.tabid = constr.tabid
left outer join syschecks chk on chk.constrid = constr.constrid and chk.type = 'T'
left outer join sysreferences r on constr.constrid=r.constrid
left outer join sysconstraints rc on rc.constrid=r.primary
left outer join systables rt on r.ptabid = rt.tabid
left outer join sysindexes i on i.idxname = constr.idxname
left outer join syscolumns c1 on c1.tabid = tab.tabid
    and c1.colno in (abs(part1), abs(part2), abs(part3), abs(part4), abs(part5), abs(part6), abs(part7), abs(part8), abs(part9), abs(part10),
                                          abs(part11), abs(part12), abs(part13), abs(part14), abs(part15), abs(part16))
WHERE constr.constrtype != 'N'

视图信息

select
    t.owner,
    t.tabname,
    v.tabid,
    v.seqno,
    v.viewtext
from
    informix.sysviews v
join informix.systables t on
    v.tabid = t.tabid
order by v.tabid,v.seqno

函数信息

select
 sp.procid,
 sp.owner,
 sp.procname,
 sb.datakey,
 sb.seqno,
 sb.data
from
 informix.sysprocedures sp
 left join sysprocbody sb on sp.procid = sb.procid
where sb.datakey IN ('D','T')
  and sp.isproc='f'
order by sb.procid, sb.seqno

存储过程信息

select
 sp.procid,
 sp.owner,
 sp.procname,
 sb.datakey,
 sb.seqno,
 sb.data
from
 informix.sysprocedures sp
 left join sysprocbody sb on sp.procid = sb.procid
where sb.datakey IN ('D','T')
  and sp.isproc='t'
order by sb.procid, sb.seqno

触发器信息

select tr.owner,tr.trigname,tr.trigid,tr.tabid,tr.event,tr.old,tr.new,
     ta.owner,ta.tabname,
    tb.seqno, tb.data
from
    systables ta
    join systriggers tr on tr.tabid = ta.tabid
    join systrigbody tb on tb.trigid = tr.trigid
where  ta.tabtype = 'T'
  and tb.datakey IN ('A', 'D')
order by tr.trigname, datakey desc, seqno

同义词

select t.owner,t.tabname,t1.owner,t1.tabname,t.tabtype from informix.systables t
left join informix.SYSSYNTABLE s on t.tabid=s.tabid
left join  informix.systables t1 on s.btabid=t1.tabid
where t.tabtype in ('S','P')
Copyright © 2011-2024 www.enmotech.com All rights reserved.