mysql 超大 sql 文件导入过程

问题

最近遇到 2 个超大 sql 文件导入,好一通折腾

文档在哪里

调优参数太多,文档都看不过来

找到这些参数也费劲,

  1. ubuntu 在 /etc/mysql/mysql.conf.d/mysqld.cnf 中找到这个链接

    ......
    #
    # The MySQL  Server configuration file.
    #
    # For explanations see
    # http://dev.mysql.com/doc/mysql/en/server-system-variables.html
    
  2. centos 7 在 /etc/my.cnf 中找到这个链接

     # For advice on how to change settings please see
     # http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
    
  3. 官方调优文档
    14.15 InnoDB Startup Options and System Variables

  4. 耐心去阅读文档中那么多参数,需要勇气!

    最终我也是从这里 mysql使用多cpu抄来的

     # wzh 20230814
     # Set the number of CPUs to be used by MySQL 
     #  # to half of the total available CPUs
     innodb_thread_concurrency = 2
     #
     # Set the number of buffer pool instances
     innodb_buffer_pool_instances = 2
     # #  
     # Set the size of the query cache
     query_cache_size = 64M
     #
     # wzh 20230814 
     bulk_insert_buffer_size = 2G
     innodb_log_buffer_size = 2G
     innodb_autoinc_lock_mode = 2
     #
    

调优后 三种导入方式对比

  1. 方式一: 使用 mysql source 命令,直接导入一个大文件 (18G)

    为了统计用时和绘画内部优化,将实际mysqldump 文件包含到 all.sql

     # cat all.sql
     SET GLOBAL innodb_lru_scan_depth=256;
     set session sql_mode = 'ALLOW_INVALID_DATES';
     SET autocommit=0;
     SET unique_checks=0;
     SET foreign_key_checks=0;
     
     show global variables like 'innodb_lru_scan_depth';
     show variables like '%sql_mode%';  
     show variables like '%autocommit';
     show variables like '%unique_checks';
     show variables like '%foreign_key_checks';
     select now();
     -- one file 18G
     source /home/XXXdata/20191230_135112.sql;
     
     show global variables like 'innodb_lru_scan_depth';
     show variables like '%sql_mode%';
     show variables like '%autocommit';
     show variables like '%unique_checks';
     show variables like '%foreign_key_checks';
     select now();
    

    导入过程

     mysql > tee out-20230816.txt
     
     mysql > source /home/XXXdata/all.sql
    

    查看结果

     # cat out-20230816.txt
     ......
     | 2023-08-16 08:17:02 |
     ......
     | 2023-08-16 14:26:40 |
    

    总共耗时 6 小时 +

  2. 方式2⃣️: 使用shell 命令行后台任务,直接导入一个大文件 (18G)

    为了统计用时和绘画内部优化,将实际mysqldump 文件包含到 all.sql

     # cat all.sql 
     
     同前一个方式
    

    shell 后台任务

     # nohup  mysql -uroot -pPassword@123 --default-character-set=utf8 --force zXXX< /home/zXXX/all.sql > /home/out-20230817.txt 2>&1 &
    

    查看执行结果

     # cat out-20230817.txt
     ......
     2023-08-16 21:08:52
     ......
     2023-08-17 01:43:14
    

    用时 大约5 小时

  3. 方式三:SQLDumpSplitter切割 sql 文件 ( 每个 2G),使用 mysql source 命令,

    切割后的结果

     # ls *.sql -l
     -rw-r--r--. 1 root root 2147482476 8月  10 14:13 20191230_135112_0.sql
     -rw-r--r--. 1 root root 2147482521 8月  10 14:15 20191230_135112_1.sql
     -rw-r--r--. 1 root root 2147482263 8月  10 14:17 20191230_135112_2.sql
     -rw-r--r--. 1 root root 2147482371 8月  10 14:19 20191230_135112_3.sql
     -rw-r--r--. 1 root root 2147481971 8月  10 14:21 20191230_135112_4.sql
     -rw-r--r--. 1 root root 2147481699 8月  10 14:24 20191230_135112_5.sql
     -rw-r--r--. 1 root root 2147482612 8月  10 14:25 20191230_135112_6.sql
     -rw-r--r--. 1 root root 2147482594 8月  10 14:27 20191230_135112_7.sql
     -rw-r--r--. 1 root root  959044232 8月  10 14:28 20191230_135112_8.sql
     -rw-r--r--. 1 root root       1096 8月  16 14:14 all.sql
    

    all.sql

     # cat all.sql 
     SELECT DATABASE();
     select now();
     
     SET GLOBAL innodb_lru_scan_depth=256;
     set session sql_mode = 'ALLOW_INVALID_DATES';
     SET autocommit=0;
     SET unique_checks=0;
     SET foreign_key_checks=0;
     
     show global variables like 'innodb_lru_scan_depth';
     show variables like '%sql_mode%';  
     show variables like '%autocommit';
     show variables like '%unique_checks';
     show variables like '%foreign_key_checks';
     
     -- 00
     source /home/XXXdata/20191230_135112_0.sql ;
     -- 01
     source /home/XXXdata/20191230_135112_1.sql ;
     -- 02
     source /home/XXXdata/20191230_135112_2.sql ;
     -- 03
     source /home/XXXdata/20191230_135112_3.sql ;
     -- 04
     source /home/XXXdata/20191230_135112_4.sql ;
     -- 05
     source /home/XXXdata/20191230_135112_5.sql ;
     -- 06
     source /home/XXXdata/20191230_135112_6.sql ;
     -- 07
     source /home/XXXdata/20191230_135112_7.sql ;
     -- 08
     source /home/XXXdata/20191230_135112_0.sql ;
     -- ALL OK
     
     show global variables like 'innodb_lru_scan_depth';
     show variables like '%sql_mode%';
     show variables like '%autocommit';
     show variables like '%unique_checks';
     show variables like '%foreign_key_checks';
     
     SELECT DATABASE();
     select now();
    

    导入过程

     mysql > tee out-20230816.txt
     
     mysql > source /home/XXXdata/all.sql
    

    查看结果

     cat out-20230816.txt
     ......
     | 2023-08-16 08:17:02 |
     ......
     | 2023-08-16 13:15:21 | 
    

    总共耗时大约 5 小时

不调优,使用shell 命令行后台任务,直接导入一个大文件 (18G)

  1. 注释掉 my.cnf 中的调优, restart mysqld 服务

     # cat /etc/my.cnf
     
     # wzh 20230814
     # Set the number of CPUs to be used by MySQL 
     #  # to half of the total available CPUs
     # innodb_thread_concurrency = 2
     #
     # Set the number of buffer pool instances
     #innodb_buffer_pool_instances = 2
     #  
     # Set the size of the query cache
     # query_cache_size = 64M
     #
     # wzh 20230814 
     # bulk_insert_buffer_size = 2G
     # innodb_log_buffer_size = 2G
     # innodb_autoinc_lock_mode = 2
     # wzh 20230817
     # default-time-zone='Asia/Shanghai'
     explicit_defaults_for_timestamp=true
     log_timestamps=SYSTEM
    

    这就和安装完 mysql 5.7 之后,全部使用缺省值一样了

  2. shell 后台任务

     nohup  mysql -uroot -pPassword@123 --default-character-set=utf8 --force zXXX< /home/zXXX/all.sql > /home/out-20230817.txt 2>&1 &
    
  3. 查看结果

    cat /home/out-20230817.txt

    ...

    2023-08-18 14:50:11

    ...

    2023-08-18 19:43:37

    大约 5 小时,对比前面调优没有多大改进?

原因分析

决定实际完成快慢的,是该进程的 CPU 占用时间( cputime ) ?

以下是中途记录的一段

#  ps -eo pid,euid,euser,lstart,etime,cputime,cmd | grep mysql
...
 1877     0 root     Fri Aug 18 08:22:21 2023    01:20:06 00:00:59 mysql -uroot -px xxxxxxxxxx --default-character-set=utf8 --force zXXX
...

可以看到,本次运行时间 01:20:06 ,CPU 占用时间 00:00:59 ,说明效率很高!

之前曾经有过运行一晚上,实际 cputime 才 2 个小时,效率太低了!

总结

  1. 切割 SQL 文件并不能显著改善导入速度 (也许我切割到 2G 还是太大了,感觉应该 1G )

  2. 使用 shell 命令行 和 mysql source 命令要快大约 20%-30%

  3. 使用多 CPU 和增加缓存等办法,没有测出有明显效果

  4. 影响导入速度的还是导入过程中的错误忽略 sql_mode = 'ALLOW_INVALID_DATES' 和 autocommit 等优化

  5. shell 命令行 加上 --force

  6. 不要同时执行 2 个或以上大任务,互相影响!

  7. 提前判断好需要的硬盘空间,不要等最后才知道 disk full ,前功尽弃!

    查看磁盘空间

    df -h

    如果可以找到原始的数据库来源,查看数据库文件大小

    $ sudo du -sh /var/lib/mysql/zXXX

    26G /var/lib/mysql/zXXX

相关推荐
兩尛2 小时前
订单状态定时处理、来单提醒和客户催单(day10)
java·前端·数据库
web2u2 小时前
MySQL 中如何进行 SQL 调优?
java·数据库·后端·sql·mysql·缓存
Elastic 中国社区官方博客3 小时前
使用 Elasticsearch 导航检索增强生成图表
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
小金的学习笔记3 小时前
RedisTemplate和Redisson的使用和区别
数据库·redis·缓存
新知图书3 小时前
MySQL用户授权、收回权限与查看权限
数据库·mysql·安全
文城5213 小时前
Mysql存储过程(学习自用)
数据库·学习·mysql
沉默的煎蛋3 小时前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
呼啦啦啦啦啦啦啦啦3 小时前
【Redis】事务
数据库·redis·缓存
HaoHao_0103 小时前
AWS Serverless Application Repository
服务器·数据库·云计算·aws·云服务器
C语言扫地僧3 小时前
MySQL 事务及MVCC机制详解
数据库·mysql