【发布时间】:2020-05-20 06:48:57
【问题描述】:
目前,我有一个服务器 A,它拥有大约 250 亿条记录(几 TB 大小),结构如下:
CREATE TABLE `table_x` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`a1` char(64) DEFAULT NULL,
`b1` int(11) unsigned DEFAULT NULL,
`c1` tinyint(1) DEFAULT NULL,
`LastUpdate` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `idxb1a1` (`b1`,`a1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
由于数据变得太大,我正在尝试将这些记录迁移到具有相同架构结构的服务器 B,使用按列 id 的升序批量插入 10K 记录(例如 INSERT INTO yourtable VALUES (1,2), (5,5), ...;)。
最初,插入速度非常快 - 但是,它逐渐变慢,现在大约需要 10 秒才能批量插入 10K 记录(即 1K/秒)。 我猜是因为它需要在每次插入后更新索引。
在开始迁移之前,我在服务器 B 上做了如下配置:
innodb_flush_log_at_trx_commit=2SET unique_checks=0;-
autocommit=0并每 50K 提交一次
服务器 B 硬件配置:
- 300GB+ 内存(240GB 用于
innodb_buffer_pool_size) - 用于数据存储的 SSD
服务器 B my.cnf:
innodb_buffer_pool_size=240G
innodb_buffer_pool_instances=64
innodb_page_cleaners=32
innodb_purge_threads=1
innodb_read_io_threads=64
innodb_write_io_threads=64
innodb_use_native_aio=0
innodb_flush_log_at_trx_commit=2
innodb_doublewrite=0
innodb_autoinc_lock_mode=2
innodb_file_per_table=1
max_connections=10000
skip_name_resolve=1
tmp_table_size=134217728
max_heap_table_size=134217728
back_log=1000
wait_timeout=900
innodb_log_buffer_size=32M
innodb_log_file_size=768M
还有什么我可以做或配置来加快插入速度的吗?
更新 #1:
我尝试将记录迁移到服务器 B 的原因是因为我想将数据拆分/分片到几台服务器(使用 MariaDB SPIDER 引擎分片解决方案)。因此,涉及发送数据快照或直接复制数据的解决方案似乎不可行。
【问题讨论】:
-
您猜测索引是原因;也许尝试删除 idxb1a1 索引,并在加载所有数据后读取它? (这将复制整个表,因此需要足够的额外磁盘空间)。顺便说一句,在您进行迁移时,似乎是升级到 utf8mb4 的绝佳机会。
-
@ysth 删除索引和重建的时间会比实际迁移时间长吗?
-
您是否考虑过基于文件的副本? (例如,关闭服务器并复制数据目录/使用备份/...)
-
@Solarflare 无法关闭,因为服务器正在生产,我想减小表中的记录大小(这意味着我不能简单地复制和粘贴)。
标签: mysql innodb bulk insertion