16.3.2 处理副本意外中断
为了使复制能够应对服务器的意外停止(有时称为崩溃安全),副本必须在停止之前恢复其状态。本节介绍复制期间复制副本意外停止的影响,以及如何配置复制副本以使恢复具有最佳机会 continue 复制。
副本意外停止后,重新启动时,复制 SQL 线程必须恢复已执行的事务。恢复所需的信息存储在副本元数据存储库中。在较早的 MySQL Server 版本中,只能在应用事务后更新的数据目录中创建该日志作为文件。这有可能失去与源同步的风险,这取决于副本停止在哪个事务处理阶段,甚至文件本身损坏。在 MySQL 5.7 中,您可以改为使用InnoDBtable 来存储中继日志信息日志。通过使用此事务性存储引擎,信息始终可在重新启动后恢复。作为一个 table,对中继日志信息日志的更新将与事务一起提交,这意味着记录在该日志中的副本的进度信息始终与应用于数据库的内容一致,即使在服务器意外中断的情况下也是如此。
要将 MySQL 5.7 配置为将中继日志信息日志存储为InnoDBtable,请将系统变量relay_log_info_repository设置为TABLE
。然后,服务器将恢复复制 SQL 线程所需的信息存储在mysql.slave_relay_log_info
table 中。有关复制元数据存储库的更多信息,请参见第 16.2.4 节“中继日志和复制应用程序元数据存储库”。
所选副本的方法,副本是单线程还是多线程,设置变量诸如relay_log_recovery以及是否使用诸如MASTER_AUTO_POSITION
之类的变量都会影响副本从意外停止中恢复的确切方式。
下 table 显示了这些不同因素对单线程副本如何从意外停止中恢复的影响。
table16.3 影响单线程副本恢复的因素
GTID | MASTER_AUTO_POSITION | relay_log_recovery | relay_log_info_repository | Crash type | Recovery guaranteed | 中继日志影响 |
---|---|---|---|---|---|---|
OFF | OFF | 1 | TABLE | Server | Yes | Lost |
OFF | OFF | 1 | Any | OS | No | Lost |
OFF | OFF | 0 | TABLE | Server | Yes | Remains |
OFF | OFF | 0 | TABLE | OS | No | Remains |
ON | ON | 1 | TABLE | Any | Yes | Lost |
ON | OFF | 0 | TABLE | Server | Yes | Remains |
ON | OFF | 0 | Any | OS | No | Remains |
如下 table 所示,使用单线程副本时,以下配置可最有效地防止意外停止:
-
使用 GTID 和
MASTER_AUTO_POSITION
时,设置relay_log_recovery=1。使用此配置,relay_log_info_repository和其他变量的设置不会影响恢复。请注意,为保证恢复,还必须在副本上设置sync_binlog=1(默认值),以便在每次写入时将副本的二进制日志同步到磁盘。否则,副本的二进制日志中可能不会存在已提交的事务。 -
使用基于文件位置的复制时,请设置relay_log_recovery=1和relay_log_info_repository=TABLE。
Note
在恢复期间,中继日志将丢失。
下 table 显示了这些不同因素对多线程副本如何从意外停止中恢复的影响。
table16.4 影响多线程副本恢复的因素
GTID | sync_relay_log | MASTER_AUTO_POSITION |
relay_log_recovery | relay_log_info_repository | Crash type | Recovery guaranteed | 中继日志影响 |
---|---|---|---|---|---|---|---|
OFF | 1 | OFF | 1 | TABLE | Any | Yes | Lost |
OFF | >1 | OFF | 1 | TABLE | Server | Yes | Lost |
OFF | >1 | OFF | 1 | Any | OS | No | Lost |
OFF | 1 | OFF | 0 | TABLE | Server | Yes | Remains |
OFF | 1 | OFF | 0 | TABLE | OS | No | Remains |
ON | Any | ON | 1 | TABLE | Any | Yes | Lost |
ON | 1 | OFF | 0 | TABLE | Server | Yes | Remains |
ON | 1 | OFF | 0 | Any | OS | No | Remains |
如下 table 所示,使用多线程副本时,以下配置可最有效地防止意外停止:
-
使用 GTID 和
MASTER_AUTO_POSITION=ON
时,设置relay_log_recovery=1。使用此配置,relay_log_info_repository和其他变量的设置不会影响恢复。从 MySQL 5.7.28 开始,当MASTER_AUTO_POSITION
设置为ON
时,多线程副本自动跳过中继日志恢复,因此relay_log_recovery的设置没有区别。 -
使用基于文件位置的复制时,请设置relay_log_recovery=1,sync_relay_log=1和relay_log_info_repository=TABLE。
Note
在恢复期间,中继日志将丢失。
重要的是要注意sync_relay_log=1的影响,它需要为每个事务写入中继日志。尽管此设置对于意外停止最 Elastic,最多会丢失一个未写的事务,但它也有可能大大增加存储负载。如果没有sync_relay_log=1,则意外停止的影响取决于 os 如何处理中继日志。另请注意,当relay_log_recovery=0时,在意外停止后下一次启动副本时,中继日志将作为恢复的一部分进行处理。此过程完成后,将删除中继日志。
使用上面推荐的基于文件位置的复制配置来意外中断多线程副本可能会导致中继日志具有意外中断导致的事务不一致(事务序列中的间隙)。参见第 16.4.1.32 节,“复制和事务不一致”。在 MySQL 5.7.13 和更高版本中,如果中继日志恢复过程遇到此类事务不一致,则会将其填充,并且恢复过程将自动 continue。在 MySQL 5.7.13 之前的 MySQL 版本中,该过程不是自动的,需要使用relay_log_recovery=0启动服务器,使用从开始直到 SQL_AFTER_MTS_GAPS启动副本以修复任何事务不一致,然后使用relay_log_recovery=1重新启动副本。
当您使用多源复制和relay_log_recovery=1时,由于意外停止而重启后,所有复制通道都将通过中继日志恢复过程。将填充由于多线程副本的意外暂停而在中继日志中发现的所有不一致情况。