金仓数据库征文_使用KDTS迁移mysql至金仓数据库问题处理记录分享

随着国家信创战略的深入推进,我司核心业务系统需要进行全面的国产化改造。原系统基于MySQL数据库构建,已稳定运行5年,数据量达到TB级别,包含数百张业务表和大量存储过程。根据企业技术栈国产化要求,需要将数据库迁移至国产金仓数据库(KingbaseES)平台。

选择使用KDTS理由:

Kingbase Data Transfer System(KDTS)是金仓数据库官方提供的专业数据迁移工具,主要功能包括:

  1. 多源数据库支持

  2. 全对象迁移能力

  3. 智能转换特性

  4. 高效迁移引擎

接下来是我在迁移过程中遇到的一些报错以及处理方式:

进行查看日志:
报错1:分区键表达式函数问题

fail:

com.kingbase8.util.KSQLException: ERROR: functions in partition key expression must be marked IMMUTABLE

根据错误信息,com.kingbase8.util.KSQLException: ERROR: functions in partition key expression must be marked IMMUTABLE,问题出在分区键表达式中使用的函数 unix_timestamp 没有被标记为 IMMUTABLE。IMMUTABLE 表示该函数在给定相同输入时总是返回相同的结果,且不会修改数据库状态。

在 Kingbase 中,分区键表达式中的函数必须是 IMMUTABLE 的,而 unix_timestamp 函数可能被标记为 STABLE 或 VOLATILE,因此无法直接用于分区键。

解决方案

使用 EXTRACT 函数: 你可以使用 EXTRACT 函数来提取时间戳的秒数,EXTRACT 函数是 IMMUTABLE 的。

PARTITION BY RANGE (EXTRACT(EPOCH FROM created_date))

点击保存,并执行:

可以看到问题已解决。

报错2:嵌套语法不兼容

报错信息:

fail:

com.kingbase8.util.KSQLException: ERROR: syntax error at or near ")"

Position: 367 At Line: 1, Line Position: 367

问题出在JOIN语法上,金仓数据库不支持这种嵌套括号的JOIN写法。

处理方法:

新库处理,单独更新脚本执行即可。

CREATE VIEW tablename123 AS

SELECT

a.id AS item_id,

a.item_name AS item_name,

b.id AS rule_id,

b.rule_name AS rule_name,

b.value AS value,

b.tenant_id AS tenant_id,

c.factor_name AS factor_name,

d.factor_value AS factor_value

FROM atl_config_item a

INNER JOIN tablename123 b ON a.id = b.config_item_id

INNER JOIN tablename12345 c ON a.id = c.config_item_id

INNER JOIN tablename123123445 d ON d.config_rule_id = b.id AND d.config_rule_factor_id = c.id

ORDER BY a.id, d.config_rule_id, d.config_rule_factor_id;

报错3:字符集编码问题#手工处理

报错信息:

fail:

com.kingbase.kdts.g.b: Failed to write table data! , datas:

Caused by: com.kingbase.kdts.writer.b.a: java.io.IOException: Ending write to copy failed.

Caused by: java.io.IOException: Ending write to copy failed.

Caused by: com.kingbase8.util.KSQLException: ERROR: invalid byte sequence for encoding "UTF8": 0x00

Where: COPY tabletest1, line 244, column relevance_key

---处理过程,mysql进行输出为csv格式

mysql> SELECT * INTO OUTFILE '/data/mysql/tabletest1_hex.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM tabletest1;

Query OK, 244 rows affected (0.01 sec)

----Kingbase 层操作copy:

cd /home/kingbase

root@VM-10-12-ubuntu:/home/kingbase# cp /data/mysql/tabletest1_hex.csv .

----执行copy命令:

kingbase@VM-10-12-ubuntu:~$ ksql -U system -d wsedtd -h 192.168.10.12 -p 54321 -c "COPY tabletest1 (id,***********) FROM '/home/kingbase/tabletest1_hex.csv' WITH (FORMAT csv, DELIMITER ',',FORCE_NULL (relevance_key),ENCODING 'UTF8');"

Password for user system:

ERROR: invalid byte sequence for encoding "UTF8": 0x00

CONTEXT: COPY tabletest1, line 1

##提示报错:进行替换处理:

sed 's/\x00//g' /home/kingbase/tabletest1_utf8.csv > /home/kingbase/tabletest1_clean.csv

#然后再次进行copy操作:

kingbase@VM-10-12-ubuntu:~$ ksql -U system -d wsedtd -h 192.168.10.12 -p 54321 -c "COPY tabletest1 (id,***********) FROM '/home/kingbase/tabletest1_clean.csv' WITH (FORMAT csv, DELIMITER ',', ENCODING 'UTF8');"

Password for user system:

ERROR: invalid input syntax for type numeric: "\N"

CONTEXT: COPY tabletest1, line 1, column company_id: "\N"

#根据上边报错,再次进行替换处理

sed -i 's/\N/NULL/g' /home/kingbase/tabletest1_clean.csv

#然后再次进行copy操作:

kingbase@VM-10-12-ubuntu:~$ ksql -U system -d wsedtd -h 192.168.10.12 -p 54321 -c "COPY tabletest1 (id, **************) FROM '/home/kingbase/tabletest1_clean.csv' WITH (FORMAT csv, DELIMITER ',', ENCODING 'UTF8');"

Password for user system:

ERROR: invalid input syntax for type numeric: "NULL"

CONTEXT: COPY tabletest1, line 1, column company_id: "NULL"

#根据上边报错,再次进行替换处理

sed -i 's/NULL//g' /home/kingbase/tabletest1_clean.csv

#然后再次进行copy操作:

kingbase@VM-10-12-ubuntu:~$ ksql -U system -d wsedtd -h 192.168.10.12 -p 54321 -c "COPY tabletest1 (id,****************) FROM '/home/kingbase/tabletest1_hex_clean.csv' WITH (FORMAT csv, DELIMITER ',', ENCODING 'UTF8');"

Password for user system:

ERROR: invalid input syntax for type bytea

CONTEXT: COPY tabletest1, line 244, column relevance_key: "\0"

#根据上边报错,再次进行替换处理

sed -n '244p' /home/kingbase/tabletest1_hex_clean.csv

"1129651325741506594","943460702762700801","12","","","","","CAROUSEL_LIST","","","���表","","","7","WORK","","","","","2025-04-22 16:33:39","2025-04-22 16:33:39","ONLINE","","","","MOBILE","","","","","","\0","","",""

根据上边信息查看报错内容,再次进行替换

sed -i 's/\0//g' /home/kingbase/tabletest1_hex_clean.csv

#然后再次进行copy操作:

kingbase@VM-10-12-ubuntu:~$ ksql -U system -d wsedtd -h 192.168.10.12 -p 54321 -c "COPY wsedtd.tabletest1 (id,***********) FROM '/home/kingbase/tabletest1_hex_clean.csv' WITH (FORMAT csv, DELIMITER ',', ENCODING 'UTF8', FORCE_NULL (relevance_key));"

Password for user system:

COPY 244

###执行成功,数据正常同步至数据库。

问题4:#外键非空缺失依赖

报错信息:

wsedtd.tabletest22 fail:

com.kingbase8.util.KSQLException: ERROR: insert or update on table "tabletest24" violates foreign key constraint "tabletest22_3BE15C83"

Detail: Key (company_id)=(2) is not present in table "tabletest25".

wsedtd.tabletest23 fail:

com.kingbase8.util.KSQLException: ERROR: insert or update on table "tabletest26" violates foreign key constraint "tabletest23_56F7617"

Detail: Key (cost_id)=(39) is not present in table "art_cost_center_item".

wsedtd.fk_user_cost_center_item_user_id fail:

com.kingbase8.util.KSQLException: ERROR: insert or update on table "tabletest26" violates foreign key constraint "cost_id_2BB897"

Detail: Key (user_id)=(47) is not present in table "tabletest27".

在 tabletest26 表上添加一个外键约束,

引用 tabletest27 表的 id 字段,

但是 tabletest26

表中存在一些记录(如 user_id=47),这些记录的 user_id 值在 tabletest27 表中找不到对应的记录

mysql> SELECT user_id

-> FROM wsedtd.tabletest26

-> WHERE user_id NOT IN (

-> SELECT id

-> FROM wsedtd.tabletest27

-> );

±--------+

| user_id |

±--------+

| 208 |

| 47 |

| 132 |

±--------+

3 rows in set (0.00 sec)

然后进行数据处理。再次执行,即可修复。

问题5:#视图报错处理函数不支持

报错信息:

test123.tabletsts28 fail:

com.kingbase8.util.KSQLException: ERROR: function sys.timestampdiff(unknown, text, text) is not unique

Hint: Could not choose a best candidate function. You might need to add explicit type casts.

Position: 787 At Line: 1, Line Position: 787

原因:

使用Kingbase8/PostgreSQL支持的日期运算语法

避免使用可能不兼容的函数

问题6:#语法差异问题

报错信息:

ERROR: column "f.scene_id" must appear in the GROUP BY clause or be used in an aggregate function

Position: 768 At Line: 1, Line Position: 768

改写SQL:

完整的GROUP BY:添加了所有SELECT中非聚合列到GROUP BY子句

语法修正:修复了所有括号匹配问题

格式优化:改进了SQL格式,使其更易读

函数一致性:统一了IF函数的使用方式

问题7:#语法兼容性差异问题

test123.tabletsts29 fail:

com.kingbase8.util.KSQLException: ERROR: invalid reference to FROM-clause entry for table "r"

Hint: There is an entry for table "r", but it cannot be referenced from this part of the query.

Position: 88 At Line: 1, Line Position: 88

错误位置:

where (test123.r.reimb_status > '1004')

问题出在 test123.r 的引用方式。

在 SQL 中,表别名(如 r)的作用是简化表名引用,不需要也不能用 schema(test123)修饰别名

兼容性问题:

某些数据库(如 MySQL)可能允许这种写法,但 Kingbase 严格遵循 SQL 标准,不允许用 schema 修饰别名。

总结:

KDTS工具针对同步过程中,出现的问题可以进行单独处理,大大方便了提升效率,同时也把自己迁移过程中的问题记录,分享给大家,希望对大家有帮助。

相关推荐
做cv的小昊几秒前
【TJU】信息检索与分析课程笔记和练习(7)数据库检索—Ei
数据库·笔记·学习·全文检索
zgl_2005377914 分钟前
ZGLanguage 解析SQL数据血缘 之 标识提取SQL语句中的目标表
java·大数据·数据库·数据仓库·hadoop·sql·源代码管理
莳花微语16 分钟前
记录一次OGG进程abended,报错OGG-01431、OGG-01003、OGG-01151、OGG-01296问题的处理
数据库·sql·mysql
尋有緣38 分钟前
力扣1355-活动参与者
大数据·数据库·leetcode·oracle·数据库开发
萧曵 丶1 小时前
MySQL三大日志系统浅谈
数据库·sql·mysql
煎蛋学姐1 小时前
SSM校园兼职招聘系统x6u36(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·企业管理·ssm 框架·校园兼职招聘系统
ChineHe2 小时前
Redis基础篇004_Redis Pipeline流水线详解
数据库·redis·缓存
西柚补习生2 小时前
通用 PWM 原理基础教学
数据库·mongodb
小张程序人生3 小时前
ShardingJDBC读写分离详解与实战
数据库
木风小助理3 小时前
三大删除命令:MySQL 核心用法解析
数据库·oracle