- 简介
- 环境依赖
- 快速上手
- 配置文件
- 命令介绍
- mtk
- init-project
- config
- license
- mig
- show
- sync
- sync-schema
- sync-sequence
- sync-object-type
- sync-domain
- sync-wrapper
- sync-server
- sync-user-mapping
- sync-queue
- sync-table
- sync-nickname
- sync-rule
- sync-table-data
- sync-table-data-estimate
- sync-index
- sync-constraint
- sync-db-link
- sync-view
- sync-mview
- sync-function
- sync-procedure
- sync-package
- sync-trigger
- sync-synonym
- sync-table-data-com
- sync-alter-sequence
- sync-coll-statistics
- check-table-data
- gen
- gen completion
- encrypt
- convert-plsql
- report
- self
- mvd
- usql
- 图形化
- 常见问题
- Release
使用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-lengthinterval
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
,迁移到 openGausstimestamp
类型会变成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')