0
点赞
收藏
分享

微信扫一扫

load_data工具的使用

load_data工具的使用

1、原理

  • noshard表和global表对数据文件不切分,只是执行导入sql,区别是对于noshard表只导入一个set,global导入所以set。使用透传语法。
  • 导入时使用多线程,根据定义的块大小对数据文件进行位置选取,线程获取文件块位置后通过多线程执行load data infile导入。
  • groupshard表,subshard二级分区表和range/list一级分区表都会进行多线程的切分和导入,区别在于切分阶段groupshard表使用每行数据的shardkey进行hash,然后结合每个set的hash范围获得要发往的setname,进而切分为子文件进行通过load_data infile导入。subshard二级分区表会在groupshard表的基础上再次细化每个set的数据文件,按照分区范围将发往同一个set的文本再次细化为发往一个set的某一个分区的文件。range/list表则根据分区范围或者list范围定位到要发往的set,再切分为文件通过load_data infile发送。

2、架构设计

主线程根据设定的块大小(假设为64k)先获取64k大小的分块,再往后定位到行结束符,从而获得一个分块range=(begin_pos,end_pos)。由此将一个文件分为多个range存在队列里。再根据设定的线程数生成多个线程,每个线程从队列里取得一块数据的位置,判断表类型如为noshard或者global则直接发送该块数据内的数据,不生成中间文件。如为shard,一级分区表,二级分区,则按行读取该块数据内的数据,根据发往的set/分区的不同将数据切分到子文件中,再通过loaddata infile发送。线程处理完一个range后,如导入不出现警告或者报错则删除子文件,再处理其他range。如出现警告或者报错,则将报错子文件存于./tmp_error目录下,将警告子文件存放在./tmp_warning目录下,再取其他range继续处理。

3、 功能介绍

\- 支持noshard单表,global复制表,groupshard分表,subshard二级分区表以及range/list一级分区表的导入。

\- 支持进度条显示,包括实时导入记录数,总进度百分比,实时导入速率,耗时等。

\- 支持命令行导入(类似--ip=127.0.0.1)和文件参数导入(配置文件load.ini)

\- 支持自定义导入线程,分割块(chunk_size)大小等参数。

\- 支持导入部分字段,使用 --fields ="(id,k,@jump,pad)"参数跳过第三列数据只导入3个字段,或者--fields ="(id,k)"导入两个字段。

\- 支持参数设定日志等级,当日志等级设置为debug时(--log_level=2)可以查看详细的报错信息,定位到具体的行。报错或者报警告的子文本会报错在./tmp_data目录下。

\- 支持后台运行,通过设置--is_daemon=true开启后台模式,开启后可通过信号量(kill -s SIGUSR1 pid)的方式获得实时的导入进度。同时log日志每隔5min打印进度。

\- 支持执行前置sql,通过参数--prefix_sqls能在导入前执行sql,对于设置net_read/write_timeout等参数也可以在此后追加,以分号隔开每个sql。目前默认运行

"SET unique_checks = 0; SET foreign_key_checks = 0;SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"

\- 支持文件夹导入

\- 支持位置参数

\- 支持自动重试

\- 支持断点续传

\- 支持设定出错时是退出线程还是继续执行其他range导入

4、执行条件

\1. Load_data必须放置在proxy的bin目录下,具有可执行权限。

注:如要迁移到其他机器上使用,请将bin/share/目录一起迁移即可。

\2. 执行load_data的用户需要有bin目录下的创建目录、创建文件的权限。

\3. TDSQL实例需要做如下设置(导入结束后需手动恢复):

\* 调整复制模式为异步复制

\* 开启Set免切设置

\* 尽量调大数据库超时参数net_read_timeout/net_write_timeout/innodb_lock_wait_timeout

\* 尽量调大数据库binlog拦截参数binlog_write_threshold

\* 数据库关闭双1参数sync_binlog/innodb_flush_log_at_trx_commit

\* 数据库开启LOCAL方式导入数据参数local_infile

\* 数据库磁盘空间检查(预计总量占用2~3倍CSV文件空间)

\* MySQL 8.0占用内存过多,需要预留足够内存

5、导入指令

导入指令有3种:命令行导入,位置参数导入和配置文件导入(执行./load_data 可以看到help信息。)

  • 命令行导入:

./load_data --ip=127.0.0.1 --port=15026 --user=test --password=test --db_table=loaddata.sbtest_shard --file=sbtest_4l.txt --field_enclosed=" " --field_terminated=" " --thread_num=128

  • 位置参数导入(支持mode2和mode3)

./load_data mode1 127.0.0.1 3336 test test123 shard.table '/tmp/datafile' '' ''

  • 配置文件导入:

./load_data –config=load.ini

其中load.ini格式参考文件load.ini

6、配置参数说明

常用参数:

--help 说明:获取帮助信息

--ip=127.0.0.1 说明:proxy的ip地址

--port=15006 说明:proxy的端口

--user=test 说明:登陆proxy的用户名

--password=test 说明:登陆proxy的秘密

--db_table=test.test 说明:指定需要导入的库名和表名,如test.sbtest

--file=data200M.txt 说明:导入文件的位置,如--file=/data2/load_new/2.txt;当为目录时,表示文件夹导入。

--field_terminated=" " 说明:字段间隔符,如空格(" "),逗号(","),制表符("\t" )等

--field_enclosed=" " 说明:字段括起符,如为空(" "),双引号号("\"")等,注:双引号在命令行和配置文件中有区别

--fields_optionally_enclosed=false 说明:是否选择性括住CHAR、VARCHAR和TEXT等字符型字段

--thread_num=1 说明:导入线程数,默认值为1

--chunk_size=10 说明:导入块大小(KB)默认值为与文件大小相关的一个分段函数

--config=load.ini 说明:配置文件导入模式,配置此参数后,其他直接读取配置文件的参数配置。

不常用参数:

--escaped_by="\\" 说明:转义字符,默认值为反双斜线

--lines_terminated="\n" 说明:行间隔符

--prefix_sqls="SET foreign_key_checks" 说明:前置运行sql,默认运行"SET unique_checks = 0", "SET foreign_key_checks = 0","SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"这3条sql

。注:prefix_sqls在命令行和配置文件中有区别

--replace_duplicates=false 说明:是否开启替换模式,替换已存在的记录

--fields="(id,k,@jump,pad)" 说明: 导入部分字段(id,k,@jump,pad)

--log_level=5 说明:设置日志等级,默认为LOG_INFO,开启debug日志请将等级设置为2

--is_daemon=false 说明:是否开启后台运行模式,默认关闭

--retry=1 说明:设置重试模式。-1表示当导入出现错误时一直重连;0表示不重试;1表示重试一段时间,需结合retry_time一起使用

--retry_time=1 说明:当retry为1时,指定重试时间,单位是小时

--skip_error=0 说明:是否跳过错误,即当发生错误时,线程是退出(0)还是跳过错误直接执行其他range(1)。

--Breakpoint=0 说明:是否开启断点重传

7、问题定位

\+ 问题描述: mysql_embedded: Unknown error 1146

could not initialize MySQL library 问题原因: load_data可执行文件未放在bin目录下

\+ 问题描述: load data failed, errmsg: ret: -1, errno: 2013: info: query error[gone away agin]

问题原因:导入连接中断,可以尝试降低线程数和块大小再重新导入。

\+ 问题描述:"Local_infile is OFF! Input /sets:allsets/set global local_infile='ON';"

问题原因:导入权限未开启,连接proxy,运行指令/sets:allsets/set global local_infile='ON';"

\+ 问题描述:配置文件设置参数prefix_sqls="CREATE DATABASE IF NOT EXISTS test",运行时query sql failed

问题原因:配置文件中prefix_sqls参数设置时,需要去掉双引号。

8、日志查看

\- 默认情况下,日志等级为LOG_INFO,只会显示info和warning,error信息,想要查看更多信息,可以通过--log_level参数将日志等级设为2,即可查看debug信息。

\- load_data会产生两个日志文件:文件名.discard.log和文件名.log

\* 文件名.discard.log:收集切分时shardkey不符合要求的数据行。比如当括起符为双引号时,如果导入数据中shardkey字段缺少半边引号94",或者""," "

时,会认为数据格式有问题,将该条数据写入discard.log

\* 文件名.log:导入阶段报错或者警告的行会在文件名.log中体现,同时该日志也会有整体导入进度的信息,导入进度每隔5min打印一次,尾部也会打印进度信息。

9、其他

\- load_data导入工具需要依赖proxy使用,所以需要放置在proxy的bin目录下使用,通过参数连接proxy完成导入。

\- Chunk_size的自适应使用分段函数,当用户未设置chunk_size参数时,

当文件<=10k时,chunk_size=1k

当10k<文件<100M时,chunk_size=(文件/10k)k

当100M<文件<=10G时,chunk_size=(文件/100k)k

当10G<文件时,chunk_size=100M

\- 配置文件中,如果括起符为双引号时,参数设置和命令行稍有区别,配置文件为 --field_enclosed=""",区别于命令行的--field_enclosed="\""

\- prefix_sqls参数的设定在使用配置文件时,需要去掉引号。

举报

相关推荐

0 条评论