07 Dec 2022
最近在使用 DataX 进行 PostgreSQL 和 PostgreSQL 之间的数据同步,在数据同步过程中, 遇到了一个问题,在本文简单记录下问题和相应的解决方案。
在一次数据同步中,DataX执行失败,错误信息如下:
具体错误信息为:com.alibaba.datax.common.exception.DataXException: Code:[DBUtilErrorCode-12], description = [不支持的数据库类型. 请注意查看 DataX 已经支持的数据库类型以及数据库版本.]. - 您的配
置文件中的列配置信息有误. 因为DataX 不支持数据库读取这种字段类型. 字段名:[country], 字段名称:[1111], 字段Java类型:[java.lang.String]. 请尝试使用数据库函数将其转换datax支持的类型
我的配置如下:
{
" job" : {
" setting" : {
" speed" : {
" channel" : 3
} ,
" errorLimit" : {
" record" : 0 ,
" percentage" : 0. 02
}
} ,
" content" : [
{
" reader" : {
" name" : " postgresqlreader" ,
" parameter" : {
" username" : " xasdas" ,
" password" : " xxx" ,
" column" : [
" id" ,
" country"
] ,
" connection" : [
{
" table" : [
" xx"
] ,
" jdbcUrl" : [
" jdbc:postgresql://xxx:5432/xxxx"
]
}
]
}
} ,
" writer" : {
" name" : " postgresqlwriter" ,
" parameter" : {
" username" : " xxxx" ,
" password" : " x" ,
" column" : [
" id" ,
" country"
] ,
" preSql" : [
] ,
" postSql" : [
] ,
" connection" : [
{
" jdbcUrl" : " jdbc:postgresql://xxx:5432/xxxx" ,
" table" : [
" xx"
]
}
]
}
}
}
]
}
}
通过检查数据库字段,发现 country 字段是 jsonb 类型,DataX不支持此类型,DataX 的支持列表:
DataX 内部类型 PostgreSQL 数据类型
Long bigint, bigserial, integer, smallint, serial
Double double precision, money, numeric, real
String varchar, char, text, bit, inet
Date date, time, timestamp
Boolean bool
Bytes bytea
那该如何解决呢,我查看了相关的 issues 和 pr , 发现了一些通过修改源代码的解决方案和一些不修改代码的方案,由于对 java 不熟悉, 就不采用修改代码的方式来解决问题。
# 解决方案
接下来我来介绍尝试的几种方案和最终采用的方案。
# 修改列类型
最方便的可能是直接将列的类型改为支持的类型,但由于数据库已经大规模使用了,修改数据库类型会影响正在使用的程序, 所以不采用此方法。
# reader 修改字段类型
第二种方法是在 DataX reader 时将列类型转换为 varchar 类型, writer 列不动,看看 postgresql 能否自动将数据类型转换为 jsonb 类型。
修改后的配置如下:
{
" job" : {
" setting" : {
" speed" : {
" channel" : 3
} ,
" errorLimit" : {
" record" : 0 ,
" percentage" : 0. 02
}
} ,
" content" : [
{
" reader" : {
" name" : " postgresqlreader" ,
" parameter" : {
" username" : " xxxx" ,
" password" : " xxxx" ,
" column" : [
" id" ,
" country::varchar"
] ,
" connection" : [
{
" table" : [
" xxxx"
] ,
" jdbcUrl" : [
" jdbc:postgresql://xxxx3:5432/xxxx"
]
}
]
}
} ,
" writer" : {
" name" : " postgresqlwriter" ,
" parameter" : {
" username" : " xxxx" ,
" password" : " xxx" ,
" column" : [
" id" ,
" country"
] ,
" preSql" : [
] ,
" postSql" : [
] ,
" connection" : [
{
" jdbcUrl" : " jdbc:postgresql://xxx:5432/xxx" ,
" table" : [
" xx"
]
}
]
}
}
}
]
}
}
运行后还是没有成功同步,出现报错:
[不支持的数据库类型. 请注意查看 DataX 已经支持的数据库类型以及数据库版本.]. - 您的配置文件中的列配置信息有误.
因为DataX 不支持数据库写入这种字段类型. 字段名:[country], 字段类型:[1111], 字段Java类型:[jsonb]. 请修改表中该字段的类型或者不同步该字段
# 临时列写入
第三种方法是第二种的扩展,除了在 reader 时进行数据转换,writer 时将 reader 转换的数据写入临时列中,写入后通过 postSql 将临时列的值更新至正确的列上。
具体的配置如下:
{
" job" : {
" setting" : {
" speed" : {
" channel" : 3
} ,
" errorLimit" : {
" record" : 0 ,
" percentage" : 0. 02
}
} ,
" content" : [
{
" reader" : {
" name" : " postgresqlreader" ,
" parameter" : {
" username" : " postgres" ,
" password" : " 123456" ,
" column" : [
" id" ,
" country::varchar"
] ,
" connection" : [
{
" table" : [
" xx"
] ,
" jdbcUrl" : [
" jdbc:postgresql://xxx:5432/xxx"
]
}
]
}
} ,
" writer" : {
" name" : " postgresqlwriter" ,
" parameter" : {
" username" : " postgres" ,
" password" : " xx" ,
" column" : [
" id" ,
" country_tmp"
] ,
" preSql" : [
] ,
" postSql" : [
" UPDATE matches SET country = country_tmp::JSONB;"
] ,
" connection" : [
{
" jdbcUrl" : " jdbc:postgresql://xxxx:5432/xxx" ,
" table" : [
" xxx"
]
}
]
}
}
}
]
}
}
运行后顺利同步成功了。此方案就是我采用的最终解决方案。
本文主要介绍了在 postgresql 和 postgresql 之间遇到的一个 jsonb 数据类型不支持的问题,本文简单介绍了这个问题,并给出了不修改代码的解决方案,
https://github.com/alibaba/DataX
https://github.com/alibaba/DataX/blob/master/postgresqlwriter/doc/postgresqlwriter.md
https://github.com/alibaba/DataX/blob/master/postgresqlreader/doc/postgresqlreader.md
Activate JavaScript
to load comments .