我将20 GB的数据库导入MySQL 5.7服务器。转储是在同一台服务器上进行的。操作系统是Ubuntu 16.04
问题在于,它的运行速度非常慢。
这是我的MySQL配置:
[mysqld]
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /nvme/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
innodb_buffer_pool_size = 18120M
innodb_lock_wait_timeout= 99999999
innodb_change_buffering=all
innodb_flush_log_at_trx_commit=0
innodb_log_file_size=1G
innodb_autoinc_lock_mode=2
#key_buffer = 4048M
max_allowed_packet = 1024M
thread_stack = 256M
thread_cache_size = 1024
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover-options = BACKUP
query_cache_limit = 4M
query_cache_size = 512M
log_error = /var/log/mysql/error.log
expire_logs_days = 10
max_binlog_size = 1G
这是来自另一个文件的Mysqldump配置
[mysqldump]
quick
quote-names
max_allowed_packet = 1024M
这是我用来创建转储的命令
mysqldump --order-by-primary --opt --max-allowed-packet=64M dbName | gzip > dbDump.sql.gz"
这一个导入它
pv dbDump.sql.gz | { echo "set sql_log_bin=0;SET autocommit=0;SET unique_checks=0;SET foreign_key_checks=0;"; zcat; \
> echo "SET unique_checks=1;SET foreign_key_checks=1;SET autocommit=1;COMMIT;";} | mysql -uuser -ppwd awesomeDb
使用autocommit = 1导入需要48分钟,autocommit = 0则需要53分钟。
现在是硬件。
I'm running an Intel 4690K on 3.5Ghz , 4 cores
32 gigs of RAM.
The Dump is located on a Samsung 850 SSD.
The Database has a dedicated m.2 NVMe SM961 128 drive. Write speeds in Crystalmark for randomized writes are ~200-300MBps.
Mysqld的资源使用情况(由KSysGuard报告)
Ram is constantly on 20.5GB
CPU is 15-19%, so it's not using a whole core.
The NVMe drive is being written on at 10-40 MiBPS. (had the same speeds on the 850 250GB). It's performing 50-200 read accesses per second
我尝试了MySQL服务器docs的所有解决方案。试过添加set sql_log_bin = 0; SET autocommit = 0; SET unique_checks = 0; SET foreign_key_checks = 0;在转储之前。但是数据库仍然需要很长时间才能导入。
我知道从服务器复制文件是最快的方法。但我的目标是加快转储导入。
我不知道瓶颈在哪里。因为明显 - 没有任何东西被最大化。
编辑输入:
DB Schema是大约200个表,有386个外键(和200个索引)。没有表有超过10M行,最大表的大小是2.3,2.0,1.3,1.3,0.9 GB。
编辑:
在测试期间始终禁用查询缓存。另外,今天我导入了一个12GB的DB(相同的DB,只是更小)。花了34分钟。虽然数据库本身几乎小了2倍。
答案 0 :(得分:0)
query_cache_size = 512M
非常糟糕。对于来自转储的每个INSERT
,必须清除查询缓存中有关表的任何条目。当然,没有任何东西,但代码实在太愚蠢了。
关闭负载的QC,或将尺寸降低到不超过50M。
如果您使用的是MyISAM,请不要这样做。转移到InnoDB。
答案 1 :(得分:0)
恢复mysqldump文件自然只使用一个线程,并按顺序导入数据,一个接一个地导入数据。
我建议使用mysqldump --tab
(以及其他选项)将每个表转储到两个文件中:一个用于模式定义的.sql文件和一个用于原始数据的文本文件。
然后,您可以使用mysqlimport --use-threads=4
导入数据文件(在创建所有表之后)(使用其他选项来处理所有文件),这样您就可以同时加载多个表。
此方法还会跳过所有使用SQL的导入,从而减少了大量的SQL解析开销。
您也可以尝试使用mydumper & myloader,它们是支持转储和恢复并行操作的开源社区工具。我不知道它是否作为预先构建的二进制文件可用,您可能必须从源代码构建它以获取最新版本。
最快的恢复解决方案是使用Percona XtraBackup进行物理备份。恢复根本不需要导入,只需将文件放在适当位置并启动MySQL服务器即可。但将数据导入现有的MySQL服务器是不可能的。恢复物理备份需要关闭MySQL服务器并覆盖已经存在的任何数据。