8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

9.3.1 建立备份策略9.3.1 Establishing a Backup Policy

为了有用,备份必须定期安排。在 MySQL 中,可以使用多种工具进行完整备份(某一时间点的数据快照)。例如,MySQL Enterprise Backup 可以对整个实例执行物理备份,优化以最小化开销并在备份 InnoDB 数据文件时避免中断;mysqldump 提供在线逻辑备份。本讨论使用 mysqldump。To be useful, backups must be scheduled regularly. A full backup (a snapshot of the data at a point in time) can be done in MySQL with several tools. For example, MySQL Enterprise Backup can perform a physical backup of an entire instance, with optimizations to minimize overhead and avoid disruption when backing up InnoDB data files; mysqldump provides online logical backup. This discussion uses mysqldump.

假设我们在周日下午 1 点在负载较低时,使用以下命令对所有数据库中的所有InnoDB表进行完整备份:Assume that we make a full backup of all our InnoDB tables in all databases using the following command on Sunday at 1 p.m., when load is low:

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

mysqldump生成的.sql文件包含一组 SQL INSERT语句,可用于在以后重新加载转储的表。The resulting .sql file produced by mysqldump contains a set of SQL INSERT statements that can be used to reload the dumped tables at a later time.

此备份操作在转储开始时会对所有表获取全局读锁(使用 FLUSH TABLES WITH READ LOCK)。一旦获取了此锁,就会读取二进制日志坐标并释放锁。如果在执行 FLUSH 语句时有长时间运行的更新语句,备份操作可能会暂停,直到这些语句执行完毕。之后,转储将变为无锁,并且不会干扰表的读取和写入操作。This backup operation acquires a global read lock on all tables at the beginning of the dump (using FLUSH TABLES WITH READ LOCK). As soon as this lock has been acquired, the binary log coordinates are read and the lock is released. If long updating statements are running when the FLUSH statement is issued, the backup operation may stall until those statements finish. After that, the dump becomes lock-free and does not disturb reads and writes on the tables.

之前假设要备份的表是 InnoDB 表,因此 --single-transaction 使用一致性读,并保证 mysqldump 查看到的数据不会改变。(其他客户端对 InnoDB 表的更改,mysqldump 进程将不可见。)如果备份操作包括非事务型表,则一致性要求它们在备份期间不发生变化。例如,对于 mysql 数据库中的 MyISAM 表,备份期间不得对 MySQL 帐户进行任何管理操作。It was assumed earlier that the tables to back up are InnoDB tables, so --single-transaction uses a consistent read and guarantees that data seen by mysqldump does not change. (Changes made by other clients to InnoDB tables are not seen by the mysqldump process.) If the backup operation includes nontransactional tables, consistency requires that they do not change during the backup. For example, for the MyISAM tables in the mysql database, there must be no administrative changes to MySQL accounts during the backup.

完整备份是必要的,但创建它们并不总是方便。它们会生成较大的备份文件,并且需要时间来生成。从优化的角度来看,它们并不理想,因为每次后续的完整备份都会包含所有数据,即使是自上一次完整备份以来未发生变化的部分。更有效的方法是先进行初始完整备份,然后进行增量备份。增量备份较小,生成所需时间也更短。权衡之处在于,在恢复时,你不能仅仅通过重新加载完整备份来恢复数据,你还必须处理增量备份以恢复增量更改。Full backups are necessary, but it is not always convenient to create them. They produce large backup files and take time to generate. They are not optimal in the sense that each successive full backup includes all data, even that part that has not changed since the previous full backup. It is more efficient to make an initial full backup, and then to make incremental backups. The incremental backups are smaller and take less time to produce. The tradeoff is that, at recovery time, you cannot restore your data just by reloading the full backup. You must also process the incremental backups to recover the incremental changes.

为了进行增量备份,我们需要保存增量的更改。在 MySQL 中,这些更改以二进制日志的形式表示,因此 MySQL 服务器应始终以 --log-bin 选项启动以启用该日志。启用二进制日志后,服务器在更新数据的同时会将每个数据更改写入文件。查看已运行数天的 MySQL 服务器的数据目录,我们会发现这些 MySQL 二进制日志文件:To make incremental backups, we need to save the incremental changes. In MySQL, these changes are represented in the binary log, so the MySQL server should always be started with the --log-bin option to enable that log. With binary logging enabled, the server writes each data change into a file while it updates data. Looking at the data directory of a MySQL server that has been running for some days, we find these MySQL binary log files:

-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 二进制日志的列表。Each time it restarts, the MySQL server creates a new binary log file using the next number in the sequence. While the server is running, you can also tell it to close the current binary log file and begin a new one manually by issuing a FLUSH LOGS SQL statement or with a mysqladmin flush-logs command. mysqldump also has an option to flush the logs. The .index file in the data directory contains the list of all MySQL binary logs in the directory.

MySQL 二进制日志对于恢复非常重要,因为它们构成了增量备份的集合。如果你在进行完整备份时确保刷新日志,那么之后创建的二进制日志文件将包含自备份以来的所有数据更改。让我们稍微修改之前的 mysqldump 命令,以便在进行完整备份时刷新 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 --source-data=2 \
         --all-databases > backup_sunday_1_PM.sql

执行此命令后,数据目录中会包含一个新的二进制日志文件,gbichot2-bin.000007,因为--flush-logs选项会导致服务器刷新其日志。--source-data选项会导致mysqldump将二进制日志信息写入其输出,因此生成的.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 --source-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 REPLICATION SOURCE TO SOURCE_LOG_FILE='gbichot2-bin.000007',SOURCE_LOG_POS=4;

因为mysqldump命令进行了完整备份,所以这些行意味着两件事:Because the mysqldump command made a full backup, those lines mean two things:

  • 转储文件包含在写入 gbichot2-bin.000007 二进制日志文件或更高版本之前所做的所有更改。The dump file contains all changes made before any changes written to the gbichot2-bin.000007 binary log file or higher.

  • 备份之后记录的所有数据更改不在转储文件中,但存在于 gbichot2-bin.000007 二进制日志文件或更高版本中。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.

在周一下午 1 点,我们可以通过刷新日志来创建增量备份,以开始一个新的二进制日志文件。例如,执行一个 mysqladmin flush-logs 命令会创建 gbichot2-bin.000008。所有在周日下午 1 点的完整备份和周一下午 1 点之间的更改都记录在 gbichot2-bin.000007 中。这个增量备份很重要,因此最好将其复制到安全的地方。(例如,备份到磁带或 DVD,或复制到另一台机器。)在周二下午 1 点,再次执行一个 mysqladmin flush-logs 命令。所有在周一下午 1 点和周二下午 1 点之间的更改都记录在 gbichot2-bin.000008 中(也应该复制到安全的地方)。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 written in gbichot2-bin.000007. 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 written in gbichot2-bin.000008 (which also should be copied somewhere safe).

MySQL 二进制日志会占用磁盘空间。为了释放空间,需要不时清理它们。一种方法是删除不再需要的二进制日志,例如在我们进行完整备份时:The MySQL binary logs take up disk space. To free up space, purge them from time to time. One way to do this is by deleting the binary logs that are no longer needed, such as when we make a full backup:

$> 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 语句”。Deleting the MySQL binary logs with mysqldump --delete-source-logs can be dangerous if your server is a replication source server, because replicas might not yet fully have processed the contents of the binary log. The description for the PURGE BINARY LOGS statement explains what should be verified before deleting the MySQL binary logs. See Section 15.4.1.1, “PURGE BINARY LOGS Statement”.