3.3 GTID自动定位
GTID是用来代替传统复制的方法,GTID复制与普通复制模式的最大不同在于,启动和恢复复制时能够自动定位,而不需要指定二进制日志文件名和位置。配置非GTID复制时,需要在CHANGE MASTER TO语句中包含MASTER_LOG_FILE或MASTER_LOG_POS选项,用于指示从主库复制的开始点。但对于GTID,从库不需要此非本地数据,其与主库同步的所有信息都直接从复制数据流中获取,因此不需要指定这些选项。要使用基于GTID的复制启动从库,推荐启用MASTER_AUTO_POSITION选项。
默认情况下禁用MASTER_AUTO_POSITION选项。如果在从库上启用了多源复制,则需要为每个适用的复制通道设置该选项。设置MASTER_AUTO_POSITION=0会使从库恢复为基于文件的复制,这时必须指定MASTER_LOG_FILE或MASTER_LOG_POS选项。当从库启用GTID(GTID_MODE=ON、ON_PERMISSIVE或OFF_PERMISSIVE)并使用MASTER_AUTO_POSITION选项时,将激活自动定位以连接到主库。主库必须设置GTID_MODE=ON才能使连接成功。
在初始握手中,从库向主库发送一个GTID集,其中包含已经收到、已提交或两者都已完成的事务。此GTID集等于@@GLOBAL.gtid_executed系统变量与select received_transaction_set from performance_schema.replication_connection_status查询结果的并集。主库会比较其二进制日志中记录的所有事务和从库发来的GTID集合,并将不包括在从库发送的GTID集中的事务全部发送给从库。自动跳过功能可确保同一事务不会应用两次。如果从库缺失的GTID已经被主库清除(purge),则复制中断,主库将错误ER_MASTER_HAS_PURGED_REQUIRED_GTIDS发送给从库。主库错误日志的ER_FOUND_MISSING_GTIDS警告消息中将列出丢失事务的GTID。从库无法自动解决此问题,尝试在不启用MASTER_AUTO_POSITION选项的情况下重新连接主库只会导致已清除事务在从库上的丢失。可以考虑修改主库上的binlog_expire_logs_seconds系统参数值(默认为2592000秒,即30天),以确保不再发生还需要使用二进制日志时它却已经被提前清除的情况。下面模拟一下这个场景:
会看到1236错误:
主库的错误日志中会显示如下信息:
主库二进制日志修改成正确的文件名,重启从库复制后恢复正常:
如果在事务交换期间发现从库已经在GTID中接收或提交了事务,但主库本身没有它们的记录,则复制停止,主库将错误ER_SLAVE_HAS_MORE_GTIDS_THAN_MASTER发送给从库。当没有配置sync_binlog=1的主库遇到电源故障或操作系统崩溃,此时尚未同步,而导致二进制日志文件的已提交事务未被从库接收,就会发生这种情况。如果主库重新提交事务,可能导致主库和从库对不同的事务使用相同的GTID,这时只能根据需要对各个事务以手动方式解决冲突,例如手工设置gtid_next。如果问题仅仅是主库缺少事务,则可以进行主从切换,允许它跟上复制拓扑结构中的其他服务器,然后在需要时再次将其设置为主库。可见sync_binlog=1对于主从数据一致性至关重要,这也是MySQL 8的默认配置值。下面模拟一下这个场景:
会看到以下错误:
重新配置从库以恢复复制: