mysqldump Best Practices: Part 1 - MySQL Prerequisites
Tags: mysql, database, developer, tutorial
Published: 2020-12-17 17:47:01

---
title: mysqldump Best Practices: Part 1 - MySQL Prerequisites
published: true
description: In this blog series we discuss common aspects you should handle upfront to ensure a successful dump & restore activity. In part 1, we focus on prerequisites.
tags: MySQL, Database, Developer, Tutorial
cover_image: https://scalegrid.io/blog/wp-content/uploads/2020/12/mysqldump-Best-Practices-Part-1-MySQL-Prerequisites-ScaleGrid-Blog.jpg
---
<link rel="canonical" href="https://scalegrid.io/blog/mysqldump-best-practices-part-1/" />
<p style="text-align: justify;"><a target="_blank" style="color: #2da964;" href="https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html">Mysqldump</a> is a client utility that is used to perform logical <a target="_blank" style="color: #2da964;" href="https://scalegrid.io/blog/mysqldump-best-practices-part-1/">backups of the MySQL database</a>. This popular migration tool is useful for various use cases of MySQL such as:</p>
<ul>
<li>Backup and restore of databases.</li>
<li>Migrating data from one server to another.</li>
<li>Migrating data across different managed MySQL service providers.</li>
<li>Migrating data between different versions of MySQL.</li>
</ul>
<p style="text-align: justify;">Mysqldump works by reading the source database objects and generating a set of SQL statements that are stored in a dump file. By replaying these statements on the destination database server, the original data is reconstructed. Since this model uses reading of the whole database and then essentially rebuilding, both dump and restore are time-consuming operations for a large database. The process might even turn cumbersome if you encounter errors during either dump or restore as it may lead you to fix the issues and re-run the operations. This is why it's important to plan well before you take up the dump and restore activity.</p>
<p style="text-align: justify;">In this 2-part blog series, we discuss some of the common aspects you should handle upfront to ensure a successful dump and restore activity. In the first part, we focus on the prerequisites you need to take care while importing the MySQL table data and in the second part, we will talk about how to handle import for stored program objects and views.<p>
<h2 style="padding-top: 15px;"><a id="1"></a>1. Space requirements</h2>
<p style="text-align: justify;">First off, it's important to ensure that your destination database volume has sufficient space to hold the imported data. Specifically, you need to be cautious if binary logs are enabled on your destination MySQL database, as binary logs generated while importing the data might take almost equal size as the data itself. Binary logs are needed if you want to restore your data on one server and want that to be replicated. In such cases, it's a good idea to plan the destination size greater than twice the size of the source database.</p>
<p style="text-align: justify;">It is also important to ensure sufficient space is available on the volume where you generate the mysqldump output file. Without these precautions, you may see your dump or restore failing due to insufficient space after running for a long time which is a loss of your productive time and effort.</p>
<h2 style="padding-top: 15px;">2. Sql_mode</h2>
<p style="text-align: justify;"><a target="_blank" style="color: #2da964;" href="https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html">sql_mode</a> settings for MySQL server determine the SQL statement syntax and data validation checks that the server performs for the operations. It is important to ensure the <code>sql_mode</code> of source and destination MySQL servers are compatible with each other, or you may encounter failures while restoring the dump you have taken. Let's demonstrate this with an example.<p/>
<p style="text-align: justify;">Say you have a table on your source which has a date column having entries as zero dates:</p>
<pre><code>
mysql> show create table sched;
--------------------------------------------------------+
| Table | Create Table                                                                                                        |
--------------------------------------------------------+
| sched | CREATE TABLE `sched` (
  `id` int(11) DEFAULT NULL,
  `ts` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+---------------------------------------------------------------------------------------------------------------------

mysql> select * from sched;
+------+------------+
| id   | ts         |
+------+------------+
|    1 | 2020-01-12 |
|    2 | 0000-00-00 |
+------+------------+
</code></pre>
<p style="text-align: justify;">Suppose the strict <code>sql_mode</code> (and <code>NO_ZERO_DATE</code>) is disabled on source, but enabled on the destination -  restoring such rows will result in failure such as:</p>
<pre><code>
ERROR 1292 (22007) at line 40: Incorrect date value: '0000-00-00' for column 'ts’' at row 2
</code></pre>
<p style="text-align: justify;">You will typically see such issues if you are taking a compact dump by enabling the <a target="_blank" style="color: #2da964;" href="https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_compact">compact option</a> as part of your mysqldump.</p>
<p style="text-align: justify;">If compact is disabled (which is by default) then you will not face this issue as mysqldump generates following conditional statement as part of the dump:</p>
<pre><code>
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE,SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
</code></pre>
<p style="text-align: justify;">This means that during the restore <code>sql_mode</code> is set to <code>'NO_AUTO_VALUE_ON_ZERO'</code> before restoring the table data so restore goes through fine.</p>
<h2 style="padding-top: 15px;">3. Unique_checks and foreign_key_checks</h2>
<p style="text-align: justify;">By default (if you don't use --compact option), mysqldump also sets the following:</p>
<pre><code>
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
</code></pre>
<p style="text-align: justify;">As explained <a target="_blank" style="color: #2da964;" href="https://dev.mysql.com/doc/refman/8.0/en/optimizing-innodb-bulk-data-loading.html">here</a>, you can speed up restore operation by temporarily turning off the uniqueness checks during the session. For big tables, this saves a lot of disk I/O because InnoDB can use its change buffer to write secondary index records in a batch.</p>
<p style="text-align: justify;">If you have <code>FOREIGN KEY</code> constraints in your tables, you can speed up table restore operation by turning off the foreign key checks for the duration of the restore session: For big tables, this can save a lot of disk I/O.</p>
<p style="text-align: justify;">Disabling <code>FOREIGN_KEY_CHECKS</code> will also help to avoid errors due to foregin key constraint checks during the restore operation. Whenever a table with foregin key constraint is created, MySQL expects that the parent table which is referred to by the foregin key already exists. This is a problem since mysqldump utility dumps the tables in alphabetical order. Let’s take an example to demonstrate this.</p>
<p style="text-align: justify;">On the source database, we have two tables:</p>
<pre><code>
CREATE TABLE `solution_table` (
  `num1` int(11) NOT NULL,
  `num2` int(11) DEFAULT NULL,
  PRIMARY KEY (`num1`));

CREATE TABLE `ref_table` (
  `key` int(11) DEFAULT NULL,
  `ref_num` int(11) DEFAULT NULL,
  KEY `ref_num` (`ref_num`),
  CONSTRAINT `ref_num_ibfk_1` FOREIGN KEY (`ref_num`) REFERENCES `solution_table` (`num1`)
)
</code></pre>
<p style="text-align: justify;">The table <code>ref_table</code> has a foreign key constraint that references the <code>solution_table</code>. Based on the alphabetical order, mysqldump first dumps the contents of <code>ref_table</code>. When this is replayed at the time of restore, it will fail with the error:
<pre><code>
ERROR 1215 (HY000) at line 50: Cannot add foreign key constraint - 
</code></pre>
<p style="text-align: justify;">Which happens while executing the create table statement for <code>‘ref_table’</code>.</p>
<p style="text-align: justify;">In summary, be aware of the issues you may encounter, if you specify <code>--compact</code> option while running mysqldump.</p>
<h2 style="padding-top: 15px;">4. Privileges required for running mysqldump</h2>
<p style="text-align: justify;">The minimum privilege required by mysqldump for dumping a database is <code>SELECT</code> on that database.</p>
<p style="text-align: justify;">However, if your database has views, you will need SHOW VIEW permissions as well,  as mysqldump always dumps views along with the tables of the database. Suppose you don't have <code>SHOW VIEW</code> permissions, then the mysqldump will fail with:</p>
<pre><code> 
mysqldump: Couldn't execute 'show create table `ivew`': SHOW VIEW command denied to user ‘dumpuser’@'172.31.18.79' for table 'iview' (1142)
</code></pre>
<p style="text-align: justify;">Another point of interest is if your dumpuser has <code>SELECT</code> permissions only on a particular table of the database, mysqldump will dump data only for that particular table and automatically ignores any other tables or views.</p>
<p style="text-align: justify;">So please ensure that the user executing mysqldump has all the appropriate privileges upfront in order to avoid any surprises or failures at a later time.</p>
<h2 style="padding-top: 15px;">5. Max_allowed_packet</h2>
<p style="text-align: justify;">The largest communication packet handled by mysql is determined by the setting <code>max_allowed_packet</code>. In the context of import, a communication packet is a single SQL statement sent to the MySQL server during the restore OR  a single row that is sent to the client during the dump.</p>
<p style="text-align: justify;">The default value of <code>max_allowed_packet</code> for mysqldump is 24MB. if mysqldump receives a packet larger than this, then you may run into the error:</p>
<pre><code>
mysqldump: Error 2020: Got packet bigger than 'max_allowed_packet' bytes when dumping table `huge1` at row: 2.
</code></pre>
<p style="text-align: justify;">So ensure that mysqldump uses the same or bigger value of <code>max_allowed_packet</code> that is configured on the source MySQL instance.</p>
<p style="text-align: justify;">The option can be specified with the flag <a target="_blank" style="font-weight:400; color: #2da964;" href="https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_max-allowed-packet"><code>--max-allowed-packet=<i>value</i></code></a> when invoking the mysqldump.</p>
<p style="text-align: justify;">When restoring the dump, ensure that <code>max_allowed_packet</code> size of your destination server is big enough to receive the packets from the dump file.</p>
<p style="text-align: justify;">Otherwise, during restore of the dump, you will see an error message:</p>
<pre><code>
ERROR 2006 (HY000) at line 70: MySQL server has gone away
</code></pre>
<p style="text-align: justify;">This error can be a little misleading as you may think that the MySQL server has shut down or crashed. But, it just means that the server has received a bigger sized packet than its configured size of <code>max_allowed_packet</code>. Again, the best practice is to ensure that the <code>max_allowed_packet</code> value for your destination server is the same as the value in the source server. This is also an important setting that can be checked and set appropriately upfront, rather than facing the errors at a later time.</p>
<p style="text-align: justify;">In this first part of the mysqldump series, we discussed prerequisites for a successful dump and restore operation for large MySQL databases in order to help you avoid multiple attempts and unproductive time spent.</p>
<p style="text-align: justify;">In the next part, we will discuss best practices to import the stored programs and views from your MySQL database.</p>