全局事务标识符 (GTID) 是创建的唯一标识符,并与在原始服务器(源)上提交的每个事务相关联。此标识符不仅对于它的起源服务器是唯一的,而且在给定复制设置中的所有服务器中也是唯一的。所有事务和所有 GTID 之间存在一对一的映射。
GTID 表示为一对坐标,由冒号字符 ( :
) 分隔,如下所示:
GTID = source_id:transaction_id
source_id
标识原始服务器
。通常,服务器
server_uuid
用于此目的。transaction_id
是一个序列号,由在此服务器上提交事务的顺序决定;例如,要提交的第一个事务的值为1
,
transaction_id
而在同一原始服务器上要提交的第十个事务的transaction_id
值为
10
。事务不可能0
在 GTID 中具有序列号。例如,最初在具有 UUID 的服务器上要提交的第 23 个事务
3E11FA47-71CA-11E1-9E33-C80AA9429562
具有此 GTID:
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
这种格式用于在语句输出中SHOW SLAVE
STATUS
以及在二进制日志中表示 GTID。在使用mysqlbinlog
查看日志文件时
--base64-output=DECODE-ROWS
或在SHOW BINLOG
EVENTS
.
如
SHOW MASTER STATUS
or
等语句的输出中所写,SHOW SLAVE STATUS
源自同一服务器的一系列 GTID 可能会折叠成一个表达式,如此处所示。
3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5
刚刚显示的示例表示源自 MySQL 服务器的第一到第五个
server_uuid
事务
3E11FA47-71CA-11E1-9E33-C80AA9429562
。
在 MySQL 5.6.6 及更高版本中,此格式还用于提供START
SLAVE
选项SQL_BEFORE_GTIDS
和
所需的参数SQL_AFTER_GTIDS
。
GTID 集是一组全局事务标识符,如下所示:
gtid_set:
uuid_set [, uuid_set] ...
| ''
uuid_set:
uuid:interval[:interval]...
uuid:
hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh
h:
[0-9|A-F]
interval:
n[-n]
(n >= 1)
GTID 集在 MySQL 服务器中以多种方式使用。例如,由
gtid_executed
和
gtid_purged
系统变量存储的值表示为 GTID 集。此外,功能
GTID_SUBSET()
和
GTID_SUBTRACT()
要求 GTID 设置为输入。
GTID 始终保留在源和副本之间。这意味着您始终可以通过检查其二进制日志来确定应用于任何副本的任何事务的来源。此外,一旦在给定服务器上提交了具有给定 GTID 的事务,该服务器将忽略具有相同 GTID 的任何后续事务。因此,在源上提交的事务只能在副本上应用一次,这有助于保证一致性。
使用 GTID 时,副本不需要任何非本地数据,例如源文件的名称和该文件中的位置。与源同步所需的所有信息都直接从复制数据流中获取。从数据库管理员或开发人员的角度来看,GTID 完全取代了以前用于确定开始、停止或恢复源和副本之间数据流的点所需的文件偏移对。这意味着,当您使用 GTID 进行复制时,您不需要(或不想
MASTER_LOG_FILE
)
MASTER_LOG_POS
在
CHANGE MASTER TO
用于指示副本从给定源复制的语句;代替这些选项,只需要启用
MASTER_AUTO_POSITION
MySQL 5.6.5 中引入的选项。有关使用基于 GTID 的复制配置和启动源和副本所需的确切步骤,请参阅
第 17.1.3.2 节,“使用 GTID 设置复制”。
GTID 的生成和生命周期包括以下步骤:
事务在源上执行并提交。
使用源的 UUID 和尚未在此服务器上使用的最小非零事务序列号为该事务分配一个 GTID;GTID 被写入源的二进制日志(紧接在日志中的事务本身之前)。
在将二进制日志数据传输到副本并存储在副本的中继日志中后(使用已建立的机制来实现此过程 - 请参阅 第 17.2 节,“复制实现”,了解详细信息),副本读取 GTID 并设置其
gtid_next
系统的值作为这个 GTID 的变量。这告诉副本必须使用此 GTID 记录下一个事务。会话上下文中的副本集
gtid_next
。副本检查以确保此 GTID 尚未用于在其自己的二进制日志中记录事务。当且仅当此 GTID 未被使用时,副本才会写入 GTID 并应用事务(并将事务写入其二进制日志)。通过首先读取和检查事务的 GTID,在处理事务本身之前,副本不仅保证没有具有此 GTID 的先前事务已应用于副本,而且还没有其他会话已经读取此 GTID 但尚未提交相关交易。换句话说,
因为
gtid_next
它不为空,所以副本不会尝试为此事务生成 GTID,而是将存储在此变量中的 GTID,即从源获取的 GTID,紧接在其二进制日志中的事务之前写入。