如何导入1T数据到MYSQL数据库?

 问题:如何快速把1T数据,导入到mysql数据库中?

1、直接LOAD DATA INFILE

LOAD DATA INFILE 'path/to/bigfile.csv' INTO TABLE XXX_table;

这样会导致文件过大,主备复制断掉(备库跟不上),数据库CPU、内存等使用率冲高,而且效率也不太高。

2、分割成小文件 LOAD DATA INFILE 

LOAD DATA INFILE 'path/to/smallfile1.csv' INTO TABLE xxx_table;
LOAD DATA INFILE 'path/to/smallfile2.csv' INTO TABLE xxx_table;
LOAD DATA INFILE 'path/to/smallfile3.csv' INTO TABLE xxx_table;
LOAD DATA INFILE 'path/to/smallfile4.csv' INTO TABLE xxx_table;
LOAD DATA INFILE 'path/to/smallfile5.csv' INTO TABLE xxx_table;
...

这样文件小了,数据库CPU、内存等使用率冲高,得到缓解了,导入效率提提高了一些,但是主备复制还是会发生断掉(备库跟不上)。

3、能否看看导入每个文件时主备延迟多少,然后导入后sleep一下是不是就好了?

主备延迟查看方法:

①备库SHOW SLAVE STATUS。

SHOW SLAVE STATUS\G;

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: master_host
                  Master_User: replication_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 154
               Relay_Log_File: relay-bin.000001
                Relay_Log_Pos: 154
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
          Exec_Master_Log_Pos: 154
        Seconds_Behind_Master: 139

Seconds_Behind_Master  就是主备延迟秒数,如果有复制延迟(Seconds_Behind_Master 不为 0),则表示备库还没有完全追上主库。

问题是生产上一般没办法直接访问备库,能访问一般也是只能select。于是继续向其他办法。

注意:即使能够读到延迟秒数,也不能直接按照这个秒数sleep,因为这是数据库的一个预估值,不太准确,所以能够获取到延迟秒数,建议做法是sleep 一定秒数(比如10秒),然后在查询这个值,在判断是否还需要继续sleep,直到主备复制延迟为0。

②能否通过,主库binlog大小评估需要sleep时间? 

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000012 | 107       | test_db      |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

mysql-bin.000012 是binlog正在写的文件名称,Position 是当前binlog记录的位置,即记录到107了。

那要怎么算生成了多少binlog呢?只需要在这个文件导入前后各执行一次就可以了。

文件导入前执行:

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154       | test_db      |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

文件导入后执行:

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 100      | test_db      |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

binlog跨文件了,再执行:SHOW BINARY LOGS;

SHOW BINARY LOGS;

+------------------+----------+
| Log_name         | File_size |
+------------------+----------+
| mysql-bin.000001 | 2000      | 
+------------------+----------+
| mysql-bin.000002 | 2000      | 
+------------------+----------+
| mysql-bin.000003 | 100       | 
+------------------+----------+

计算binlog大小:binlog_size = (2000-154) + 2000 + 100 = 3945

最后发现这个也不准确,因为这里面备库执行速度不仅取决于条数,还会受导入的数据量本身影响,即:越往后导入表的数据量越多速度会变慢。

③还有其他办法,来评估需要sleep时间? 

自己查询判断备库是否已经同步完成。操作方法:导入文件数据--->文件导入完成----->读取文件最后一条记录----->在主库查询确保能查询到记录------->备库查询直到能够查询到这条记录。

读取文件最后一行:

import org.apache.commons.io.input.ReversedLinesFileReader;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class ReadLastLineWithCommonsIO {
    public static void main(String[] args) {
        File file = new File("path/to/your/file.txt");

        try (ReversedLinesFileReader reader = new ReversedLinesFileReader(file, StandardCharsets.UTF_8)) {
            String lastLine = reader.readLine();
            System.out.println("Last line: " + lastLine);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

好处:能够精准判断备库什么时候同步完成,而且顺便检查了数据的准确性。

留个正在看到问题:主备复制延迟,不是可以使用备库多线程并行复制吗?这个并行复制原理又是怎样的?

大家有好的办法欢迎随时交流。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开发里面最懂数据库的光光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值