原标题:MySQL 5.7基于GTID的主从复制实践
在 「」 一文中我们讲解了 MySQL 5.7 新特性多源复制的实现方法。今天我们来讲讲 MySQL 5.7 的另一个新特性基于 GTID 的主从复制实现。
什么是GTID Replication
从 MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式。通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。
在原来基于二进制日志的复制中,从库需要告知主库要从哪个偏移量进行增量同步,如果指定错误会造成数据的遗漏,从而造成数据的不一致。借助GTID,在发生主备切换的情况下,MySQL的其它从库可以自动在新主库上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。
什么是GTID
GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。 GTID 实际上 是由 UUID+TID 组成的。其中 UUID 是一个 MySQL 实例的唯一标识。TID 代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。下面是一个GTID的具体形式:
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
一组连续的事务可以用 - 连接的事务序号范围表示。例如:
e6954592-8dba-11e6-af0e-fa163e1cf111:1-5
GTID 集合可以包含来自多个 MySQL 实例的事务,它们之间用逗号分隔。如果来自同一 MySQL 实例的事务序号有多个范围区间,各组范围之间用冒号分隔。例如:
e6954592-8dba-11e6-af0e-fa163e1cf111:1-5:11-18,e6954592-8dba-11e6-af0e-fa163e1cf3f2:1-27
可以使用 SHOW MASTER STATUS 实时看当前的事务执行数。
GTID的作用
GTID 的使用不单单是用单独的标识符替换旧的二进制日志文件和位置,它也采用了新的复制协议。旧的协议往往简单直接,即:首先从服务器上在一个特定的偏移量位置连接到主服务器上一个给定的二进制日志文件,然后主服务器再从给定的连接点开始发送所有的事件。
新协议稍有不同:支持以全局统一事务 ID (GTID) 为基础的复制。当在主库上提交事务或者被从库应用时,可以定位和追踪每一个事务。GTID 复制是全部以事务为基础,使得检查主从一致性变得非常简单。如果所有主库上提交的事务也同样提交到从库上,一致性就得到了保证。
GTID 相关操作:默认情况下将一个事务记录进二进制文件时,首先记录它的 GTID,而且 GTID 和事务相关信息一并要发送给从服务器,由从服务器在本地应用认证,但是绝对不会改变原来的事务 ID 号。因此在 GTID 的架构上就算有了N层架构,复制是N级架构,事务 ID 依然不会改变,有效的保证了数据的完整和安全性。
你可以使用基于语句的或基于行的复制与 GTID ,但是,为了获得最佳效果,我们建议你使用基于行(ROW)的格式。
GTID功能的具体归纳主要有以下两点:
根据 GTID 可以知道事务最初是在哪个实例上提交的
GTID 的存在方便了 Replication 的 Failover
我们可以看下在 MySQL 5.6 的 GTID 出现以前 Replication Failover 的操作过程。假设我们有一个如下图的环境:
此时,Server A 的服务器宕机,需要将业务切换到 Server B 上。同时,我们又需要将 Server C 的复制源改成 Server B。复制源修改的命令语法很简单即:
CHANGE MASTER TO MASTER_HOST='xxx', MASTER_LOG_FILE='xxx', MASTER_LOG_POS=nnnn
而这种方式的难点在于,由于同一个事务在每台机器上所在的 binlog 名字和位置都不一样,那么怎么找到 Server C 当前同步停止点对应 Server B 上 master_log_file 和 master_log_pos 的位置就成为了难题。
这也就是为什么 M-S 复制集群需要使用 MMM、MHA 这样的额外管理工具的一个重要原因。 这个问题在 5.6 的 GTID 出现后,就显得非常的简单。
由于同一事务的 GTID 在所有节点上的值一致,那么根据 Server C 当前停止点的 GTID 就能唯一定位到 Server B 上的GTID。甚至由于 MASTER_AUTO_POSITION 功能的出现,我们都不需要知道 GTID 的具体值。直接使用以下命令就可以直接完成 Failover 的工作。
CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION=='xxx'
如何产生GTID
GTID 的生成受 gtid_next 控制。 在主服务器上gtid_next 是默认的 AUTOMATIC,即在每次事务提交时自动生成新的 GTID 。它从当前已执行的 GTID 集合(即 gtid_executed )中,找一个大于 0 的未使用的最小值作为下个事务 GTID 。同时在 Binlog 的实际的更新事务事件前面插入一条 set gtid_next 事件。
这里以一条 insert 语句来看看 GTID 的生成过程:
在从库上回放主库的 Binlog 时,先执行 SET @&#