7.3.1 构建备份策略

为了有用,必须定期安排备份。可以使用多种工具在 MySQL 中进行完整备份(时间点上的数据快照)。例如,MySQL 企业备份可以对整个实例执行physical backup,并进行优化以最大程度地减少开销并避免在备份InnoDB数据文件时造成中断; mysqldump在线提供logical backup。本讨论使用mysqldump

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

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

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

此备份操作在转储开始时(使用带读取锁的平桌子)在所有 table 上获取全局读取锁定。一旦获取了此锁,便会读取二进制日志坐标并释放该锁。如果发出FLUSH语句时正在运行长的更新语句,则备份操作可能会停止,直到这些语句完成为止。此后,转储将变为无锁,并且不会干扰对 table 的读写。

早先假设要备份的 table 是InnoDB个 table,因此--single-transaction使用一致的读取,并保证mysqldump看到的数据不会更改。 (mysqldump进程看不到其他 Client 端对InnoDBtable 所做的更改。)如果备份操作包括非事务 table,则一致性要求它们在备份期间不更改。例如,对于mysql数据库中的MyISAMtable,在备份期间不得对 MySQL 帐户进行任何 Management 更改。

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

要进行增量备份,我们需要保存增量更改。在 MySQL 中,这些更改在二进制日志中 table 示,因此应始终使用--log-bin选项启动 MySQL 服务器以启用该日志。启用二进制日志记录后,服务器将在更新数据时将每个数据更 Rewrite 入文件。查看以--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 二进制日志的列 table。

MySQL 二进制日志对于恢复很重要,因为它们形成了增量备份的集合。如果确保在进行完全备份时刷新日志,则随后创建的二进制日志文件将包含自备份以来所做的所有数据更改。让我们稍微修改一下先前的mysqldump命令,以便在完全备份时刷新 MySQL 二进制日志,并且转储文件包含新的当前二进制日志的名称:

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

执行此命令后,数据目录包含一个新的二进制日志文件gbichot2-bin.000007,因为--flush-logs选项导致服务器刷新其日志。 --master-data选项使mysqldump将二进制日志信息写入其输出,因此生成的.sql转储文件包括以下几行:

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

由于mysqldump命令进行了完整备份,因此这些行 table 示两件事:

  • 转储文件包含在写入gbichot2-bin.000007二进制日志文件或更高版本的任何更改之前所做的所有更改。

  • 备份后记录的所有数据更改都不存在于转储文件中,而是存在于gbichot2-bin.000007二进制日志文件或更高版本中。

在星期一的下午 1 点,我们可以通过刷新日志以创建新的二进制日志文件来创建增量备份。例如,执行mysqladmin flush-logs命令将创建gbichot2-bin.000008。周日下午 1 点之间的所有更改完整备份和星期一下午 1 点将位于gbichot2-bin.000007文件中。此增量备份很重要,因此将其复制到安全位置是个好主意。 (例如,将其备份到磁带或 DVD 上,或将其复制到另一台计算机上.)在星期二下午 1 点执行另一条mysqladmin flush-logs命令。周一下午 1 点之间的所有更改和星期二下午 1 点将位于gbichot2-bin.000008文件中(也应将其复制到安全的位置)。

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

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

Note

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