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 集的并集,以及性能模式 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
集合中。如果通道上的过滤条件相同,则不会出现问题,因为所有事务版本都包含相同的数据,因此结果相同。但是,如果通道上的过滤条件不同,则数据库可能会变得不一致,复制可能会挂起。