提高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。 数据库同时具有MyISAMInnoDB表。 我可以做些什么来改善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); } 

有很多参数丢失,要充分了解问题的原因。 如:

  1. MySQL版本
  2. 磁盘types和速度
  3. 在启动MySQL服务器之前在服务器上释放内存
  4. iostat在mysqldump之前和之后的输出。
  5. 您首先使用什么参数来创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_pa​​cket ”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转储快得多。