GTID 替代了以前用于确定启动、停止或恢复源和副本之间数据流点的文件偏移量对。当使用 GTID 时,副本同步源所需的所有信息都直接从复制数据流中获取。
要使用基于 GTID 的复制启动副本,您需要在 CHANGE REPLICATION SOURCE TO
语句中启用 SOURCE_AUTO_POSITION
选项。备选的 SOURCE_LOG_FILE
和 SOURCE_LOG_POS
选项指定日志文件名称和文件中的起始位置,但使用 GTID 时,副本不需要此非本地数据。有关使用基于 GTID 的复制配置和启动源和副本的完整说明,请参见 第 19.1.3.4 节,“使用 GTID 设置复制”。
SOURCE_AUTO_POSITION
选项默认情况下处于禁用状态。如果在副本上启用了多源复制,则需要为每个适用的复制通道设置该选项。再次禁用 SOURCE_AUTO_POSITION
选项会导致副本恢复为基于文件的复制;这意味着,当 GTID_ONLY=ON
时,某些位置可能会被标记为无效,在这种情况下,您还必须在禁用 SOURCE_AUTO_POSITION
时指定 SOURCE_LOG_FILE
和 SOURCE_LOG_POS
。
当副本启用了 GTID (GTID_MODE=ON
、ON_PERMISSIVE
或 OFF_PERMISSIVE
) 并且启用了 SOURCE_AUTO_POSITION
选项时,将为连接到源激活自动定位。源必须设置 GTID_MODE=ON
才能使连接成功。在初始握手过程中,副本发送一个 GTID 集,其中包含它已接收、提交或同时接收和提交的事务。此 GTID 集等于 gtid_executed
系统变量 (@@GLOBAL.gtid_executed
) 中的 GTID 集的并集,以及 Performance Schema replication_connection_status
表中记录为已接收事务的 GTID 集(语句 SELECT RECEIVED_TRANSACTION_SET FROM PERFORMANCE_SCHEMA.replication_connection_status
的结果)。
源服务器通过发送其二进制日志中记录的所有未包含在副本发送的GTID集中 GTID 的事务来进行响应。 为此,源服务器首先通过检查其每个二进制日志文件(从最新的开始)的标头中的 Previous_gtids_log_event
来确定要开始处理的适当二进制日志文件。 当源服务器找到第一个不包含副本缺少的事务的 Previous_gtids_log_event
时,它将从该二进制日志文件开始。 此方法高效,并且仅在副本落后于源服务器大量二进制日志文件时才会花费大量时间。 然后,源服务器读取该二进制日志文件和后续文件中的事务,直到当前文件,发送副本缺少 GTID 的事务,并跳过副本发送的 GTID 集中的事务。 直到副本接收到第一个缺少的事务所经过的时间取决于其在二进制日志文件中的偏移量。 此交换确保源服务器仅发送副本尚未接收或提交的 GTID 的事务。 如果副本从多个源服务器接收事务,例如钻石拓扑结构中,自动跳过功能确保事务不会被应用两次。
如果源服务器应该发送的任何事务已从源服务器的二进制日志中清除,或通过其他方法添加到 gtid_purged
系统变量的 GTID 集中,源服务器会向副本发送错误 ER_SOURCE_HAS_PURGED_REQUIRED_GTIDS
,并且复制不会启动。 缺少的清除事务的 GTID 将在源服务器的错误日志中被识别并列出,并在警告消息 ER_FOUND_MISSING_GTIDS
中列出。 副本无法从该错误自动恢复,因为用于赶上源服务器的某些事务历史记录已被清除。 尝试在没有启用 SOURCE_AUTO_POSITION
选项的情况下重新连接只会导致副本上的清除事务丢失。 从这种情况中恢复的正确方法是副本从另一个源服务器复制 ER_FOUND_MISSING_GTIDS
消息中列出的缺少事务,或者用从较新的备份创建的新副本替换副本。 考虑修改源服务器上的二进制日志过期时间段 (binlog_expire_logs_seconds
) 以确保这种情况不再发生。
如果在事务交换过程中发现副本已接收或提交了带有源服务器 UUID 的 GTID 的事务,但源服务器本身没有记录它们,源服务器会向副本发送错误 ER_REPLICA_HAS_MORE_GTIDS_THAN_SOURCE
,并且复制不会启动。 如果没有设置 sync_binlog=1
的源服务器遇到电源故障或操作系统崩溃,并且丢失了尚未同步到二进制日志文件但已由副本接收的已提交事务,则会出现这种情况。 如果源服务器重新启动后,任何客户端都对源服务器提交事务,则源服务器和副本可能会出现分歧,这会导致源服务器和副本对不同的事务使用相同的 GTID。 从这种情况中恢复的正确方法是手动检查源服务器和副本是否已出现分歧。 如果现在对不同的事务使用相同的 GTID,则需要根据需要对单个事务执行手动冲突解决,或者从复制拓扑结构中删除源服务器或副本。 如果问题仅仅是源服务器上的缺少事务,可以将源服务器改为副本,使其赶上复制拓扑结构中的其他服务器,然后根据需要将其再次改为源服务器。
对于钻石拓扑结构中的多源副本(副本从两个或多个源服务器复制,而这些源服务器又从一个公共源服务器复制),当使用基于 GTID 的复制时,请确保多源副本的所有通道上的任何复制过滤器或其他通道配置都相同。 使用基于 GTID 的复制时,过滤器仅应用于事务数据,而 GTID 不会被过滤掉。 这样做是为了使副本的 GTID 集与源服务器的 GTID 集保持一致,这意味着可以在每次重新获取已过滤掉的事务时使用 GTID 自动定位。 在下游副本是多源副本并从钻石拓扑结构中的多个源服务器接收同一事务的情况下,下游副本现在将拥有事务的多个版本,结果取决于哪个通道首先应用事务。 第二个尝试应用事务的通道将使用 GTID 自动跳过跳过该事务,因为该事务的 GTID 已由第一个通道添加到 gtid_executed
集中。 如果通道上的过滤相同,则不会出现问题,因为事务的所有版本都包含相同的数据,因此结果相同。 但是,如果通道上的过滤不同,数据库可能会变得不一致,并且复制可能会挂起。