提高mysql导入的速度
我有22GB
大型数据库。 我曾经以gzip格式备份mysqldump
命令。
当我提取gz文件时,它会产生16.2GB
的.sql
文件
当我尝试在我的本地服务器中导入数据库时,大约需要48小时导入。是否有一种方法可以提高导入过程的速度?
另外我想知道是否需要做任何硬件更改来提高性能。
当前系统configuration
Processor: 4th Gen i5 RAM: 8GB
#UPDATE
my.cnf如下
# # The MySQL database server configuration file. # # You can copy this to one of: # - "/etc/mysql/my.cnf" to set global options, # - "~/.my.cnf" to set user-specific options. # # One can use all long options that the program supports. # Run program with --help to get a list of available options and with # --print-defaults to see which it would actually understand and use. # # For explanations see # http://dev.mysql.com/doc/mysql/en/server-system-variables.html # This will be passed to all mysql clients # It has been reported that passwords should be enclosed with ticks/quotes # escpecially if they contain "#" chars... # Remember to edit /etc/mysql/debian.cnf when changing the socket location. [client] port = 3306 socket = /var/run/mysqld/mysqld.sock # Here is entries for some specific programs # The following values assume you have at least 32M ram # This was formally known as [safe_mysqld]. Both versions are currently parsed. [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] # # * Basic Settings # user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock port = 3306 basedir = /usr datadir = /var/lib/mysql tmpdir = /tmp lc-messages-dir = /usr/share/mysql skip-external-locking # # Instead of skip-networking the default is now to listen only on # localhost which is more compatible and is not less secure. bind-address = 127.0.0.1 # # * Fine Tuning # key_buffer = 16M max_allowed_packet = 512M thread_stack = 192K thread_cache_size = 8 # This replaces the startup script and checks MyISAM tables if needed # the first time they are touched myisam-recover = BACKUP #max_connections = 100 #table_cache = 64 #thread_concurrency = 10 # # * Query Cache Configuration # query_cache_limit = 4M query_cache_size = 512M # # * Logging and Replication # # Both location gets rotated by the cronjob. # Be aware that this log type is a performance killer. # As of 5.1 you can enable the log at runtime! #general_log_file = /var/log/mysql/mysql.log #general_log = 1 # # Error log - should be very few entries. # log_error = /var/log/mysql/error.log # # Here you can see queries with especially long duration #log_slow_queries = /var/log/mysql/mysql-slow.log #long_query_time = 2 #log-queries-not-using-indexes # # The following can be used as easy to replay backup logs or for replication. # note: if you are setting up a replication slave, see README.Debian about # other settings you may need to change. #server-id = 1 #log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M #binlog_do_db = include_database_name #binlog_ignore_db = include_database_name # # * InnoDB # # InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. # Read the manual for more InnoDB related options. There are many! # # * Security Features # # Read the manual, too, if you want chroot! # chroot = /var/lib/mysql/ # # For generating SSL certificates I recommend the OpenSSL GUI "tinyca". # # ssl-ca=/etc/mysql/cacert.pem # ssl-cert=/etc/mysql/server-cert.pem # ssl-key=/etc/mysql/server-key.pem [mysqldump] quick quote-names max_allowed_packet = 512M [mysql] #no-auto-rehash # faster start of mysql but no tab completition [isamchk] key_buffer = 512M # # * IMPORTANT: Additional settings that can override those from this file! # The files must end with '.cnf', otherwise they'll be ignored. # !includedir /etc/mysql/conf.d/
正在上传3天,现在已经导入了9.9 GB。 数据库同时具有MyISAM
和InnoDB
表。 我可以做些什么来改善import业绩?
我试图用mysqldump
以gz格式分别导出每个表格,并通过执行下面的代码的PHP脚本导入每个表格
$dir="./"; $files = scandir($dir, 1); array_pop($files); array_pop($files); $tablecount=0; foreach($files as $file){ $tablecount++; echo $tablecount." "; echo $file."\n"; $command="gunzip < ".$file." | mysql -u root -pubuntu cms"; echo exec($command); }
有很多参数丢失,要充分了解问题的原因。 如:
- MySQL版本
- 磁盘types和速度
- 在启动MySQL服务器之前在服务器上释放内存
- iostat在mysqldump之前和之后的输出。
- 您首先使用什么参数来创build转储文件。
还有很多。
所以我会试着猜测你的问题是在磁盘上,因为我有150个MySQL实例,我用其中一个3TB的数据pipe理,通常磁盘是问题
现在解决scheme:
首先 – 你的MySQL没有configuration为最佳性能。
您可以阅读有关在Percona博客文章中configuration的最重要的设置: http ://www.percona.com/blog/2014/01/28/10-mysql-settings-to-tune-after-installation/
特别是检查参数:
innodb_buffer_pool_size innodb_flush_log_at_trx_commit innodb_flush_method
如果你的问题是磁盘 – 从同一个驱动器读取文件 – 正在使问题变得更糟。
而如果你的MySQL服务器开始交换,因为它没有足够的RAM可用 – 你的问题变得更大。
您需要在还原过程之前和之后在您的计算机上运行诊断程序,以便弄清楚。
此外,我可以build议你使用另一种技术来执行重build任务,其工作比mysqldump更快。
这是Percona Xtrabackup – http://www.percona.com/doc/percona-xtrabackup/2.2/
您将需要使用它创build备份,并从中恢复,或者直接使用stream选项从正在运行的服务器重build。
此外,从5.5开始的MySQL版本 – InnoDB比MyISAM执行得更快。 考虑改变你的所有表。
以所描述的方式进行转储和恢复将意味着MySQL在数据导入时必须完全重build索引。 它也必须每次parsing数据。
如果你能以MySQL已经理解的格式复制数据文件,效率会更高。 这样做的一个好方法是使用Percona的innobackupex
(开源并作为XtraBackup的一部分可以从这里下载)。
这将获取MyISAM表的快照,对于InnoDB表,它将复制底层文件,然后重放事务日志以确保一致的状态。 它可以从一个活的服务器做到这一点,没有停机时间(我不知道这是否是你的要求?)
我build议你阅读文档,但要以最简单的forms使用备份:
$ innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/ $ innobackupex --apply-log /path/to/BACKUP-DIR/
如果数据在同一台机器上,innobackupex甚至有一个简单的恢复命令:
$ innobackupex --copy-back /path/to/BACKUP-DIR
还有更多的select和不同的方式来实际做备份,所以我真的鼓励你在开始之前仔细阅读文档。
为了参考速度,我们的低速testing服务器(约600 IOPS)可以使用此方法在大约4小时内恢复500 GB备份。
最后:你提到了可以做些什么来加快import。 这主要取决于瓶颈是什么。 通常情况下,导入操作是I / O绑定的(您可以通过检查io等待来进行testing),加快磁盘吞吐速度的方法是更快的磁盘本身,或者更多的磁盘本身。
确保将“ max_allowed_packet ”variables增加到足够大的大小。 如果你有很多的文本数据,这将真的有帮助。 使用高性能硬件肯定会提高导入数据的速度。
mysql --max_allowed_packet=256M -u root -p < "database-file.sql"
你可以做的一件事是
SET AUTOCOMMIT = 0; SET FOREIGN_KEY_CHECKS=0
你也可以玩的价值观
innodb_buffer_pool_size innodb_additional_mem_pool_size innodb_flush_method
在my.cnf
,让你走,但总的来说,你应该看看其余的innodb参数 ,以及看看最适合你的东西。
这是我过去的一个问题,我不觉得自己已经彻底解决了,但是我希望自己从这个方向指向自己。 本来可以节省很多时间。
获得更多的内存,获得更快的处理器,获得更快的写入SSD。 批量插入,这样他们将比一堆单独的插入运行得更快。 这是一个巨大的文件,需要时间。
方法1:禁用外键作为fakedrakebuild议。
SET AUTOCOMMIT = 0; SET FOREIGN_KEY_CHECKS = 0
方式2:使用BigDump,它将大块你的mysqldump文件,然后导入。 http://www.ozerov.de/bigdump/usage/
问题:你说你正在上传? 你如何导入你的转储? 不直接从服务器/命令行?
我不得不面对同样的问题。 我发现使用mysqldump
输出到一个CSV文件(像这样):
mysqldump -u [username] -p -t -T/path/to/db/directory [database] --fields-enclosed-by=\" --fields-terminated-by=,
然后使用mysql客户端中的LOAD DATA INFILE
查询导入数据(如下所示):
LOAD DATA FROM INFILE /path/to/db/directory/table.csv INTO TABLE FIELDS TERMINATED BY ',';
比仅执行包含数据的SQL查询要快一个数量级。 当然,它也依赖于已经创build的表(和空)。
你当然也可以通过导出然后导入你的空模式来做到这一点。
我不确定它是否适合您,但最好的方法是Tata和AndySavage已经说过:从生产服务器上抓取数据文件的快照,然后使用Percona的innobackupex。 它将以一致的方式备份InnoDb表并在MyISAM表上执行写入locking。
准备在生产机器上的完整备份:
http://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/preparing_a_backup_ibk.html
将备份的文件复制(或通过SSH进行备份 – 此处为更多信息)备份文件到本地计算机并恢复:
还原备份:
http://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/restoring_a_backup_ibk.html
您可以在这里findinnobackupex的完整文档: http ://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/innobackupex_script.html
恢复时间将比读取SQL转储快得多。