GTID主从复制转换

二进制与GTID复制的转换 2020-12-06

GTDI是服务器和事务序列号的一对坐标,用冒号分割

GTID = source_id:transaction_id
source_id标识的原始服务器。transaction_id是通过在事务提交源上的顺序确定一个序列号
例:3E11FA47-71CA-11E1-9E33-C80AA9429562:23 #指定服务器的第23个事务

GTID集是包括一个或多个单个GTID或一系列GTID的集。;GTID范围用冒号分隔
例如:3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5
3E11FA47-71CA-11E1-9E33-C80AA9429562:1-3:11:47-49

GTID集可以包括单个GTID和GTID范围的任意组合,并且可以包括源自不同服务器的GTID。
2174B383-5441-11E8-B90A-C80AA9429562:1-3, 24DA167-0C0C-11E8-8442-00059A3C7B00:1-19
  • GTID对于源服务器是唯一的,在复制拓扑中也是唯一的
  • 系统表mysql.gtid_executed用于保留MySQL服务器上已分配应用的所有事务的GTID。(未写入副本的gtid也会保留,gtid按顺序生成,不会跳过)
  • 启用了二进制日志,每当重置二进制日志或关闭服务器时,服务器都会将前一个二进制日志的所有事务的GTID写入mysql.gtid_executed表中,如果服务器意外停止,则当前二进制日志文件中的GTID集不会保存在mysql.gtid_executed表中。在恢复期间,这些GTID从二进制日志文件添加到表中。
  • 未包含GTID事务的二进制日志不能在启用了GTID的服务器上使用
  • 为了节省空间通过设置gtid_executed_compression_period系统变量,可以在经过指定的事务数后压缩表,从而控制压缩率 。此变量的默认值为1000,这意味着默认情况下,每1000个事务处理后将执行表压缩。设置gtid_executed_compression_period为0根本无法执行压缩。

重置GTID执行历史:

RESET MASTER

gtid_purged系统变量被设置为空字符串。
gtid_executed系统变量的全局值设置为空字符串。
mysql.gtid_executed表被清除
如果服务器启用了二进制日志记录,则将删除现有的二进制日志文件并清除二进制日志索引文件。

操作GTID函数

给定两组全局事务标识符 set1和 set2,如果中的所有GTIDset1也在 set2中 ,则返回true。否则返回false。
GTID_SUBSET(set1,set2)

给定两组全局事务标识符set1和set2,仅返回set1不在set2中的那些GTID。
GTID_SUBTRACT(set1,set2)

等到服务器应用了所有包含全局事务标识符的事务 gtid_set。在指定的秒数过去之后,可选的超时功能使功能不再等待。
WAIT_FOR_EXECUTED_GTID_SET(gtid_set[, timeout])

类似于WAIT_FOR_EXECUTED_GTID_SET(),但仅用于一个启动的复制通道。WAIT_FOR_EXECUTED_GTID_SET()而是确保所有通道都覆盖所有状态。
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS(gtid_set[, timeout][,channel])

在线启动GTID事务

此过程不需要使服务器脱机,并且适合在生产中使用。但是,如果在启用GTID事务时可以使服务器脱机,则此过程会更容易
拓扑中的所有服务器都必须使用MySQL 5.7.6或更高版本。
服务器的gtid_mode值为OFF

在每台服务器上,执行(让服务器在正常工作量下运行一段时间并监视日志。如果此步骤在日志中引起任何警告,请调整您的应用程序,使其仅使用与GTID兼容的功能,并且不生成任何警告。):
SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;

在每台服务器上,执行:
SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;

在每台服务器上,执行:
SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;

在每台服务器上,执行:
SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;

在每台服务器上,等待状态变量 ONGOING_ANONYMOUS_TRANSACTION_COUNT为零。可以使用以下命令进行检查(在副本上,从理论上讲这有可能显示为零,然后再次显示为非零。这不是问题,只要显示一次为零即可。):
SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';

等待直到步骤5生成的所有事务复制到所有服务器。
在每台服务器上执行(执行后不能使用没有GTID的包含匿名事务的二进制日志):
SET @@GLOBAL.GTID_MODE = ON;

在每个服务器上,将gtid_mode=ON和enforce_gtid_consistency=ON添加到 my.cnf。
现在,您可以确保所有事务都具有GTID,要开始使用GTID协议以便以后可以执行自动故障转移,请在每个副本上执行以下操作。(如果使用多源复制,使用FOR CHANNELchannel子句对每个通道执行此操作:)
STOP SLAVE [FOR CHANNEL 'channel'];
CHANGE MASTER TO MASTER_AUTO_POSITION = 1 [FOR CHANNEL 'channel'];
START SLAVE [FOR CHANNEL 'channel'];

在线禁用GTID事务

拓扑中的所有服务器都必须使用MySQL 5.7.6或更高版本
所有服务器的gtid_mode值为ON

在每个副本上执行以下操作,如果您使用多源复制,使用FOR CHANNELchannel子句对每个通道执行此操作:
STOP SLAVE [FOR CHANNEL 'channel'];
CHANGE MASTER TO MASTER_AUTO_POSITION = 0, MASTER_LOG_FILE = file, MASTER_LOG_POS = position [FOR CHANNEL 'channel'];
START SLAVE [FOR CHANNEL 'channel'];

在每台服务器上,执行:
SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;

在每台服务器上,执行:
SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;

在每个服务器上,等待直到变量@@GLOBAL.GTID_OWNED等于空字符串。可以在副本上使用以下命令进行检查:从理论上讲,它有可能为空然后又为非空。这不是问题,只需将其清空一次即可。
SELECT @@GLOBAL.GTID_OWNED;

等待任何二进制日志中当前存在的所有事务复制到所有副本。
在每台服务器上,执行:
SET @@GLOBAL.GTID_MODE = OFF;

在每台服务器上,在my.cnf中设置gtid_mode=OFF。如果要设置enforce_gtid_consistency=OFF, set @@GLOBAL.enforce_gtid_consistency=OFF之后,您应该将enforce_gtid_consistency=OFF添加到配置文件中。

验证匿名事务

监视复制拓扑并验证是否已复制所有匿名事务。在线更改复制模式时,这很有用,因为您可以验证更改为GTID事务是安全的。

在源上执行(记下File和Position列中的值)
SHOW MASTER STATUS;

在每个副本上,使用源中的文件和位置信息执行
SELECT MASTER_POS_WAIT(file, position);

如果复制拓扑为源->副本->副本的副本,那么应该重复执行上述操作。
源执行步骤1,副本执行步骤2
副本执行步骤1,副本的副本执行步骤2

{/if}