Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Establishing a Backup Policy

9.3.1 建立备份策略

为了有用,备份必须定期进行。MySQL 可以使用多种工具建立全量备份(数据的某个时间点快照)。例如,MySQL Enterprise Backup 可以对整个实例进行 物理备份,优化减少 overhead 和避免在备份 InnoDB 数据文件时的中断;mysqldump 提供在线 逻辑备份。以下讨论使用 mysqldump

假设我们在星期天下午1点,负载低时,对所有数据库中的 InnoDB 表进行全量备份:

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

mysqldump 产生的 .sql 文件包含了一组 SQL INSERT 语句,可以在后续时间重新加载备份表。

这个备份操作在开始dump时,获取所有表的全局读锁(使用FLUSH TABLES WITH READ LOCK)。一旦获取了该锁,binary log坐标就被读取,然后释放锁。如果在发出FLUSH语句时,有长时间更新的语句正在运行,备份操作可能会等待这些语句完成。然后,dump就不再锁定表,并且不会干扰读写操作。

之前假设要备份的是InnoDB表,所以--single-transaction使用一致的读取方式,确保mysqldump不改变数据。(InnoDB表中的更改由其他客户端进行,不会被mysqldump进程看到。如果备份操作包括非事务表,要求这些表在备份期间不发生变化。例如,对于mysql数据库中的MyISAM表,在备份期间不能进行MySQL账户的管理更改。

全量备份是必要的,但是创建它们不总是方便的。它们生成了大文件,需要花费时间来生成。它们不是最优的,因为每个连续的全量备份都包含了自上一个全量备份以来所有数据,即使部分数据没有变化。更高效的是首先创建一个全量备份,然后创建增量备份。增量备份较小,生产时间也短。但是,在恢复时,你不能只靠重新加载全量备份来恢复数据,还需要处理增量备份以恢复增量变更。

为了创建增量备份,我们需要保存增量变更。在 MySQL 中,这些变更在二进制日志中表示,所以 MySQL 服务器应该总是使用--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 也有一个flush日志的选项。数据目录中的.index 文件包含该目录中的所有 MySQL 二进制日志列表。

MySQL 二进制日志对于恢复非常重要,因为它们组成了增量备份集。如果您在做全备时确保刷新了日志,那么创建后的二进制日志文件中包含自备以来所有数据变化。让我们修改之前的mysqldump 命令,使其在全备时刷新 MySQL 二进制日志,并使得dump 文件包含新当前二进制日志的名称:

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

执行该命令后,数据目录中包含一个新的二进制日志文件,gbichot2-bin.000007--flush-logs选项导致服务器刷新日志。 --source-data选项导致mysqldump将二进制日志信息写入输出,故生成的.sql备份文件中包含这些行:

-- Position to start replication or point-in-time recovery from
-- CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE='gbichot2-bin.000007',SOURCE_LOG_POS=4;

因为mysqldump命令执行了完整备份,那些行表示两个意思:

  • 备份文件包含在gbichot2-bin.000007二进制日志文件或更高版本之前的所有变更。

  • 备份后所有数据变更都没有出现在备份文件中,但却出现在gbichot2-bin.000007二进制日志文件或更高版本中。

星期一下午1点,我们可以通过刷新日志来创建增量备份,例如执行mysqladmin flush-logs命令创建gbichot2-bin.000008。从星期日下午1点到星期一下午的所有更改都写入了gbichot2-bin.000007。这个增量备份很重要,所以应该将其复制到安全的地方(例如,备份到磁带或DVD,或者复制到另一个机器上)。星期二下午1点,执行另一个mysqladmin flush-logs命令。从星期一下午到星期二下午的所有更改都写入了gbichot2-bin.000008(也应该将其复制到安全的地方)。

MySQL二进制日志占用磁盘空间。为了释放空间,时不时地清除它们。一个方法是删除不再需要的二进制日志,例如,当我们做了全备份时:

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

使用mysqldump--delete-source-logs删除 MySQL 二进制日志可能会危险,如果您的服务器是复制源服务器,因为副本可能还没有完全处理二进制日志的内容。PURGE BINARY LOGS 语句的描述解释了在删除 MySQL 二进制日志前需要验证什么。请参阅第15.4.1.1节,“PURGE BINARY LOGS 语句”