Assuming a good portion of the data on your MySQL server remains unchanged over time, you can increase the speed and reduce the required storage space for your regular backups by backing up not all the data on the server each time, but only the changes to the data which have taken place over time. In order to that, after making first a full backup that contains all data, you can do one of the following:
Performing a series of differential backups. Each differential backups includes all the changes made to the data since the last full backup was performed. To restore data up to, for example, time
t, you simply restore first the full backup, and then, on top of it, the differential backup taken for time
Perform a series of incremental backup. Each incremental backup only includes the changes since the previous backup, which can itself be a full or incremental backup. The first backup in an incremental series is always then a differential backup; but after that, each incremental backup only contains the changes made since that last incremental backup. Each subsequent incremental backup is thus usually smaller in size than a differential backup, and is faster to make; that allows you to make very frequent incremental backups, and then enables you to restore the database to a more precise point in time when necessary. However, restoring data with incremental backups might take longer and more work: in general, to restore data up to, for example, time
t, you start with restoring the full backup, and then restore the incremental backups one by one, until you are finished with the incremental backup taken for time t.
MySQL Enterprise Backup supports both incremental and differential backups. You should decide on which backup strategy to adopt by looking at such factors like how much storage space you have, how quickly you have to be able to restore data, and so on.
MySQL Enterprise Backup treats differential backup as a special case of incremental backup that has a full backup as its base. To create a differential backup, simply follow the instructions below for performing incremental backups, and make sure you specify a full backup as the base of your incremental backup; you should also ignore any instructions that only apply to the handling of multiple incremental backups.
For MySQL Enterprise Backup 8.0.17 and later, you can
create a differential backup easily using the option
See Section 20.7, “Incremental Backup Options”, for
descriptions of the mysqlbackup options used
for incremental backups. An Incremental backup is enabled with
one of the two options:
Creating Incremental Backups Using Only the Redo Log for
When creating an incremental backup, you have to indicate to
mysqlbackup the point in time of the previous
full or incremental backup. For convenience, you can use the
--incremental-base option to
automatically derive the necessary log
sequence number (LSN) from the metadata stored in a
previous backup directory or on the server. Or, you can specify
an explicit LSN value using the
--start-lsn option, providing to
mysqlbackup the ending LSN from a previous
full or incremental backup (see
Other Considerations for Incremental Backups on some
limitation that applies when using the
To prepare the backup data to be restored, you combine all incremental backups with an original full backup. Typically, you perform a new full backup after a designated period of time, after which you can discard the older incremental backup data.
The changes to InnoDB tables are determined based on the contents of the
InnoDBredo log. Since the redo log files have a fixed size that you know in advance, it can require less I/O to read the changes from them than to scan the InnoDB tablespace files to locate the changed pages, depending on the size of your database, amount of DML activity, and size of the redo log files.
Since the redo log files act as a circular buffer, with records of older changes being overwritten as new DML operations take place, you must take new incremental backups on a predictable schedule dictated by the size of the log files and the amount of redo data generated for your workload. Otherwise, the redo log might not reach back far enough to record all the changes since the previous incremental backup, in which case mysqlbackup will quickly determine that it cannot proceed and will return an error. Your backup script should be able to catch that error and then perform an incremental backup with the
To calculate the size of the redo log, issue the command
SHOW VARIABLES LIKE 'innodb_log_file%'and, based on the output, multiply the
innodb_log_file_sizesetting by the value of
innodb_log_files_in_group. To compute the redo log size at the physical level, look into the
datadirdirectory of the MySQL instance and sum up the sizes of the files matching the pattern
The InnoDB LSN value corresponds to the number of bytes written to the redo log. To check the LSN at some point in time, issue the command
SHOW ENGINE INNODB STATUSand look under the
LOGheading. While planning your backup strategy, record the LSN values periodically and subtract the earlier value from the current one to calculate how much redo data is generated each hour, day, and so on.
This type of incremental backup is not so forgiving of too-low
--start-lsnvalues as the standard
--incrementaloption is. For example, you cannot make a full backup and then make a series of
--incremental-with-redo-log-onlybackups all using the same
--start-lsnvalue. Make sure to specify the precise end LSN of the previous backup as the start LSN of the next incremental backup; do not use arbitrary values.
To judge whether this type of incremental backup is practical and efficient for a particular MySQL instance:
Measure how fast the data changes within the InnoDB redo log files. Check the LSN periodically to decide how much redo data accumulates over the course of some number of hours or days.
Compare the rate of redo log accumulation with the size of the redo log files. Use this ratio to see how often to take an incremental backup, in order to avoid the likelihood of the backup failing because the historical data are not available in the redo log. For example, if you are producing 1GB of redo log data per day, and the combined size of your redo log files is 7GB, you would schedule incremental backups more frequently than once a week. You might perform incremental backups every day or two, to avoid a potential issue when a sudden flurry of updates produced more redo log data than usual.
Benchmark incremental backup times using both the
--incremental-with-redo-log-onlyoptions, to confirm if the redo log backup technique performs faster and with less overhead than the traditional incremental backup method. The result could depend on the size of your data, the amount of DML activity, and the size of your redo log files. Do your testing on a server with a realistic data volume and a realistic workload. For example, if you have huge redo log files, reading them in the course of an incremental backup could take as long as reading the InnoDB data files using the traditional incremental technique. Conversely, if your data volume is large, reading all the data files to find the few changed pages could be less efficient than processing the much smaller redo log files.
Backup compression (i.e., use of the compression options) is not supported when you perform incremental backups with the redo log only. If backup compression is important to you, do not use the
For MySQL Enterprise Backup 8.0.18 and later: mysqlbackup supports creating incremental backups using the page tracking functionality of the MySQL Server, by which mysqlbackup looks for changed pages in the InnoDB data files that have been modified since the last backup and then copies them. In general, incremental backups using page tracking are faster than other kinds of incremental backups performed by mysqlbackup if the majority of the data in the database has not been modified. Using this feature requires the following to be done on the server before the base backup for the incremental backup is made:
mysqlbackupcomponent, which comes with the MySQL Enterprise Server 8.0 installation, by running this command at a mysql client connected to the server:
INSTALL COMPONENT "file://component_mysqlbackup";
Start page tracking with the following function:
The LSN value starting from which changed pages have been tracked is returned by this function:
You can stop page tracking with the following function:
The previously mentioned functions regarding page tracking
BACKUP_ADMIN privilege to run.
--incremental option is
used without any value specified, mysqlbackup
performs an incremental backup using the page tracking
functionality. User can also specifies
--incremental=page-track to make
mysqlbackup use the page tracking
functionality. However, the prerequisites for making use of the
page tracking functionality for incremental backups are:
Page tracking is functioning properly on the server, and it has been enabled (with
SELECT mysqlbackup_page_track_set(true)) before the base backup was created; if that is not the case, mysqlbackup throws an error when
--incremental=page-track, or it performs a full-scan incremental backup instead when
The number of changed pages is less than 50% of the total number of pages; if that is not the case, mysqlbackup throws an error when
--incremental=page-track, or it performs a full-scan incremental backup instead when
mysqlbackup needs to be started with enough memory to process all the tracked pages in memory. If there is not enough memory, mysqlbackup throws an error and then exits. Here are some guidelines for assuring enough memory for the operation:
The default value of 400 [MB] for the
--limit-memoryoption allows mysqlbackup to handle about 800GB of changed data. Adjust the value for the option according to your data size.
The page tracking feature uses the memory buffers configured for mysqlbackup for sorting the pages. Determine the number of buffers needed for page sorting by the following steps:
Before running the incremental backup, perform the following query on the server to determine the
end_lsnfor the base backup:
SELECT end_lsn FROM mysql.backup_history WHERE exit_state = 'SUCCESS' AND backup_type != 'TTS' AND server_uuid = @@server_uuid ORDER BY end_time DESC, end_lsn DESC LIMIT 0,1;
Run the following query on the server to get the number of changed pages since the base backup was created (retry the query if it returns a negative value):
SELECT mysqlbackup_page_track_get_changed_page_count(<the above end_lsn>, 0);
Every changed page needs 8 bytes in the sorting buffer. So, multiply the
changed_page_countvalue obtained in the last step by 8 to get the number of bytes needed for the sorting buffer.
Each buffer has 16 Megabytes (16777216 bytes). So, divide the number of bytes needed for the sorting buffers calculated in the last step by 16777216 and round the result up to the next integer, to get the number of buffers needed for sorting.
Make sure the value for the option
--number-of-buffersis no smaller than the number of required sorting buffers you calculated in the last step. Remember that there could be more changed pages created while you are doing this calculation, so you might want to give mysqlbackup a few more extra buffers.
The default memory limit of 400MB should be able to support up to 25 buffers (up to 18 buffers only for cloud backups); increase the memory limit if you need more buffers than that by changing the value of the
--incremental option is set
performs a full-scan incremental backup, in which it scans all
InnoDB data files in the server's data directory to find pages
that have been changed since the last backup was made and then
copies those pages. A full-scan incremental backup might not be
very efficient when not many tables have been modified since the
last back up.
An optimistic incremental backup, on the other hand, only scans
for changed pages in InnoDB data files that have been modified
since the last backup, thus saving some unnecessary scan time.
An optimistic incremental backup can be performed by specifying
While an optimistic increment backup might shorten the backup
time, it has the following limitations:
Since this feature makes use of the modification times of the files in the server's data directory, two things must have remained unchanged since the previous backup: (1) the system time on the server, and (2) the location of the data directory. Otherwise, the backup might fail, or an inconsistent incremental backup might be produced.
Optimistic incremental backups cannot be performed with the
--incremental-with-redo-log-only, for which mysqlbackup reads the redo log files instead of scanning the files in the data directory.
--start-lsnoption is used, a full scan is performed even if
--incremental=optimisticis specified since, in that case, mysqlbackup cannot determine the point in time for which the previous backup is consistent, and thus has no time frame to determine which files have been modified recently.
For these and other cases in which an optimistic incremental backup is not desirable, perform a full-scan incremental backup, or an incremental backup using page tracking (for MySQL Enterprise Backup 8.0.18 and later). See Section 4.1.2, “Grant MySQL Privileges to Backup Administrator” on the privileges required for mysqlbackup to perform an optimistic incremental backup. Also see Using Optimistic Backups and Optimistic Incremental Backups Together on how to utilize the two features together in a backup schedule.
For MySQL Enterprise Backup 8.0.17 and earlier, full-scan
backup is the default method for incremental backups, which is
utilized if no value is specified for
The incremental backup feature is primarily intended for InnoDB tables, or non-InnoDB tables that are read-only or rarely updated. Incremental backups detect changes at the level of pages in the InnoDB data files, as opposed to table rows; each page that has changed is backed up. Thus, the space and time savings are not exactly proportional to the percentage of changed InnoDB rows or columns.
For non-InnoDB files, the entire file is always included in an incremental backup, which means the savings for backup resources are less significant when comparing with the case with InnoDB tables.
No binary log files are copied into the incremental backup if
--start-lsn option is used. To
include binary log files for the period covered by the
incremental backup, use the
--incremental-base option instead,
which provides the necessary information for
mysqlbackup to ensure that no gap exists
between binary log data included in the previous backup and the
current incremental backup.
These examples use mysqlbackup to make an
incremental backup of a MySQL server, including all databases
and tables. We show two alternatives, one using the
--incremental-base option and the
other using the
--incremental-base option, you do not
have to keep track of LSN values between one backup and the
next. Instead, you can do one of the following:
Tell mysqlbackup to query the
end_lsnvalue from the last successful non-TTS backup as recorded in the
backup_historytable on the server using
history:last_full_backup(for release 8.0.17 and later).
Advanced: For directory backups, specify the directory of the previous backup (either full or incremental) with
--incremental-base=dir:, and mysqlbackup will figure out the starting point for this backup based on the metadata of the earlier one. Because you need a known set of directory names, you might want to use hardcoded names or generate a sequence of names in your own backup script, rather than using the
--with-timestampoption. If your last backup was a single-file, you can still use
--incremental-base=dir:to provide the location of the temporary directory you supplied with the
--backup-diroption during the last backup
In the following example, the
option is used, given which mysqlbackup
fetches the LSN of the last successful (non-TTS) full or partial
backup from the
and performs an incremental backup basing on that.
mysqlbackup --defaults-file=/home/dbadmin/my.cnf \ --incremental --incremental-base=history:last_backup \ --backup-dir=/home/dbadmin/temp_dir \ --backup-image=incremental_image1.bi \ backup-to-image
In the following example, an incremental backup similar to the one in the last example but optimistic in nature is performed.
mysqlbackup --defaults-file=/home/dbadmin/my.cnf \ --incremental=optimistic --incremental-base=history:last_backup \ --backup-dir=/home/dbadmin/temp_dir \ --backup-image=incremental_image1.bi backup-to-image
Advanced: Use the following command to
create an incremental directory backup using the
option; the backup is saved at the location specified by
mysqlbackup --defaults-file=/home/dbadmin/my.cnf --incremental \ --incremental-base=dir:/incr-backup/wednesday \ --incremental-backup-dir=/incr-backup/thursday \ backup
You can also use the
option to specify where the incremental backup should start. You
have to record the LSN of the previous backup reported by
mysqlbackup at the end of the backup:
mysqlbackup: Was able to parse the log up to lsn 2654255716
The number is also recorded in the
meta/backup_variables.txt file in the
folder specified by
during the backup. Supply then that number to
mysqlbackup using the
--start-lsn option. The incremental backup then
includes all changes that came after the
To create an incremental backup image with the
--start-lsn option, use the following command,
backup directory, which, in this case, is a directory for
storing the metadata for the backup and some temporary files:
mysqlbackup --defaults-file=/home/dbadmin/my.cnf --incremental \ --start-lsn=2654255716 \ --with-timestamp \ --backup-dir=/incr-tmp \ --backup-image=/incr-backup/incremental_image.bi \ backup-to-image
In the following example though, because
--backup-image does not provide a
full path to the image file to be created, the incremental
backup image is created under the folder specified by
mysqlbackup --defaults-file=/home/dbadmin/my.cnf --incremental \ --start-lsn=2654255716 \ --with-timestamp \ --backup-dir=/incr-images \ --backup-image=incremental_image1.bi \ backup-to-image
On a regular schedule determined by date or amount of database activity, take more incremental or differential backups.
On how to restore your database using the incremental backups, see Section 5.1.3, “Restoring an Incremental Backup”