为了使复制能够适应服务器的意外停止(有时被描述为崩溃安全),副本必须能够在停止之前恢复其状态。本节介绍复制过程中副本意外停止的影响,以及如何配置副本以获得恢复继续复制的最佳机会。
在副本意外停止后,在重新启动时,复制SQL线程必须恢复关于已经执行了哪些事务的信息。恢复所需的信息存储在副本的应用程序元数据存储库中。从MySQL 8.0开始,这个存储库默认创建为InnoDB
表命名mysql.slave_relay_log_info
.通过使用这个事务性存储引擎,信息在重新启动时总是可以恢复的。对应用程序元数据存储库的更新与事务一起提交,这意味着存储库中记录的副本的进度信息始终与应用到数据库的信息一致,即使在服务器意外停止的情况下也是如此。有关应用程序元数据存储库的更多信息,请参见17.2.4节,“中继日志和复制元数据存储库”.
的应用程序元数据存储库中DML事务和原子DDL更新副本的复制位置mysql.slave_relay_log_info
表,并将更改应用到数据库,作为原子操作。在所有其他情况下,包括不是完全原子的DDL语句,以及不支持原子DDL的豁免存储引擎mysql.slave_relay_log_info
如果服务器意外停止,表可能缺少与复制数据相关的更新。在这种情况下,恢复更新是一个手动过程。有关MySQL 8.0中原子DDL支持的详细信息,以及某些语句复制的结果行为,请参见第13.1.1节,“原子数据定义语句支持”.
副本从意外停止中恢复的恢复过程取决于副本的配置。恢复过程的细节受到所选择的复制方法的影响,副本是单线程还是多线程,以及相关系统变量的设置。恢复过程的总体目标是确定在意外停止发生之前已经在副本的数据库上应用了哪些事务,并检索和应用在意外停止之后副本错过的事务。
对于基于gtid的复制,恢复过程需要副本已经接收或提交的事务的gtid。可以使用GTID自动定位从源中检索丢失的事务,GTID自动定位将源的事务与副本的事务进行比较,并识别丢失的事务。
对于基于文件位置的复制,恢复过程需要一个准确的复制SQL线程(应用程序)位置,显示在副本上应用的最后一个事务。基于该位置,复制I/O线程(接收方)从源二进制日志中检索从该点开始应应用于副本的所有事务。
使用基于gtid的复制可以最容易地配置复制,使其对意外中断具有弹性。GTID自动定位意味着副本可以可靠地识别和检索丢失的事务,即使应用的事务序列中存在空白。
以下信息提供了适合于不同类型的副本的设置组合,以确保恢复在复制的控制下。
复制控制之外的一些因素可能会对复制恢复过程和恢复过程后复制的整体状态产生影响。特别是,影响单个存储引擎恢复过程的设置可能会导致在副本意外停止时丢失事务,因此复制恢复过程不可用。的innodb_flush_log_at_trx_commit = 1
下面列表中提到的设置是用于复制设置的关键设置InnoDB
与事务。但是,其他设置具体到InnoDB
或其他存储引擎,特别是与刷新或同步相关的存储引擎,也会产生影响。始终检查并应用所选存储引擎提供的关于崩溃安全设置的建议。
副本上的以下设置组合对意外停机最有弹性:
使用基于gtid的复制时(
gtid_mode =对
),设置SOURCE_AUTO_POSITION = 1
|MASTER_AUTO_POSITION = 1
,它激活到源的连接的GTID自动定位,以自动识别和检索丢失的事务。属性设置此选项将复制源更改为
语句(从MySQL 8.0.23)或将master更改为
语句(MySQL 8.0.23之前)。如果副本有多个复制区域通道,则需要为每个通道分别设置该选项。有关GTID自动定位工作的详细信息,请参见章节17.1.3.3,“GTID自动定位”.当使用基于文件位置的复制时,SOURCE_AUTO_POSITION = 1
|MASTER_AUTO_POSITION = 1
不使用,而是使用二进制日志位置或中继日志位置来控制复制开始的位置。集
sync_relay_log = 1
,它指示复制I/O线程在每个接收到的事务写到中继日志之后,将中继日志同步到磁盘。这意味着从源二进制日志(在应用程序元数据存储库中)读取的当前位置的副本记录永远不会超过保存在中继日志中的事务记录。注意,尽管这种设置是最安全的,但由于涉及到磁盘写入的数量,它也是最慢的。与Sync_relay_log > 1 .执行以下命令
,或sync_relay_log = 0
(其中同步由操作系统处理),在副本意外停止的情况下,可能有未同步到磁盘的已提交事务。如果恢复副本基于上次同步到磁盘的中继日志中的信息,试图再次检索和应用事务,而不是跳过它们,则此类事务可能导致恢复过程失败。设置sync_relay_log = 1
对于多线程副本尤其重要,如果不能使用中继日志中的信息填充事务序列中的空白,则恢复过程将失败。对于单线程副本,如果相关信息在应用程序元数据存储库中不可用,恢复过程只需要使用中继日志。集
innodb_flush_log_at_trx_commit = 1
,它同步InnoDB
在提交每个事务之前将日志记录到磁盘。此设置为默认设置,可确保InnoDB
表格和InnoDB
日志保存在磁盘上,因此不再需要中继日志中有关事务的信息。结合设置sync_relay_log = 1
时,此设置进一步保证了InnoDB
表格和InnoDB
日志在任何时候都与中继日志的内容保持一致,因此在意外停止的情况下,清除中继日志文件不会在副本的事务历史中造成无法填补的空白。集
relay_log_info_repository = TABLE
中的复制SQL线程位置InnoDB
表格mysql.slave_relay_log_info
,并与事务提交一起更新它,以确保记录始终准确。此设置是MySQL 8.0的默认设置文件
设置已弃用。从MySQL 8.0.23开始,系统变量本身的使用已弃用,因此省略它并允许它默认使用。如果文件
如果使用设置(这是早期版本中的默认设置),则信息存储在数据目录中的一个文件中,该文件将在应用事务后更新。这就产生了丢失与源同步的风险,这取决于副本在处理事务的哪个阶段停止,甚至文件本身的损坏。通过设置relay_log_info_repository = FILE
,不能保证恢复。集
relay_log_recovery = ON
,可以在服务器启动后立即自动恢复中继日志。此全局变量默认为从
并且在运行时是只读的,但是您可以将其设置为在
与——relay-log-recovery
在副本意外停止后,副本启动时的选项。注意,此设置忽略现有的中继日志文件,以防它们损坏或不一致。中继日志恢复过程启动一个新的中继日志文件,并从应用程序元数据存储库中记录的复制SQL线程位置开始从源处获取事务。以前的中继日志文件会随着时间的推移被副本的正常清除机制删除。
对于多线程副本,设置relay_log_recovery = ON
自动处理从中继日志执行的事务序列中的任何不一致和空白。在使用基于文件位置的复制时,可能会出现这些间隙。(详情请参见17.5.1.34节,“复制和事务不一致”)。中继日志恢复过程处理间隙的方法与启动副本| slave直到sql_after_mts_gaps
声明。当副本达到一致的无间隙状态时,中继日志恢复过程继续从复制SQL线程位置开始从源获取进一步的事务。当使用基于gtid的复制时,从MySQL 8.0.18开始,一个多线程副本首先检查是否MASTER_AUTO_POSITION
设置为在
,如果是,则省略计算应该跳过或不跳过的事务的步骤,以便恢复过程不需要旧的中继日志。