处理副本意外停止
为了使复制对服务器意外停止(有时被描述为崩溃安全)具有弹性,副本必须有可能在停止之前恢复其状态。本节介绍复制期间副本意外停止的影响,以及如何配置副本以获得最佳恢复机会以继续复制。
副本意外停止后,重新启动时,复制 SQL 线程必须恢复有关哪些事务已执行的信息。恢复所需的信息存储在副本的应用程序元数据存储库中。在较旧的 MySQL 服务器版本中,此存储库只能作为在应用事务后更新的数据目录中的文件创建。在 MySQL 5.7 中,您可以改为使用InnoDB
名为的表 mysql.slave_relay_log_info
存储应用程序元数据存储库。作为一个表,对应用程序元数据存储库的更新与事务一起提交,这意味着记录在该存储库中的副本进度信息始终与应用于数据库的信息一致,即使在服务器意外停止的情况下也是如此。要将 MySQL 5.7 配置为将应用程序元数据存储库存储为 InnoDB
表,请将系统变量设置 relay_log_info_repository
为 TABLE
. 有关应用程序元数据存储库的更多信息,请参阅第 16.2.4 节,“中继日志和复制元数据存储库”。
副本从意外停止中恢复的恢复过程因副本的配置而异。恢复过程的细节受所选择的复制方法、副本是单线程还是多线程以及相关系统变量的设置的影响。恢复过程的总体目标是确定在意外停止发生之前已在副本的数据库上应用了哪些事务,并检索和应用副本在意外停止后错过的事务。
- 对于基于 GTID 的复制,恢复过程需要副本已经接收或提交的事务的 GTID。可以使用 GTID 自动定位从源检索丢失的事务,它会自动将源的事务与副本的事务进行比较并识别丢失的事务。
- 对于基于文件位置的复制,恢复过程需要一个准确的复制 SQL 线程(应用程序)位置,显示应用在副本上的最后一个事务。基于该位置,复制 I/O 线程(接收器)从源的二进制日志中检索应从该点开始应用于副本的所有事务。
使用基于 GTID 的复制可以最轻松地将复制配置为对意外停止具有弹性。GTID 自动定位意味着副本可以可靠地识别和检索丢失的事务,即使应用事务的顺序存在间隙。
以下信息提供了适用于不同类型副本的设置组合,以保证在复制控制下的恢复。
重要的
复制控制之外的一些因素可能会对复制恢复过程和恢复过程后复制的整体状态产生影响。特别是,影响单个存储引擎恢复过程的设置可能会导致事务在副本意外停止的情况下丢失,因此无法用于复制恢复过程。在 innodb_flush_log_at_trx_commit=1
下面的列表中提到的设置是一个复制设置一键设置,使用InnoDB
与交易。但是,其他特定于 InnoDB
或其他存储引擎,尤其是与刷新或同步相关的存储引擎,也会产生影响。始终检查并应用您选择的存储引擎提出的有关崩溃安全设置的建议。
副本上的以下设置组合对意外停止最具弹性:
- 当使用基于 GTID 的复制 (
gtid_mode=ON
) 时, setMASTER_AUTO_POSITION=1
,它会激活 GTID 自动定位,以便与源的连接自动识别和检索丢失的事务。此选项是使用CHANGE MASTER TO
语句设置的。如果副本有多个复制通道,则需要为每个通道单独设置此选项。有关 GTID 自动定位如何工作的详细信息,请参阅 第 16.1.3.3 节,“GTID 自动定位”。当使用基于文件位置的复制时,MASTER_AUTO_POSITION=1
不使用,而是使用二进制日志位置或中继日志位置来控制复制开始的位置。 - Set
sync_relay_log=1
,它指示复制 I/O 线程在每个接收到的事务写入磁盘后将中继日志同步到磁盘。这意味着从源的二进制日志(在源元数据存储库中)读取的当前位置的副本记录永远不会在中继日志中保存的事务记录之前。请注意,尽管此设置最安全,但由于涉及的磁盘写入次数,它也是最慢的。与sync_relay_log > 1
, 或sync_relay_log=0
(其中同步由操作系统处理),在副本意外停止的情况下,可能存在尚未同步到磁盘的已提交事务。如果恢复副本根据上次同步到磁盘的中继日志中的信息,尝试重新检索和应用事务而不是跳过它们,则此类事务可能导致恢复过程失败。环境sync_relay_log=1
对于多线程副本尤其重要,如果无法使用中继日志中的信息填充事务序列中的间隙,则恢复过程将失败。对于单线程副本,如果应用程序元数据存储库中没有相关信息,则恢复过程只需要使用中继日志。 - Set
innodb_flush_log_at_trx_commit=1
,它在InnoDB
提交每个事务之前将日志同步到磁盘。此设置是默认设置,可确保将InnoDB
表和InnoDB
日志保存在磁盘上,以便不再需要中继日志中有关事务的信息。结合设置sync_relay_log=1
,此设置进一步保证了InnoDB
表和InnoDB
日志的内容始终与中继日志的内容一致,从而清除中继日志文件不会导致副本中事务的历史记录出现无法填补的空白。意外停止的事件。 - Set
relay_log_info_repository = TABLE
,它将复制 SQL 线程位置存储在InnoDB
表中mysql.slave_relay_log_info
,并与事务提交一起更新以确保记录始终准确。此设置不是 MySQL 5.7 中的默认设置。如果使用默认FILE
设置,则信息存储在数据目录中的文件中,该文件在应用事务后更新。这会产生与源失去同步的风险,具体取决于副本在处理事务的哪个阶段停止,甚至文件本身损坏。使用该设置relay_log_info_repository = FILE
,无法保证恢复。 - Set
relay_log_recovery = ON
,在服务器启动后立即启用自动中继日志恢复。此全局变量OFF
在运行时默认 为只读,但您可以在副本意外停止后的副本启动时ON
使用--relay-log-recovery
选项将其设置为。请注意,此设置会忽略现有的中继日志文件,以防它们损坏或不一致。中继日志恢复过程启动一个新的中继日志文件,并从应用程序元数据存储库中记录的复制 SQL 线程位置开始从源获取事务。随着时间的推移,副本的正常清除机制会删除先前的中继日志文件。
对于多线程副本,从 MySQL 5.7.13 开始,设置会 relay_log_recovery = ON
自动处理从中继日志执行的事务序列中的任何不一致和间隙。当使用基于文件位置的复制时,可能会出现这些间隙。(有关更多详细信息,请参阅 第 16.4.1.32 节,“复制和事务不一致”。)中继日志恢复过程使用与 START SLAVE UNTIL SQL_AFTER_MTS_GAPS
声明会。当副本达到一致的无间隙状态时,中继日志恢复过程继续从复制 SQL 线程位置开始从源获取更多事务。在 MySQL 5.7.13 之前的 MySQL 版本中,此过程不是自动的,需要使用 启动服务器 relay_log_recovery = OFF
,使用 启动副本 START SLAVE UNTIL SQL_AFTER_MTS_GAPS
以修复任何事务不一致,然后使用 重新启动副本 relay_log_recovery = ON
。当使用基于 GTID 的复制时,从 MySQL 5.7.28 开始,多线程副本首先检查是否 MASTER_AUTO_POSITION
设置为 ON
,如果是,则省略计算应跳过或不跳过的事务的步骤,以便恢复过程不需要旧的中继日志。