50

Are there any documented techniques for speeding up mySQL dumps and imports?

This would include my.cnf settings, using ramdisks, etc.

Looking only for documented techniques, preferably with benchmarks showing potential speed-up.

Alex R
  • 11,364
  • 15
  • 100
  • 180
deadprogrammer
  • 11,253
  • 24
  • 74
  • 85
  • Just FYI... I had a Raid 5 drive failing, which caused really bad performance with a MySQL restore. What normally took 40 minutes was pushing 24 hours. Just for reference. – gahooa May 03 '11 at 18:31

11 Answers11

31

Assuming that you're using InnoDB...

I was in the situation of having a pile of existing mysqldump output files that I wanted to import in a reasonable time. The tables (one per file) were about 500MB and contained about 5,000,000 rows of data each. Using the following parameters I was able to reduce the insert time from 32 minutes to under 3 minutes.

innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 256M
innodb_flush_method = O_DIRECT

You'll also need to have a reasonably large innodb_buffer_pool_size setting.

Because my inserts were a one-off I reverted the settings afterwards. If you're going to keep using them long-term, make sure you know what they're doing.

I found the suggestion to use these settings on Cedric Nilly's blog and the detailed explanation for each of the settings can be found in the MySQL documentation.

Jeff Hiltz
  • 483
  • 1
  • 4
  • 10
  • This is the second time I use this method. In both cases (different databases), it reduced the import time from hours into few minutes. Thanks! – lepe Feb 02 '15 at 06:54
  • I recently had to do this for a simple table of ~8 columns and mostly int data. Before applying these, i was getting about ~30 inserts/s (indexes disabled). After the change i was getting ~600 inserts/s. The biggest win comes from setting innodb_flush_log_at_trx_commit from '1' (default) to '2', which flushes writes to log every sec, instead of on every transaction (which is after each insert when a autocommit is true. It is true by default) – Adil Aug 06 '15 at 05:56
  • Can you explain what happen when editing this values? For us to understand. I just used this and the speed is awesome. – reignsly Sep 12 '17 at 17:52
24
  1. Get a copy of High Performance MySQL. Great book.
  2. Extended inserts in dumps
  3. Dump with --tab format so you can use mysqlimport, which is faster than mysql < dumpfile
  4. Import with multiple threads, one for each table.
  5. Use a different database engine if possible. importing into a heavily transactional engine like innodb is awfully slow. Inserting into a non-transactional engine like MyISAM is much much faster.
  6. Look at the table compare script in the Maakit toolkit and see if you can update your tables rather than dumping them and importing them. But you're probably talking about backups/restores.
JBB
  • 4,543
  • 3
  • 24
  • 25
15

http://www.maatkit.org/ has a mk-parallel-dump and mk-parallel-restore

If you’ve been wishing for multi-threaded mysqldump, wish no more. This tool dumps MySQL tables in parallel. It is a much smarter mysqldump that can either act as a wrapper for mysqldump (with sensible default behavior) or as a wrapper around SELECT INTO OUTFILE. It is designed for high-performance applications on very large data sizes, where speed matters a lot. It takes advantage of multiple CPUs and disks to dump your data much faster.

There are also various potential options in mysqldump such as not making indexes while the dump is being imported - but instead doing them en-mass on the completion.

Alister Bulman
  • 34,482
  • 9
  • 71
  • 110
13

If you are importing to InnoDB the single most effective thing you can do is to put

innodb_flush_log_at_trx_commit = 2

in your my.cnf, temporarily while the import is running. You can put it back to 1 if you need ACID.

kapex
  • 28,903
  • 6
  • 107
  • 121
Aleksandar Ivanisevic
  • 3,099
  • 3
  • 17
  • 8
  • I wonder, wouldn't setting it to `0` be even faster? – Petr Jun 01 '13 at 07:50
  • really didn't understand what this does, but it sped up the restore of my large innoDB database dump. for MyISAM dbs increasing `key_buffer_size` helped (to 30% of available memory). – arun Sep 22 '13 at 01:19
  • 1
    Just curious, does SET autocommit=0 render this unnecessary? – Sian Lerk Lau Jan 02 '14 at 02:50
5

Make sure you are using the --opt option to mysqldump when dumping. This will use bulk insert syntax, delay key updates, etc...


If you are ONLY using MyISAM tables, you can safely copy them by stopping the server, copying them to a stopped server, and starting that.

If you don't want to stop the origin server, you can follow this:

  1. Get a read lock on all tables
  2. Flush all tables
  3. Copy the files
  4. Unlock the tables

But I'm pretty sure your copy-to server needs to be stopped when you put them in place.

gahooa
  • 131,293
  • 12
  • 98
  • 101
  • Actually thats what mysqlhotcopy does – aldrinleal May 01 '11 at 05:58
  • Sadly, I only have one up-vote to give. Changing the way I was performing mysqldump, using the --opt option as you suggested, shaved 5 hours off of my import! – Nate Apr 10 '15 at 18:40
  • @Nate There must be other reasons why your import is now faster, because `--opt` is enabled by default in mysqldump. It has been so at least since v5.5 (2010). – dr_ Oct 28 '16 at 10:14
5

I guess your question also depends on where the bottleneck is:

  • If your network is a bottleneck you could also have a look at the -C/--compress flag to mysqldump.
  • If your computer runs out of memory (ie. starts swapping) you should buy more memory.

Also, have a look at the --quick flag for mysqldump (and --disable-keys if you are using MyIsam).

Ztyx
  • 14,100
  • 15
  • 78
  • 114
  • [Reference](http://dev.mysql.com/doc/refman/5.6/en/mysqldump.html#option_mysqldump_disable-keys) says `--disable-keys` is 'effective only for nonunique indexes of MyISAM tables'. – kapex Mar 02 '13 at 10:57
  • kapep - thanks for the correction. I've updated the answer. – Ztyx Mar 27 '13 at 00:09
4

Using extended inserts in dumps should make imports faster.

che
  • 12,097
  • 7
  • 42
  • 71
  • 1
    if you do that there is a good chance you will not be able to import back if the dump is even moderately big – Jonathan Feb 21 '09 at 20:33
  • How come MySQL client isn't able to process even moderately big dumps with extended inserts? – che Feb 21 '09 at 22:07
  • My guess is that the client has a fixed size buffer for each line it is reading and extended inserts exceeds that limit. – Ztyx Apr 19 '10 at 09:10
  • fwiw I've imported a 10GB dump using extended inserts and it has gone flawlessly. – alxgb May 23 '14 at 14:24
4

turn off foreign key checks and turn on auto-commit.

longneck
  • 287
  • 2
  • 2
1

There is an method for using LVM snapshots for backup and restore that might be an interesting option for you.

Instead of doing a mysqldump, consider using LVM to take snapshots of your MySQL data directories. Using LVM snapshots allow you to have nearly real time backup capability, support for all storage engines, and incredibly fast recovery. To quote from the link below,

"Recovery time is as fast as putting data back and standard MySQL crash recovery, and it can be reduced even further."

http://www.mysqlperformanceblog.com/2006/08/21/using-lvm-for-mysql-backup-and-replication-setup/

1

mysqlhotcopy might be an alternative for you too if you only have MyIsam tables.

Ztyx
  • 14,100
  • 15
  • 78
  • 114
-2

Using indexes but not too much, activate query cache, using sphinx for big database, here is some good tips http://www.keedeo.com/media/1857/26-astuces-pour-accelerer-vos-requetes-mysql (In French)

Peter O.
  • 32,158
  • 14
  • 82
  • 96
paul
  • 1
  • You shouldn't just give a link to another site as an answer, since the site may go out of date in the future. Instead, click the "edit" link on this answer and include the essential parts of the solution from that page here. See: http://meta.stackexchange.com/q/8259 – Peter O. Nov 14 '12 at 06:10