mysql load data infile 数据会部分丢失

2016-06-05 17:45:40 +08:00
 MonkeyDLuffy

多线程使用 load data infile 时 发现插 50w 数据 数据库只有十几万 框架使用的是 mybatis 使用拦截器拦截底层 sql 然后通过流去写数据库

一开始认为是线程的问题 在插入数据的方法上加了 同步锁 发现还是只有十几万数据

现在怀疑是底层数据库 io 的问题

不知道有什么好思路吗?谢谢

2588 次点击
所在节点    MySQL
8 条回复
notgod
2016-06-05 19:00:55 +08:00
#1 Check 硬盘是不是有逻辑坏道
#2 比较 2 次 Load 中断的地方是不是一致
#3 比较 2 次 Load 插入的条目是不是一致
#4 将 50W 的 file, split 为 10w / 个 然后一个一个来 试试
最后就差不多可以定位出问题在哪里了
load data infile 文件 和 my.cnf 里的有个什么 size / time 也有一定关系

IO 基本不会有问题
MYSQL 比较成熟 有人做数据仓储 N 亿级的数据测试也无问题
iyaozhen
2016-06-05 19:46:23 +08:00
这种情况很可能是中间哪个数据不合法,写入不了。可以加个 ignore 参数
BOYPT
2016-06-05 19:46:39 +08:00
公司也有台机器也是这么弄的,我配置了 crontab 自动入库,然而时不时找我说弄到一半就没在库里。
我登陆进去发现,因为 mysqld 占用内存太大被内核 kill 了
notgod
2016-06-05 19:48:23 +08:00
@BOYPT
这个有遇到过 好好的 mysql 挂了 有检查 一堆内存耗尽的日志
后来写了个监控脚本 一发现 mysql 进程不存在 就启动下
MonkeyDLuffy
2016-06-06 08:31:40 +08:00
@notgod @iyaozhen @BOYPT 谢谢了 我去试试
MonkeyDLuffy
2016-06-06 08:37:44 +08:00
@notgod 目前是 50w 数据 存在一个 array 里面 开 50 个线程 每个线程负责 1w 数据的插入 使用 mybatis 拦截器 50 个线程的调用 转换成 50 次 load data infile 的调用
MonkeyDLuffy
2016-06-06 08:54:25 +08:00
如果用一个线程操作 数据库是不会少的 多个线程就会出现这个情况
BOYPT
2016-06-06 13:58:15 +08:00
我后来是在脚本里面用 split 命令分割了文件,分批 load data

TEMPDIR=$(mktemp -d)
/usr/bin/split -l 50000 --suffix-length=5 $LOG "$TEMPDIR/db_"

SQL=""
for LOG in $(ls $TEMPDIR); do
SQL=$SQL"LOAD DATA LOCAL INFILE '$TEMPDIR/$LOG' INTO TABLE tbl_log_infos FIELDS TERMINATED BY '^A' (fld_time, fld_ip, fld_domain, fld_url, fld_title, fld_referrer, fld_high_ratio, fld_wide_ratio, fld_color_depth, fld_language, fld_drcom_tag, fld_client);"
done

这样组合好一大堆 SQL 后再一次过喂给 mysql client

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/283663

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX