7.3.1 建立备份策略

为了有用,必须定期安排备份。可以使用多种工具在 MySQL 中完成完整备份(某个时间点的数据快照)。例如, MySQL Enterprise Backup可以执行整个实例的 物理备份,并通过优化来最小化开销并避免备份InnoDB数据文件时的中断;mysqldump提供在线 逻辑备份。此讨论使用mysqldump

假设我们 InnoDB在周日下午 1 点负载较低时使用以下命令对所有数据库中的所有表进行完整备份:

$> mysqldump --all-databases --master-data --single-transaction > backup_sunday_1_PM.sql

mysqldump 生成的结果.sql文件 包含一组 SQL 语句,可用于稍后重新加载转储的表。 INSERT

此备份操作在转储开始时获取所有表的全局读锁(使用FLUSH TABLES WITH READ LOCK)。一旦获得此锁,就会读取二进制日志坐标并释放锁。如果在 FLUSH发出语句时正在运行长更新语句,则备份操作可能会停止,直到这些语句完成。在那之后,转储变得无锁并且不会干扰表上的读取和写入。

前面假设要备份的表是 InnoDB表,所以 使用一致读,保证mysqldump--single-transaction看到的数据 不变。(其他客户端对表所做的更改不会被mysqldump进程看到。)如果备份操作包括非事务表,则一致性要求它们在备份期间不更改。例如,对于数据库中的 表, 在备份期间不得对 MySQL 帐户进行管理更改。 InnoDBMyISAMmysql

完整备份是必要的,但创建它们并不总是很方便。它们会产生大型备份文件并需要时间来生成。它们不是最佳的,因为每个连续的完整备份都包括所有数据,即使是自上次完整备份以来未更改的部分。进行初始完整备份,然后进行增量备份效率更高。增量备份更小,生成时间更短。权衡是,在恢复时,您不能仅通过重新加载完整备份来恢复数据。您还必须处理增量备份以恢复增量更改。

要进行增量备份,我们需要保存增量更改。在 MySQL 中,这些更改在二进制日志中表示,因此 MySQL 服务器应始终 --log-bin以启用该日志的选项启动。启用二进制日志记录后,服务器在更新数据时将每个数据更改写入文件。查看使用该 --log-bin选项启动并运行了几天的 MySQL 服务器的数据目录,我们发现这些 MySQL 二进制日志文件:

-rw-rw---- 1 guilhem  guilhem   1277324 Nov 10 23:59 gbichot2-bin.000001
-rw-rw---- 1 guilhem  guilhem         4 Nov 10 23:59 gbichot2-bin.000002
-rw-rw---- 1 guilhem  guilhem        79 Nov 11 11:06 gbichot2-bin.000003
-rw-rw---- 1 guilhem  guilhem       508 Nov 11 11:08 gbichot2-bin.000004
-rw-rw---- 1 guilhem  guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
-rw-rw---- 1 guilhem  guilhem    998412 Nov 14 10:08 gbichot2-bin.000006
-rw-rw---- 1 guilhem  guilhem       361 Nov 14 10:07 gbichot2-bin.index

每次重新启动时,MySQL 服务器都会使用序列中的下一个数字创建一个新的二进制日志文件。FLUSH LOGS当服务器正在运行时,您还可以通过发出SQL 语句或使用mysqladmin flush-logs命令 告诉它关闭当前二进制日志文件并手动开始一个新文件 。mysqldump还有一个刷新日志的选项。数据目录中的.index文件包含目录中所有 MySQL 二进制日志的列表。

The MySQL binary logs are important for recovery because they form the set of incremental backups. If you make sure to flush the logs when you make your full backup, the binary log files created afterward contain all the data changes made since the backup. Let's modify the previous mysqldump command a bit so that it flushes the MySQL binary logs at the moment of the full backup, and so that the dump file contains the name of the new current binary log:

$> mysqldump --single-transaction --flush-logs --master-data=2 \
         --all-databases > backup_sunday_1_PM.sql

After executing this command, the data directory contains a new binary log file, gbichot2-bin.000007, because the --flush-logs option causes the server to flush its logs. The --master-data option causes mysqldump to write binary log information to its output, so the resulting .sql dump file includes these lines:

-- Position to start replication or point-in-time recovery from
-- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

Because the mysqldump command made a full backup, those lines mean two things:

  • The dump file contains all changes made before any changes written to the gbichot2-bin.000007 binary log file or higher.

  • All data changes logged after the backup are not present in the dump file, but are present in the gbichot2-bin.000007 binary log file or higher.

On Monday at 1 p.m., we can create an incremental backup by flushing the logs to begin a new binary log file. For example, executing a mysqladmin flush-logs command creates gbichot2-bin.000008. All changes between the Sunday 1 p.m. full backup and Monday 1 p.m. are in the gbichot2-bin.000007 file. This incremental backup is important, so it is a good idea to copy it to a safe place. (For example, back it up on tape or DVD, or copy it to another machine.) On Tuesday at 1 p.m., execute another mysqladmin flush-logs command. All changes between Monday 1 p.m. and Tuesday 1 p.m. are in the gbichot2-bin.000008 file (which also should be copied somewhere safe).

MySQL 二进制日志占用磁盘空间。要释放空间,请不时清除它们。一种方法是删除不再需要的二进制日志,例如当我们进行完整备份时:

$> mysqldump --single-transaction --flush-logs --master-data=2 \
         --all-databases --delete-master-logs > backup_sunday_1_PM.sql
笔记

如果您的服务器是复制源服务器,使用mysqldump --delete-master-logs 删除 MySQL 二进制日志可能很危险,因为副本服务器可能尚未完全处理二进制日志的内容。该PURGE BINARY LOGS语句的描述解释了在删除 MySQL 二进制日志之前应该验证的内容。参见 第 13.4.1.1 节,“PURGE BINARY LOGS 语句”