LoadData工具使用说明
最近更新时间: 2024-10-17 17:10:00
依赖
依赖库信息
ubuntu系列:apt-get install expat
centos系列:yum install expat expat-devel -y
原理
noshard表和global表对数据文件不切分,只是执行导入sql,区别是对于noshard表只导入一个set,global导入所有set。使用透传语法。
导入时使用多线程,根据定义的块大小对数据文件进行位置选取,线程获取文件块位置后通过多线程执行load data infile导入。
groupshard表、subshard二级分区表和range/list全局分区表都会进行多线程的切分和导入,区别在于切分阶段groupshard表使用每行数据的shardkey进行hash,然后结合每个set的hash范围获得要发往的setname,进而切分为子文件进行通过loaddatainfile导入。subshard二级分区表会在groupshard表的基础上再次细化每个set的数据文件,按照分区范围将发往同一个set的文本再次细化为发往一个set的某一个分区的文件。range/list表则根据分区范围或者list范围定位到要发往的set,再切分为文件通过load data infile发送。
架构设计
主线程根据设定的块大小(假设为64k)先获取64k大小的分块,再往后定位到行结束符,从而获得一个分块range=(begin_pos,end_pos)。由此将一个文件分为多个range存在队列里。再根据设定的线程数生成多个线程,每个线程从队列里取得一块数据的位置,判断表类型如为noshard或者global则直接发送该块数据内的数据,不生成中间文件。如为shard,一级分区表,二级分区,则按行读取该块数据内的数据,根据发往的set/分区的不同将数据切分到子文件中,再通过load data infile发送。线程处理完一个range后,如导入不出现警告或者报错则删除子文件,再处理其他range。如出现警告或者报错,则将报错子文件存于./tmp_error目录下,将警告子文件存放在./tmp_warning目录下,再取其他range继续处理。
功能介绍
支持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导入
支持参数开启文件列数与字段数检查功能
执行条件
执行load_data的用户需要有bin目录下的创建目录、创建文件的权限。
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文件空间)
需要预留足够内存
导入指令
导入指令有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
位置参数导入(支持mode0/mode1/mode2/mode3/mode4):
/load_data mode0/mode1 proxy_host proxy_port user password db_table shardkey_index file field_terminate filed_enclosed [split_size] [escaped by]
example:
example:./load_data mode1 10.10.10.10 3336 test test123 shard.table 1 '/tmp/datafile' ' ' ''
mode0: 只拆分数据,不进行数据导入。
mode1:用insert ignore导入的方式,并且skip_error是false,遇见错误直接退出。
mode2:用insert ignore导入的方式,并且skip_error是true,遇见错误不停止。
mode3:用replace 导入方式,并且skip_error是false,遇见错误直接退出。
mode4:用replace 导入方式,并且skip_error是true,遇见错误不停止。
配置文件导入:
./load_data –config=load.ini
其中load.ini格式参考文件load.ini
配置参数说明
常用参数:
--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=10 说明:当retry为1时,指定重试时间,单位是小时,默认一个小时
--skip_error=0 说明:是否跳过错误,即当发生错误时,是停止导入(0)还是跳过错误(1)。
--Breakpoint=0 说明:是否开启断点重传
--client_timeout=10 说明,mysql api的超时参数,默认是10s.
--column_check=0 说明:是否开启字段检查功能,注意此功能与导入部分字段功能冲突,无法同时使用
举例说明
假设有表test:
CREATE TABLE `test` (
`a` int(30) NOT NULL,
`b` int(30) DEFAULT NULL,
`c` int(30) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
已有数据文件test1.txt格式如下:
"1","11","111"
"2","22","222"
将test.txt导入test表可以使用下面指令开启2个线程导入:
./load_data --ip=127.0.0.1 --port=15009 --user=test --password=test --db_table=loaddata.test --file=/data1/test1.txt --field_enclosed="\"" --field_terminated="," --thread_num=2;
已有数据文件test2.txt格式如下:
"1","aaa","11","111"
"2","bbb","22",,"222"
想要跳过test2.txt的第二列数据,将数据导入表test,可以使用以下指令:
./load_data --ip=127.0.0.1 --port=15009 --user=test --password=test --db_table=loaddata.test --file=/data1/test1.txt --field_enclosed="\"" --field_terminated="," --thread_num=2 --fields="(a,@jump,b,c)";
已有数据文件test3.txt格式如下:
"1",,"111"
"2",,"222"
想将第二列的空值导入表中为NULL,可以使用fields参数来实现,具体指令如下:
./load_data --ip=127.0.0.1 --port=15009 --user=test --password=test --db_table=loaddata.test --file=/data1/test3.txt --field_enclosed="\"" --field_terminated="," --thread_num=2 --fields="(a, @b, c) SET b = NULLIF(@b,'')";
问题定位
问题描述: 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参数设置时,需要去掉双引号。
日志查看
默认情况下,日志等级为LOG_INFO,只会显示info和warning,error信息,想要查看更多信息,可以通过--log_level参数将日志等级设为2,即可查看debug信息。
load_data会产生两个日志文件:文件名.discard.log和文件名.log
文件名.discard.log:收集切分时shardkey不符合要求的数据行。比如当括起符为双引号时,如果导入数据中shardkey字段缺少半边引号94",或者""," "时,会认为数据格式有问题,将该条数据写入discard.log。如果开启column_check后,多列或者少列的错误行会记录到此日志。
文件名.log:导入阶段报错或者警告的行会在文件名.log中体现,同时该日志也会有整体导入进度的信息,导入进度每隔5min打印一次,尾部也会打印进度信息。
其他
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参数的设定在使用配置文件时,需要去掉引号