OceanBase MySQL 的 load data
命令跟 MySQL 的 load data
命令是一样的。这里依然导入上面那个 t1.csv
。不同之处,需要把 csv
文件放到 OBSERVER 节点机器上。暂时 OceanBase 还不支持加载本地文件,该功能还在研发中。
LOAD 语法
LOAD DATA [/*+ parallel(N) load_batch_size(M)*/] INFILE 'file_name' [REPLACE | IGNORE] INTO TABLE tbl_name [{FIELDS | COLUMNS} [TERMINATED BY 'string'] [[OPTIONALLY] ENCLOSED BY 'char'] [ESCAPED BY 'char'] ] [LINES [STARTING BY 'string'] [TERMINATED BY 'string'] ] [IGNORE number {LINES | ROWS}] [(col_name_var [, col_name_var] ...)] [SET col_name={expr | DEFAULT}, [, col_name={expr | DEFAULT}] ...]
LOAD 原理
Load Data 目前可以对 CSV 格式的文本文件进行导入,整个导入的过程大概分为以下的过程:
- 解析文件:OceanBase 会根据用户输入的文件名,读取文件中的数据,并且根据用户的输入的并行度来决定 并行或者串行解析输入文件中的数据。
- 分发数据:由于 OceanBase 是分布式数据库系统,各个分区的数据可能分布在各个不同的observer,Load Data 会对解析出来的数据进行计算,决定数据需要被发送到哪个observer。
- 插入数据:当目标 observer 收到了发送过来的数据之后,在本地执行 insert 操作把数据插入到对应的分区当中。
为了提高 Load Data 语句的性能,用户可以执行加载数据的并行度,Load Data 在解析文件、计算分区、数据分发阶段都可以多个线程并行工作。 为了避免分布式事务对性能的影响,Load Data 会将按分区将数据分组,并分发到 observer上进行多次写入,每次写入开启一个独立的事务,写入的数据来源于一个分组。如果在 Load Data 语句执行过程中出现了错误,用户可能需要手工删除已经被加载的数据。另外,如果导入数据文件很大的话,每个节点插入数据的时间可能会很长,请根据需要调整 ob_query_timeout 参数。
Load Data 提供了很多选项支持用户不同的需求,目前支持的选项有: 并行度: /+ parallel(N)/ 选项指定加载数据的并行度,默认值是 N=4,建议使用的值范围是 [0--租户的最大 CPU 数]。
load data /*+ parallel(4) */infile '/home/admin/a.csv' into table t
批量: /+ load_batch_size(M)/ 选项指定每次插入的批量大小,默认是 M=1000,根据导入数据行的总长度调整 M 的大小,建议使用的值是 [100-1000]。
输入文件: INFILE 'file_name' 关键字指定输入文件的路径和文件名,目前 Load Data 只支持加载 OBSERVER 本地的输入文件。所以,用户需要在导入之前把文件拷贝到某一个 observer 所在机器上,并连接文件所在的 observer 运行 Load Data 语句。
目标表索引: 为了提高导入效率,建议先建基础表,等导入完成后,再创建表的索引。对全局索引,务必要导入之后再创建,否则可能会报 not support 错误。
执行权限: 用户需要授予权限才能访问机器上文件,有两步:
- 首先修改安全文件所在路径,设置为空(即无需检查) set global secure_file_priv = "";
- 对用户授予权限
- mysql 模式,授予 file 权限:执行 grant file on to USER_NAME;
重复数据处理: 这部分指定如何处理重复的数据。Replace 表示将表中原有的数据替换成为输入文件中的数据; Ignore 表示忽略掉重复的数据。Load Data 通过表的主键来判断数据是否重复,如果表不存在主键,那么 Load Data 语句就无法判断数据是否重复,replace 和 ignore 选项没有区别。如果用户不指定这个选项,那么遇到重复数据的时候,Load Data 语句会将出现错误的数据记录到日志文件中。 目标表选项: INTO TABLE tbl_name 关键字用于指定目标表名称。Load Data 支持分区表和非分区表。
字段格式: 这部分指定输入文件的各个字段的分隔符选项,通过 Fields|Columns 子句来指定,其中:Terminated By 关键字用来指定字段的分隔符, Enclosed By 关键字指定每个字段的开始和结束是否包含了特定的字符,Escaped By 关键字用来指定字段中的通配符。
行格式: 这部分指定输入文件中每一行的开始和结束字符,通过 Lines 子句设置。 其中 Starting By 用于指定每一行开始的字符;Terminated By 用户指定每一行的结束字符。IGNORE number {LINES | ROWS} 子句指定忽略掉输入文件的前number行数据。
load data /*+ parallel(4) */infile '/home/admin/a.csv' into table t fields terminated by ',' lines terminated by '\n';
日志文件
如果导入的过程中出现了错误,基于 Load Data 的设计,出现错误的 insert 语句会被回滚,并且 Load Data 语句会在 OBSERVER 安装路径的 log 子目录下产生名称为 obloaddata.log. 的日志文件,以下是一个日志文件的示例:
Tenant name: mysql File name: /home/admin/a.csv Into table: `test`.`t` Parallel: 1 Batch size: 1000 SQL trace: YD7A20BA65670-0005AADAAA3CAB52 Start time: 2020-07-29 21:08:13.073741 Load query: load data infile '/home/admin/test.csv' into table t fields terminated by ',' lines terminated by '\n' Row ErrCode ErrMsg 1 1062 Duplicated primary key 2 1062 Duplicated primary key
日志中会包含 Load Data 产生的任务的基本信息,包含了:租户名,输入文件名,目标表名,并行度,使用的 Load Data 命令。 并且以行为单位给出具体错误的信息。
示例
以上一节 MySQL 里导出的 CSV 为例,导入到 OceanBase 。
$ mysql -h127.1 -uroot@obmysql#obdemo -P2883 -p123456 -c -A test -Ns MySQL [test]> select * from t1; MySQL [test]> load data infile '/tmp/t1.csv' into table t1 fields terminated by ',' enclosed by '"' lines terminated by '\n' ; MySQL [test]> select * from t1; 1 中 国 中 国 2 中,国 "中 国" 3 中\n国 中 \n国 4 中\\国 "中\\国" MySQL [test]>
如果有使用问题,欢迎到 OceanBase 社区版官网问答区反馈 。反馈地址:https://open.oceanbase.com/answer/
(https://open.oceanbase.com/answer) 。
附录:
- 4.1 OceanBase 的 MySQL 兼容性简介
- 4.2 如何使用 mysqldump 迁移 MySQL 表 OceanBase
- 4.3 如何使用 dbcat 迁移 MySQL 表结构到 OceanBase
- 4.4 如何把 MySQL 表数据导出到 CSV 文件
- 4.5 如何使用 OceanBase 的 LOAD 命令加载 csv 数据文件 OceanBase
- 4.6 如何使用 DataX 加载 CSV 数据文件到 OceanBase
- 4.7 如何使用 DATAX 迁移 MySQL数据到 OceanBase
- 4.8 如何使用 OBDUMPER / OBLOADER 工具导出/导入 OceanBase 数据
- 4.9 如何使用 DATAX 迁移 OceanBase 数据到 MySQL/ORACLE
- 4.10 如何使用 CANAL 将 MySQL 数据实时同步到 OceanBase
结束语
加入教程直播群方式一:钉钉群号3255 4020
加入教程直播群方式二:扫码下方二维码加入