Mysql LOAD DATA INFILE 导入大文件的方法

缘起:

目前有一个5000千万行的数据文件data.csv,需要导入mysql进行测试。

直接运行

LOAD DATA INFILE ‘data.csv’ INTO TABLE test.mytab FIELDS TERMINATED BY ‘\t’ ENCLOSED BY ” LINES TERMINATED BY ‘\n’;

N个小时都没有完成。使用pstack以及vmstat发现mysql还是在卖力的工作。而取消操作之后,很长时间都无法使用SQL操作这个表。

通过执行

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
查看mysql一直有一个线程执行一直在回滚操作,回滚操作锁定了这个表,
这个大数据量的LOAD DATA INFILE操作是一个巨大的事务。

以此推理,使用load data语句导入大数据量文件,会有以下问题:

1、在binlog文件中写大量的binary log,会严重影响到主从复制,导致备库复制严重滞后。

2、表空间积累一堆undo日志,清理线程不能清理,大部分的操作都会变慢,包括简单的select操作。

3、如果导入发生异常,innoDB引擎的回滚速度很慢,那么回滚过程会很长,还不如清理数据之后重新导入耗时短。

解决措施:

1、使用perl脚本将文件按10万进行分割,写入管道文件:

perl mk-fifo-split data.csv  –fifo /tmp/fifo –lines 100000

2、用脚本不断读取管道,进行每批次10万行的导入操作:

while [ -e /tmp/fifo ];
do time mysql -u root -phitv -e "LOAD DATA INFILE '/tmp/fifo' INTO TABLE test.mytab FIELDS TERMINATED BY '\t' ENCLOSED BY '' LINES TERMINATED BY '\n';"
sleep 1;
done

每10万条插入时间缩减为10秒左右,且每批次导入时间增长较缓慢。

继续优化:

while [ -e /tmp/fifo ];
do time mysql -u root -phitv -e "set foreign_key_checks=0; set sql_log_bin=0; set unique_checks=0;LOAD DATA INFILE '/tmp/fifo' INTO TABLE test.mytab FIELDS TERMINATED BY '\t' ENCLOSED BY '' LINES TERMINATED BY '\n';"
sleep 1;
done

速度还是很慢,数据表有多个索引字段,删除表中索引约束之后,导入每10万条变成0.4秒左右。

由tcp_tw_recycle引发的问题

1、现场问题:

客户端A通过NAT网关访问应用服务成功,而客户端B通过NAT网关访问
应用服务 经常性出现connect失败。在服务端抓包发现:服务端已经收到了syn包,但没有回复synack包;客户端A 关闭了tcp_tw_recycle,而客户端B开启了
tcp_tw_recycle;据当事人称开启 tcp_tw_recycle 是为了减少tcp的TIME_WAIT状态。

阅读更多

系统设计之限流

对于有庞大用户量的系统必然会遇到某一个时段业务高峰。由于前期性能预估不足、业务量急增,而某个系统组件性能存在瓶颈,该组件无法工作,整个系统请求拥堵。

在高可用系统中,限流是解决此类问题的一个性价比很高的技术手段。通过限流,在大量请求的高压之下仍可以在保证整个系统在其能力范围内稳定的工作。

阅读更多

清除僵尸连接的妙招

一个网络服务程序如果没有开启tcp keepalive机制,那么遇到客户端与服务端网络故障,导致断链接的TCP FIN报文丢失的情况,服务端的对应链接就不会释放,一直积累,当超过该服务的最大允许链接数时,就无法接入服务了。这时最简单的方法是直接重启服务。但是如果是极其重要的业务服务,不能容忍重启带来的业务损失,那么该怎么办呢?

阅读更多

系统稳定性设计之超时和重试

设置请求超时本身很不起眼,但是需要强调一下超时的意义,“小偏方治大病”。

随着业务越来复杂,业务后台服务会依赖其他业务服务以及基础服务,如消息队列、redis、mysql数据库等。网络总是不可靠,各种服务总是不可靠的。
这些被依赖的服务总会出现各种各样性能不足、功能不可用等情况,此时我们的服务调用其他服务资源时,若没有设置超时,则依赖的服务一个点故障,就可以拖垮整个服务。

阅读更多

worse is better

做系统设计和开发时,需要在既有需要约束下,反复考虑如何有最少的组件、最清晰的逻辑构建系统,甚至为了简洁性、可以牺牲一少部分需求。
因为我们对问题的理解总是随着对问题的思考而越来越深入;我们在做选择时受限于当时对问题的理解,很难真正做出最合适的决策。遵循“事缓则圆” 的原则,能尽量弄清楚那些是自己已经清楚的部分,那些是自己尚不能确定的部分;在决策时遵从简单粗暴原则寻找一个次优的决策;在适当的时候能进行重构对自己当初的设计和实现进行修正(甚至抛弃),利用对问题域更多的理解来做出一个比你上次决策显得更好更合理的决策。

现实是在许多环境下很少有人有勇气承认自己做的不好,需要改进。于是整个系统就这样腐烂下去。

阅读更多