V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
MonkeyDLuffy
V2EX  ›  MySQL

mysql load data infile 数据会部分丢失

  •  
  •   MonkeyDLuffy · 2016-06-05 17:45:40 +08:00 · 2580 次点击
    这是一个创建于 2883 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

    IO 基本不会有问题
    MYSQL 比较成熟 有人做数据仓储 N 亿级的数据测试也无问题
    iyaozhen
        2
    iyaozhen  
       2016-06-05 19:46:23 +08:00 via Android   ❤️ 1
    这种情况很可能是中间哪个数据不合法,写入不了。可以加个 ignore 参数
    BOYPT
        3
    BOYPT  
       2016-06-05 19:46:39 +08:00   ❤️ 1
    公司也有台机器也是这么弄的,我配置了 crontab 自动入库,然而时不时找我说弄到一半就没在库里。
    我登陆进去发现,因为 mysqld 占用内存太大被内核 kill 了
    notgod
        4
    notgod  
       2016-06-05 19:48:23 +08:00   ❤️ 1
    @BOYPT
    这个有遇到过 好好的 mysql 挂了 有检查 一堆内存耗尽的日志
    后来写了个监控脚本 一发现 mysql 进程不存在 就启动下
    MonkeyDLuffy
        5
    MonkeyDLuffy  
    OP
       2016-06-06 08:31:40 +08:00
    @notgod @iyaozhen @BOYPT 谢谢了 我去试试
    MonkeyDLuffy
        6
    MonkeyDLuffy  
    OP
       2016-06-06 08:37:44 +08:00
    @notgod 目前是 50w 数据 存在一个 array 里面 开 50 个线程 每个线程负责 1w 数据的插入 使用 mybatis 拦截器 50 个线程的调用 转换成 50 次 load data infile 的调用
    MonkeyDLuffy
        7
    MonkeyDLuffy  
    OP
       2016-06-06 08:54:25 +08:00
    如果用一个线程操作 数据库是不会少的 多个线程就会出现这个情况
    BOYPT
        8
    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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4007 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 04:13 · PVG 12:13 · LAX 21:13 · JFK 00:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.