概念和组成
1,全局事务表示:global transaction identifiers
2, GTID和事务一一对应,并且全局唯一
3,一个GTID在一个服务器上只执行一次
4,mysql 5.6.5开始支持
组成
GTID = server_uuid:transaction_id 如:4855c186-ba02-11ef-8bf4-000c297511da:23
server_uuid 是集群唯一事务id是单调递增整数
查看方式1:select @@server_uuid
查看方式2:auto.cnf文件
GTID和binlog关系
2.1 Binlog构成
1, 版本信息,binlog metadata, etc
2, Previous_gtid_log_event: 用于表示当前binlog文件之前已经执行过的gtid集合,记录在Binlog文件头,如:4855c186-ba02-11ef-8bf4-000c297511da:1-23
3, GTID event 结构
假设有4个binlog: mysql-bin.000001 - mysql-bin.000004
mysql-bin.000001:Previous-GTIDs=empty; binlog_event:1-40
mysql-bin.000002:Previous-GTIDs=1-40; binlog_event:41-80
mysql-bin.000003:Previous-GTIDs=41-80; binlog_event:81-120
mysql-bin.000004:Previous-GTIDs=81-120; binlog_event:121-160
2.2 查找GTID=N 对应的binlog文件
1,假设我们要找GTID = N,那么MySQL的扫描顺序为: 从最后一个binlog开始扫描(即: mysql-bin.000004)
2,mysql-bin.000004 的previous-gtid = 1-120, 如果N = 140 > Previous-GTIDs,那么GTID = 140 肯定在mysql-bin.000004 中
3, mysql-bin.000004 的previous-gtid = 1-120, 如果N = 88 在 Previous-GTIDs 中,那么继续对比上一个binlog文件mysql-bin.000003,然后继续step2,直到找到为止
GTID复制协议
主从同步GTID过程
1, 从库向主库发送 COMBINLOGDUMP_GTID 命令,同时携带从库已经执行的 GTID 集合。
2,主库接收到请求后,会检查从库的 GTID 集合是否是主库 GTID 集合的子集
3,主库将从库缺失的事务发送给从库。
4, 从库接收到主库发送的事务后,执行这些事务,从而实现数据的同步。 同样的GTID不能被执行两次,如果有同样的GTID会自动skip。
传统复制和GTID对比
传统复制产生的问题
如果master 宕机,需要切换到slave1上,那么slave2就需要挂载到slave1上。由于同一个事物在每台机器上所在的binlog名字和位置不一样,那么如何找到slave2当前同步停止点对应Slave1上的master_log_file和master_log_pos位置就成为一个难点
GTID模式下的处理
由于一个事务的GTID在所有节点上一致,那么根据slave2 当前停止点的GTID就能定位到slave1上的GTID。 直接使用 CHANGE MASTER TO MASTER_HOST=‘xxx’, MASTER_AUTO_POSITION=1 命令就可以字节完成failover的工作
搭建GTID环境
从0开始搭建
配置主从my.cnf文件
创建复制账户
使用change master更新主从配置
传统复制升级为GTID复制
1,master和slave的my.cnf文件中添加下面配置
gtid_mode=ON
enforce_gtid_consistency=1
2, master设置为read_only模式,等待主从同步完毕
3, 一次重启master和slave 的mysqld服务,重启后可以看到gtid_mode是打开的
mysql> show global variables like '%gtid%';
+----------------------------------+------------------------------------------+
| Variable_name | Value |
+----------------------------------+------------------------------------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed | 4855c186-ba02-11ef-8bf4-000c297511da:1-5 |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+------------------------------------------+
8 rows in set (0.01 sec)
4,使用change master更新主从配置
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)mysql> CHANGE MASTER TO -> MASTER_HOST='192.168.10.129',-> MASTER_USER='repl',-> MASTER_PASSWORD='abcd1234',-> MASTER_PORT=3358,-> MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.04 sec)
5, 验证
使用 show slave status\G 查看主从复制状态,如果Auto_Position: 1 即表示当前是GTID模式
Retrieved_Gtid_Set: Executed_Gtid_Set: 4855c186-ba02-11ef-8bf4-000c297511da:1-5Auto_Position: 1Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version:
1 row in set (0.00 sec)
如果要转回传统复制,则将这2行删除再重启即可
GTID相关参数
Variable_name | VALUE | 含义 |
enforce_gtid_consistency | ON | 保持GTID强一致 OFF:允许所有事务违反 GTID 一致性。 ON:没有事务允许违反 GTID 一致性。 WARN:所有事务允许违反 GTID 一致性,但会产生一个警告 |
gtid_executed | 4855c186-ba02-11ef-8bf4-000c297511da:1-7 | 执行过的所有GTID |
gtid_mode | ON | GTID开关模式 |
gtid_owned | 正在运行的gtid | |
gtid_purged | 4855c186-ba02-11ef-8bf4-000c297511da:1-6 | 丢弃掉的GTID,被清理的binlog中的gtid |
gtid_next | AUTOMATIC | session级别变量,下一个要执行的gtid |
binlog_gtid_simple_recovery | ON | 用于控制在 MySQL 启动时,如何遍历二进制日志文件(binlog)以寻找全局事务标识符(GTID) |
gtid_executed_compression_period | 1000 | 1000用于控制压缩 mysql.gtid_executed 表的事务阈值数量 |
session_track_gtids | OFF | 用于控制在会话中是否跟踪全局事务标识符(GTIDs) OFF:关闭 GTID 跟踪。 OWN_GTID:返回当前事务产生的 GTID。 ALLGTIDS:返回系统执行的所有 GTID,即 GTIDEXECUTED |
enforce_gtid_consistency 参数如果开启,则下面几种sql不允许执行
1,create table xx select statements
2,事务中 create/drop temporary table
3,同时更新事务引擎和非事务引擎
mysql> create table hero4 as select * from hero;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
mysql>