关于数据库:myloader导入更快吗并没有

6次阅读

共计 3230 个字符,预计需要花费 9 分钟才能阅读完成。

  • 0. 论断后行
  • 1. 背景介绍
  • 2. 测试过程
  • 3. 后果比照
  • 附录

myloader 还默认禁用 binlog 了

0. 论断后行

重要论断先说:导入大批量数据时,采纳 GreatSQL 8.0.32-24 中新增并行 load data 个性是最快的,对于该个性的形容详见:Changes in GreatSQL 8.0.32-24。

1. 背景介绍

前几天我用 MySQL 官网提供的 airportdb 库中的 weatherdata 表做测试,论断是相比原生快了约 5 倍。

群里有小伙伴反驳说用 myloader 更香,于是就有了本次测试。

因为 weatherdata 表较小,表空间只有 228MB,所以我改用 sysbench 表做测试,该表共 600 万行数据,表空间约 1.5GB,其余信息如下:

greatsql> show create table myload\G
*************************** 1. row ***************************
       Table: myload
Create Table:CREATE TABLE `myload` (
  `id` int NOT NULL AUTO_INCREMENT,
  `k` int NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_2` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=6194244 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

greatsql> show table status like 'myload'\G
*************************** 1. row ***************************
           Name: myload
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 5930876
 Avg_row_length: 233
    Data_length: 1385168896
Max_data_length: 0
   Index_length: 153894912
      Data_free: 7340032
 Auto_increment: 6194244
    Create_time: 2023-07-08 09:25:02
    Update_time: 2023-07-08 09:25:33
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci
       Checksum: NULL
 Create_options:
        Comment:

2. 测试过程

本次测试基于 GreatSQL 8.0.32-24 版本,其余相干信息如下:

# myloader 版本
$ myloader --version
myloader0.15.0-1, built against MySQL 5.7.42-46 with SSL support with GZIP

# MySQL Shell 版本
 JS > shell.version
Ver 8.0.32 for Linux on x86_64 - for MySQL 8.0.32 (MySQL Community Server (GPL))

默认开启 binlog + 双 1 + redo log + doublewrite buffer:

|binlog_rows_query_log_events |ON|
| innodb_buffer_pool_size | 8589934592|innodb_doublewrite |ON|
|innodb_flush_log_at_trx_commit |1|
|innodb_redo_log_capacity |2147483648|
|sync_binlog |1|

3. 后果比照

上面是几个不同导入形式的比照测试后果,每种形式我都测试至多 3 次,去除噪点数据后取平均值:

工具 耗时(秒) binlog 大小(MB) mysqld 内存增长(MB)
原生 load data 62.801741 1091 1536
并行 load data(chunk=4MB,并发 16 线程) 11.81 1091 1522
myloader(dump 时 chunk=64MB,load 时并发 16 线程) 29.358 2246 1868
myloader(dump 时 chunk=64MB,load 时并发 16 线程)+ 关 binlog 21.426
myloader(默认 + 开 binlog) 82.651 2246
myloader(默认 + 关 binlog) 62.830
util.importTable(默认,chunk=64MB,并发 8 线程) 16.0034 1091 1662

从这个测试后果能够看到几个比照关系:

  1. 原生 load data 最慢,因为是单线程的,它的耗时是并行 load data 的 5.32 倍;
  2. 原生 load data 的耗时是多线程模式下 myloader 的 2.14 倍;
  3. 原生 load data 的耗时是多线程模式下 util.importTable 的 3.92 倍;
  4. 当 myloader 没有开启并行(mydumper 备份时要先进行调配)的话,它的耗时是最久的,是并行 load data 的 7 倍,是多线程模式下 util.importTable 的 5.16 倍;
  5. 当 myloader 未开启 binlog 时(其默认行为,有 ” 舞弊 ” 嫌疑),其耗时是并行 load data 的 1.81 倍,是多线程模式下 util.importTable 的 1.34 倍;
  6. 最初,myloader 导入后造成的 binlog 文件最大,内存开销也最大。

综上,在 MySQL 8.0/GreatSQL 8.0.32 中,采纳 myloader 导入数据就不再是最优计划了,举荐采纳 GreatSQL 的并行 load data,或者 MySQL Shell 的 util.loadDump/util.importTable 导入,其本质也是采纳并行的思路,导入效率更高,额定的 binlog 和内存开销也更小。

最初,补充说下,myloader 导入时产生的 binlog 更多,是因为它的导入形式是重复执行 INSERT SQL,在 binlog_rows_query_log_events = ON 时,相比 load data 形式会产生更多 binlog。

附录

1. myloader 多分片形式导出

设置导出时进行分片,每个分片(chunk)10MB

$ mydumper -F 10 -S /data/GreatSQL/mysql.sock -T sbtest.myload -o /tmp/myload

最初的(未压缩)文件总大小为 1.2GB。

2. outfile 导出

greatsql> select * into outfile '/tmp/myload.csv' from myload;

很简略,平平无奇,最初的(未压缩)文件总大小为 1.1GB。

3. util.dumpTables 多分片形式导出 设置导出时进行分片,每个分片(chunk)64MB(默认值)

MySQL  localhost  JS > util.dumpTables("sbtest", ["myload"], "/tmp/myload", {threads:16, chunking:true, bytesPerChunk:"67108864"})

最初的(压缩后)文件总大小为 505MB。


Enjoy GreatSQL :)

## 对于 GreatSQL

GreatSQL 是实用于金融级利用的国内自主开源数据库,具备高性能、高牢靠、高易用性、高平安等多个外围个性,能够作为 MySQL 或 Percona Server 的可选替换,用于线上生产环境,且完全免费并兼容 MySQL 或 Percona Server。

相干链接:GreatSQL 社区 Gitee GitHub Bilibili

GreatSQL 社区:

社区博客有奖征稿详情:https://greatsql.cn/thread-100-1-1.html

技术交换群:

微信:扫码增加 GreatSQL 社区助手 微信好友,发送验证信息 加群

正文完
 0