首批通过分布式安全可靠测评,为关键业务系统打造
定义控制文件
更新时间:2026-04-07 17:00:52
通过已定义的控制文件,OBLOADER 可以对被导入的数据进行预处理。
文件模板
控制文件的定义模版如下所示:
lang=java
(
${列名} ${字节偏移位置}(可选) "${预处理函数}"(可选) ${映射定义}(可选),
${列名} ${字节偏移位置}(可选) "${预处理函数}"(可选) ${映射定义}(可选),
${列名} ${字节偏移位置}(可选) "${预处理函数}"(可选) ${映射定义}(可选),
${列名} ${字节偏移位置}(可选) "${预处理函数}"(可选) ${映射定义}(可选)
);
列名:数据库表结构中的字段名称。OBLOADER 不区分列名大小写。如果需要区分大小写,请将列名放入中括号([ ])或者反引号(``)内。例如:
[c1]表示 c1 列,[C1]表示 C1 列。字节偏移位置:支持两种声明方式,绝对偏移和相对偏移。仅
--pos格式数据支持定义字节偏移位置。绝对偏移:
position(start, end),start与end分别表示字段的起始位置(字节)与结束位置(字节)。如果需要指定列长以忽略导入某一段字节到数据库表中,您可以使用特殊关键字 _FILLER 代替实际的列名并标记该部分数据,此操作将创建一个匿名列,该列会由 OBLOADER 解析,但不会与表中的任何现有列关联。此关键字特别适用于忽略文件中某些不相关的数据,如行尾的填充字节。示例:_filler position(5:10),表示跳过第 5 到第 10 个字节。相对偏移:
position(length),length表示字段的长度(字节)。
预处理函数:在控制文件中为指定的列配置预处理函数,以对导入的数据进行预处理。
映射定义:导入的数据文件中预处理数据的列位置。
注意
- 控制文件的命名规范为 <表名>.ctrl。
- 数据导入前,OBLOADER 会检索以
.ctrl结尾的控制文件,并根据控制文件中配置的函数对导入的数据进行预处理。- 导入多个表且包含多个控制文件时,OBLOADER 会检索
ctl-path路径下所有以.ctrl结尾的文件,并按照控制文件名与表名的对应关系绑定到导入的表。此情况下,请确保控制文件名与对应导入的表名相同。例如:控制文件loader1.ctrl对应表loader1,控制文件loader2.ctrl对应表loader2。 - 导入单个表且只包含一个控制文件时,
--ctl-path选项可以直接指定控制文件名,OBLOADER 会直接将指定的控制文件绑定到导入的表。
- 导入多个表且包含多个控制文件时,OBLOADER 会检索
注意事项
如表中定义的列名包含了数据库关键字,需在列名前后添加反引号(`)进行转义。示例如下:
lang=java ( `WHEN` "lower(`WHEN`)", c2 "nanvl(c2,'0')" );OBLOADER 3.x 版本不再支持 map 文件,字段映射功能合并到 ctrl 文件中。示例如下:
lang=java( C1 "NONE" map(1), C2 "NONE" map(1), // 多列映射 C3 "CONSTANT('xxx')", // xxx 为指定的常量 C4 "SEQUENCE(100, 1)" // 100 为初值,1 为步长 );其中,
C3 "CONSTANT('xxx')"和C4 "SEQUENCE(100, 1)"为生成列。说明
- OBLOADER 3.0.0 之前版本仅支持单列映射,不支持生成列。OBLOADER 3.0.0 之后版本的控制文件中可以配置多列映射以及生成列。
- 生成列是指数据文件中不存在的列。OBLOADER 支持对生成列进行预处理的函数包括:
CONSTANT,SEQUENCE,DB_SEQUENCE。例如:C4 "SEQUENCE(100, 1)",具体描述请参考 预处理函数。
控制文件不能和
--exclude-column-names一起生效,控制文件包含--exclude-column-names的功能。控制文件中需要列出数据库目标表结构中的字段名称,否则无法与数据文件字段值对应。
使用示例
导入 --cut、--csv 和 --sql 格式的数据
准备数据。
示例语句:
DROP TABLE IF EXISTS `student`; CREATE TABLE `mysql`.`loader` ( `c1` varchar(120) NULL, `c2` varchar(120) NULL, `c3` varchar(120) NULL, `c4` varchar(120) NULL, `c5` varchar(120) NULL, `c6` varchar(120) NULL, `c7` varchar(120) NULL, `c8` varchar(120) NULL, `c9` varchar(120) NULL, `c10` varchar(120) NULL, `c11` varchar(120) NULL, `c12` varchar(120) NULL, `c13` varchar(120) NULL, `c14` varchar(120) NULL, `c15` int(120) NULL, `c16` timestamp NULL, `c17` varchar(120) NULL, `c18` varchar(120) NULL, `c19` varchar(120) NULL, `c20` varchar(120) NULL, `c21` varchar(120) NULL, `c22` date NULL, `c23` varchar(120) NULL, `c24` varchar(120) NULL, `c25` varchar(120) NULL, `c26` varchar(120) NULL, `c27` varchar(120) NULL, `c28` varchar(120) NULL ) DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci; INSERT INTO `loader`(`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`,`c17`,`c18`,`c19`,`c20`,`c21`,`c22`,`c23`,`c24`,`c25`,`c26`,`c27`,`c28`) VALUES ('XIAOHONG', 1111111,'222222 ',123456,123,'hhhhh',1234,'abc','null',123456,'1','1','china','123',456,'2023-07-11 20:56:36','123','1','1',11,2,'2023-07-11','Abc123','Ab3','Ab3','12345Ab3','Ab312345','123456789');定义控制文件。用户在控制文件中为被导入的每一列配置对应的 预处理函数。
示例语句:
lang=java ( c1 "lower(c1)" map(1), -- c1 列的值中的字母转换为小写 c2 "ltrim(c2)" map(2), -- c2 列的值从左开始截断空格 c3 "rtrim(c3)" map(3), -- c3 列的值从右开始截断空格 c4 "substr(c4,0,5)" map(4), -- c4 列的值第 1 位置截取 5 个字符长度的字符串 c5 "trim(c5)" map(5), -- c5 列的值左右两侧截断空格 c6 "upper(c6)" map(6), -- c6 列的值中的字母转换为大写 c7 "nanvl(c7,'0')" map(7), -- c7 列的值进行数值验证,非数值则返回 0 c8 "replace(c8,'a','A')" map(8), -- c8 列的值中的 a 替换为 A c9 "nvl(c9,'null')" map(9), -- c9 列的值进行判空,若为 null 返回 null 字符串 c10 "length(c10)" map(10), -- c10 列的值进行长度计算 c11 "lpad(c11,5,'x')" map(11), -- c11 列的值左侧追加 5 个字符长度字符串 'x' c12 "rpad(c12,5,'x')" map(12), -- c12 列的值右侧追加 5 个字符长度字符串 'x' c13 "convert(c13,'utf-8','gbk')" map(13), -- c13 列的值从 gbk 转换为 utf-8 字符编码 c14 "concat(c14, '_suffix')" map(14), -- c14 列的值与常量进行拼接 c15 "none" map(15), -- c15 列的值不作任何处理,直接返回对应列的值 c16 "systimestamp" map(16), -- c16 列的值不作任何处理,直接返回当前集群的时间戳 c17 "constant('1')" map(17), -- c17 列的值不作任何处理,仅返回常量 1 c18 "lpadb(c18,5,'x')" map(18), -- c18 列的值左侧追加 5 个字节长度(单)字符 'x' c19 "rpadb(c19,5,'x')" map(19), -- c19 列的值右侧追加 5 个字节长度(单)字符 'x' c20 "case when length(trim(c20))<18 then 'Y' else 'N' end" map(20), -- c20 列的值进行条件真值匹配,若为真返回对应列的值 c21 "case length(trim(c21)) when '1' then 'one' when '2' then 'two' else 'unknown' end" map(21), -- c21 列的值进行条件等值匹配,若匹配成功返回对应列的值 C22 "SYSDATE" map(22), -- c22 列的值为当前日期 C23 "MASK(C23)" map(23), -- c23 列的值进行脱敏,只对列名有效,列中的大、小写字母和数字使用默认脱敏字符替代(默认脱敏字符:大写字母 X,小写字母 x,数字 n) C24 "MASK_FIRST_N(C24,'A','a','b',3)" map(24), -- c24 列的值指定大、小写字母以及数字的脱敏字符(默认 N 为 0,从第一个字符开始) C25 "MASK_LAST_N(C25,'A','a','b',3)" map(25), -- c25 列的值指定大、小写字母以及数字的脱敏字符(默认 N 为 0,从最后一个字符开始) C26 "MASK_SHOW_FIRST_N(C26,'A','a','b',3)" map(26), -- c26 列的值指定不脱敏字符数(默认 N 为 0,从第一个字符开始) C27 "MASK_SHOW_LAST_N(C27,'A','a','b',3)" map(27), -- c27 列的值指定不脱敏字符数(默认 N 为 0,从最后一个字符开始) C28 "REVERSE(C28)" map(28), -- c28 列的值将字符顺序颠倒 );注意
- 控制文件的命名规范为 <表名>.ctrl。
- 一个控制文件对应一个表,预处理多个表的数据时,需要在
ctl-path路径下创建多个控制文件,且控制文件名须与导入的对应表名相同。
通过
--ctl-path选项指定控制文件所在的绝对路径进行数据预处理后,导入--csv格式的数据。示例语句:
$./obloader -h xx.x.x.x -P 2883 -u test@mysql#cluster_a -p ****** --sys-user **u*** --sys-password ****** -D USERA --csv --table '*' --ctl-path /home/controls/ -f /output其中,
--ctl-path /home/controls/选项为指定控制文件所在的绝对路径。任务结果示例:
... All Load Tasks Finished: ---------------------------------------------------------- | No.# | Type | Name | Count | Status | ---------------------------------------------------------- | 1 | TABLE | loader | 1 -> 1 | SUCCESS | ---------------------------------------------------------- Total Count: 1 End Time: 2023-07-04 07:13:01 ...导入的数据示例:
... SELECT * FROM `loader`; +----------+---------+--------+-------+------+-------+------+------+------+------+-------+-------+-------+------------+------+---------------------+------+-------+-------+------+------+------------+--------+------+------+----------+----------+-----------+ | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21 | c22 | c23 | c24 | c25 | c26 | c27 | c28 | +----------+---------+--------+-------+------+-------+------+------+------+------+-------+-------+-------+------------+------+---------------------+------+-------+-------+------+------+------------+--------+------+------+----------+----------+-----------+ | xiaohong | 1111111 | 222222 | 12345 | 123 | HHHHH | 1234 | Abc | null | 6 | xxxx1 | 1xxxx | china | 123_suffix | 456 | 2023-07-05 02:52:07 | 1 | xxxx1 | 1xxxx | Y | one | 2023-07-05 | Xxxnnn | Aab | Aab | 123bbAab | Aabbb345 | 987654321 | +----------+---------+--------+-------+------+-------+------+------+------+------+-------+-------+-------+------------+------+---------------------+------+-------+-------+------+------+------------+--------+------+------+----------+----------+-----------+ 1 row in set (0.04 sec) ...
导入 --pos 格式的数据
定义控制文件示例语句:
lang=java
(
c1 position(1:5) "trim(c1)", -- 截取 c1 列的第 1 到第 5 个字节,并且对得到的结果两侧截断空格
c2 position(7:25) "replace(trim(c2),'',' ')" -- 截取 c2 列的第 7 到第 25 个字节,并且对得到的结果两侧截断空格,同时对于空字符用空格替代
);
注意
OBLOADER V3.0.0 之后的版本不再支持 --null-replacer、--empty-replacer、--default-date 和 --date-format 选项。