作者:杨文

DBA,负责客户我的项目的需要与保护,会点数据库,不限于MySQL、Redis、Cassandra、GreenPlum、ClickHouse、Elastic、TDSQL等等。

本文起源:原创投稿

*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


1、问题形容

有时咱们在导入导出数据时,须要对数据进行解决,来满足业务上的数据需要,此时须要应用管制文件配合导数工具来满足业务上不同数据的需要。

2、管制文件模板:

lang=java(  列名 字节偏移地位(可选) "预处理函数" 映射定义(可选),  列名 字节偏移地位(可选) "预处理函数" 映射定义(可选),  列名 字节偏移地位(可选) "预处理函数" 映射定义(可选));

简略示例:

lang=javaserver=mysql/oracle(    c1 "nvl(c1,'not null')" map(field_position),    c2 "none" map(field_position));

参数阐明:

  • field_position为导入的数据文件中预处理数据的列地位。
  • 管制文件的命名标准:table_name.ctl,大小写与数据库中保持一致。
  • 管制文件的内容要求列名的程序与表中定义的列程序保持一致,且列名大小写与表中的列名大小写保持一致。

3、应用案例:

3.1、测试数据:

cat /data/test/TABLE/test.dat1@##oceanbase@##2023-01-12 15:00:00.0@##1@##ob@##1@##ob2@##oceanbase@##2023-01-12 15:00:00.0@##2@##ob@##2@##ob3@##oceanbase@##2023-01-12 15:00:00.0@##3@##ob@##3@##obcreate table test01 (id int(10) not null primary key,name varchar(10),time timestamp not null default '1971-01-01 01:01:01',blank varchar(255) null);create table test02 (id int(10) not null primary key,name varchar(10) not null,time timestamp not null,bar varchar(255) default null,blank varchar(255) default null,line varchar(255) default null,mark  varchar(255) default null,test  varchar(255) not null);

3.2、案例1:

表列少于文本列:表全列导入。

管制文件:

vi /data/test01.ctllang=java(id "none" map(1),name "none" map(2),time "none" map(3),blank "none" map(5));

导入语句:

./obloader -h 10.186.60.94 -P 2883 -u root -p rootroot \-c ywob -t mysql_yw_tent -D ywdb --table test01 --cut \-f /data/test/TABLE/test.dat --log-path /data/ --external-data \--replace-data --column-splitter '@##' --ctl-path /data/test01.ctl

输入后果:

All Dump Tasks Finished:----------------------------------------------------------------------------------------------------         No.#      |        Type       |        Name       |       Count       |       Status----------------------------------------------------------------------------------------------------          1        |       TABLE       |      test01       |         3         |      SUCCESS-------------------------------------------------------------------------

能够看到是胜利的。此时,咱们进库再进行select查问数据进行验证,能够看到确实是胜利的。

3.3、案例2:

表列少于文本列:表局部列导入。

管制文件:

vi /data/test01.ctllang=java(id "none" map(1));

导入数据,能够看到报错信息:

Error:"Field 'id' doesn't have a default value"

批改管制文件:

vi /data/test01.ctllang=java(id "none" map(1),name "none" map(2));

此时再导入是胜利的。

阐明:

  • 插入局部列时,须要为插入的每列,在参数文件中指定对应的文本列。
  • not null列必须有对应的插入数据,或者是有缺省值。

3.4、案例3:

表列多于文本列:全列导入。

管制文件:

vi /data/test02.ctllang=java(id "none" map(1),name "none" map(2),time "none" map(3),bar "none" map(4),blank "none" map(5),line "none" map(6),mark "none" map(7));

导入语句:

./obloader -h 10.186.60.94 -P 2883 -u root -p rootroot \-c ywce -t mysql_yw_tent -D ywdb --table test02 --cut \-f /data/test/TABLE/test.dat --log-path /data/ --external-data \--replace-data --column-splitter '@##' --ctl-path /data/test02.ctl

输入后果:

All Dump Tasks Finished:----------------------------------------------------------------------------------------------------         No.#      |        Type       |        Name       |       Count       |       Status----------------------------------------------------------------------------------------------------          1        |       TABLE       |      test02       |         3         |      SUCCESS----------------------------------------------------------------------------------------------------

能够看到是胜利的。然而明天在另一个同版本的OB环境下意外的发现了一个怪事,居然报错了:

Error: Column count doesn't match value count at row 1

报错信息:列数不匹配。

依据这种状况进行剖析:发现JDK版本不统一。并且能够看到导入的数据文件比表构造少一列,数据文件以“@##”作为列分隔符,并且最初一列结尾没有分隔符。

解决:

形式1:批改管制文件:

vi /data/test02.ctllang=java(id "none" map(1),name "none" map(2),time "none" map(3),bar "none" map(4),blank "none" map(5),line "none" map(6),mark "none" map(7),test "none" map(1));

形式2:批改表构造,最初一个字段能够为null。

形式3:批改数据文件,在最初面增加‘@##’后缀。

3.5、在应用“obdumper+管制文件”导出数据时,也有可能会呈现该报错信息:

Error: Column count doesn't match value count at row 1

可能的起因:数据库名大小写敏感,即数据库中的库名是小写,然而导出命令中写成了大写,导致管制文件中的配置内容不失效。

补充:

其实,还能够应用SUBSTR(char,position[,length ])进行截取解决数据;

示例:

SUBSTR('abc',0,3)

小倡议:

数据导入后进行简略查看每个字段导入的数据是否是对应的。可能存在某些状况下数据导入了,但理论数据和字段并没有对齐,可能只是凑巧数据能存入对应字段。以及查看中文是否失常显示。