我正在为大型网站迁移做一些准备工作。
数据库大小约为10GB,有几个表包含> 1500万条记录。不幸的是,由于我的职权范围之外的客户关系,这只出现在SQL格式的大型单个mysqldump文件中,但是你知道这是怎么回事。我的目标是最大限度地减少停机时间,从而尽可能快地导入数据。
我试图使用标准的MySQL CLI界面,如下所示:
$mysql database_name < superhuge_sql_file -u username -p
然而,这是超级慢的。
为了尝试加快速度,我已经使用awk将文件拆分为包含相关数据的每个表的块,并构建了一个小的shell脚本来尝试并行导入表,就像这样;
#!/bin/sh
awk '/DROP TABLE/{f=0 ;n++; print >(file="out_" n); close("out_" n-1)} f{ print > file}; /DROP TABLE/{f=1}' superhuge.sql
for (( i = 1; i <= 95; i++ ))
do
mysql -u admin --password=thepassword database_name < /path/to/out_$i &
done
值得一提的是,这是一个“使用一次并销毁”脚本(脚本中的密码等)。
现在,这可行,但目前在四核服务器上完成其他任何事情仍需要3个多小时才能完成。这些表确实并行导入,但不能同时导入所有这些表,并且在此过程中尝试通过CLI获取MySQL服务器信息非常慢。我不确定为什么但是在尝试使用相同的mysql用户帐户访问表时会挂起。 max_user_connections无限制。
我已在my.cnf中将max connections设置为500,但在此服务器上没有配置MySQL。
我有一个很好的搜索但是想知道是否有任何MySQL配置选项可以帮助加快这个过程,或者我错过的任何其他方法会更快。
答案 0 :(得分:4)
如果您可以考虑使用GNU parallel
,请查看wardbekker gist:上的此示例
# Split MYSQL dump file
zcat dump.sql.gz | awk '/DROP TABLE IF EXISTS/{n++}{print >"out" n ".sql" }'
# Parallel import using GNU Parallel http://www.gnu.org/software/parallel/
ls -rS *.sql | parallel --joblog joblog.txt mysql -uXXX -pYYY db_name "<"
将大文件拆分为单独的SQL文件,然后运行parallel
进行并行处理。
因此,要在GNU parallel中运行10个线程,您可以运行:
ls -rS data.*.sql | parallel -j10 --joblog joblog.txt mysql -uuser -ppass dbname "<"
在OS X上,它可以是:
gunzip -c wiebetaaltwat_stable.sql.gz | awk '/DROP TABLE IF EXISTS/{n++}{filename = "out" n ".sql"; print > filename}'
相关:Unix.SE上的Import sql files using xargs
答案 1 :(得分:0)
将转储文件导入服务器
$ sudo apt-get install pigz pv
$ zcat /path/to/folder/<dbname>_`date +\%Y\%m\%d_\%H\%M`.sql.gz | pv | mysql --user=<yourdbuser> --password=<yourdbpassword> --database=<yournewdatabasename> --compress --reconnect --unbuffered --net_buffer_length=1048576 --max_allowed_packet=1073741824 --connect_timeout=36000 --line-numbers --wait --init-command="SET GLOBAL net_buffer_length=1048576;SET GLOBAL max_allowed_packet=1073741824;SET FOREIGN_KEY_CHECKS=0;SET UNIQUE_CHECKS = 0;SET AUTOCOMMIT = 1;FLUSH NO_WRITE_TO_BINLOG QUERY CACHE, STATUS, SLOW LOGS, GENERAL LOGS, ERROR LOGS, ENGINE LOGS, BINARY LOGS, LOGS;"
可选:用于连接的命令参数
--host=127.0.0.1 / localhost / IP Address of the Import Server
--port=3306
可选软件包有助于更快地导入数据库SQL文件
with a progress view (pv)
Parallel gzip (pigz/unpigz) to gzip/gunzip files in parallel
更快地压缩输出
或者,您确实有一系列
的MySQL选项。导出
https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
导入
https://dev.mysql.com/doc/refman/5.7/en/mysql-command-options.html
配置
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html
这是我的服务器SSD四核上运行的示例my.cnf,通常会在8小时内导入100GB的DB文件。但是您可以调整服务器的设置,以帮助其更快地编写。
使用上面的链接检查每个配置变量,以将您的MySQL Server与变量和值进行匹配。
# Edit values to as per your Server Processor and Memory requirements.
[mysqld]
# Defaults
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
log-error = /var/log/mysql/error.log
datadir = /var/lib/mysql
log_timestamps = SYSTEM
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci
# InnoDB
innodb_buffer_pool_size = 48G
innodb_buffer_pool_instances = 48
innodb_log_file_size = 3G
innodb_log_files_in_group = 4
innodb_log_buffer_size = 256M
innodb_log_compressed_pages = OFF
innodb_large_prefix = ON
innodb_file_per_table = true
innodb_buffer_pool_load_at_startup = ON
innodb_buffer_pool_dump_at_shutdown = ON
innodb_autoinc_lock_mode = 2
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 360
innodb_flush_neighbors = 0
innodb_flush_method = O_DIRECT
innodb_io_capacity = 2500
innodb_io_capacity_max = 5000
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_monitor_enable = all
performance_schema = ON
key_buffer_size = 32M
wait_timeout = 30
interactive_timeout = 3600
max_connections = 1000
table_open_cache = 5000
open_files_limit = 8000
tmp_table_size = 32M
max_heap_table_size = 64M
# Slow/Error
log_output = file
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow_query.log
long_query_time = 10
log_queries_not_using_indexes = ON
log_slow_rate_limit = 100
log_slow_rate_type = query
log_slow_verbosity = full
log_slow_admin_statements = ON
log_slow_slave_statements = ON
slow_query_log_always_write_time = 1
slow_query_log_use_global_control = all
# Query
join_buffer_size = 32M
sort_buffer_size = 16M
read_rnd_buffer_size = 8M
query_cache_limit = 8M
query_cache_size = 8M
query_cache_type = 1
# TCP
max_allowed_packet = 1G
答案 2 :(得分:-1)
转储中的sql是否插入了多行?转储是否使用多行插入? (或者你可以预先处理它?)
This guy涵盖了很多基础知识,例如:
禁用MySQL索引,因此在导入运行之前:
ALTER TABLE `table_name` DISABLE KEYS;
然后在导入后将其更改回来:
ALTER TABLE `table_name` DISABLE KEYS;
使用MyISAM表类型时,请使用MySQL的INSERT DELAYED
命令,这样可以鼓励MySQL在数据库空闲时将数据写入磁盘。
对于InnoDB表,请使用这些额外命令以避免大量磁盘访问:
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET AUTOCOMMIT = 0;
最后这些:
SET UNIQUE_CHECKS = 1;
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;