金仓数据库征文_使用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工具针对同步过程中,出现的问题可以进行单独处理,大大方便了提升效率,同时也把自己迁移过程中的问题记录,分享给大家,希望对大家有帮助。

相关推荐
芝麻馅汤圆儿6 小时前
sockperf 工具
linux·服务器·数据库
wsx_iot6 小时前
mysql的快照读和当前读
数据库·mysql
梁萌6 小时前
MySQL分区表使用保姆级教程
数据库·mysql·优化·分区表·分区·partitions
期待のcode6 小时前
MyBatis-Plus的Wrapper核心体系
java·数据库·spring boot·后端·mybatis
透明的玻璃杯7 小时前
sqlite数据库链接池二
数据库·oracle·sqlite
老华带你飞7 小时前
出行旅游安排|基于springboot出行旅游安排系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring·旅游
Logic1017 小时前
《数据库运维》 郭文明 实验4 数据库备份与恢复实验核心操作与思路解析
运维·数据库·sql·mysql·学习笔记·形考作业·国家开放大学
马克学长7 小时前
SSM物流信息管理系统35wzn(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·数字化管理·ssm 框架·物流信息管理
IndulgeCui7 小时前
KingbaseES 三权分立原则
数据库