MYSQL主从复制gtid浅析

Gtid概念

从 MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式。通过 GTID保证了每个在主库上提交的事务在集群中有一个唯一的ID。 这种方式强化了数据库的主备一致性,故障恢复以及容错能力。
在原来基于二进制日志的复制中,从库需要告知主库要从哪个偏移量进行增量同步,如果指定错误会造成数据的遗漏,从而造成数据的不一致。借助GTID,在发生主备切换的情况下,MySQL的其它从库可以自动在新主库上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。

GTID用来代替classic的复制方法,不在使用binlog+pos开启复制。而是使用master_auto_postion=1的方式自动匹配GTID断点进行复制。(更简单的实现failover,不用以前那样在需要找log_file和log_Pos)

什么是Gitd

GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。 GTID 实际上 是由UUID+TID 组成的 。其中 UUID 是一个 MySQL 实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。
下面是一个GTID的具体形式:3E11FA47-71CA-11E1-9E33-C80AA9429562:23,冒号分割前边为uuid,后边为TID。

GTID 集合可以包含来自多个 MySQL 实例的事务,它们之间用逗号分隔。

如果来自同一MySQL实例的事务序号有多个范围区间,各组范围之间用冒号分隔。例如: e6954592-8dba-11e6-af0e-fa163e1cf111:1-5:11-18,e6954592-8dba-11e6-af0e-fa163e1cf3f2:1-27 可以使用show master status实时查看当前事务执行数

在传统的slave端,binlog是不用开启的,但是在GTID中,slave端的binlog是必须开启的,目的是记录执行过的GTID(强制)。

Gtid的作用

Gtid采用了新的复制协议旧协议是,首先从服务器上在一个特定的偏移量位置连接到主服务器上一个给定的二进制日志文件,然后主服务器再从给定的连接点开始发送所有的事件。
新协议有所不同,支持以全局统一事务ID (GTID)为基础的复制。当在主库上提交事务或者被从库应用时,可以定位和追踪每一个事务。GTID复制是全部以事务为基础,使得检查主从一致性变得非常简单。如果所有主库上提交的事务也同样提交到从库上,一致性就得到了保证。

Gtid的工作原理

  1. 当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。
  2. binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值。(SET @@SESSION.GTID_NEXT= '18f5da07-a096-11ea-8c70-000c290e1abf:7'/!/;)
  3. sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID。
  4. 如果有记录,说明该GTID的事务已经执行,slave会忽略。
  5. 如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行。
  6. 在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。

浅析gtid

#主库上操作
mysql> insert into test values(1000);
mysql> commit;
 
mysql> show master status;
+-------------------+----------+--------------+------------------+------------------------------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+-------------------+----------+--------------+------------------+------------------------------------------+
| master-bin.000001 |     2350 |              |                  | 18f5da07-a096-11ea-8c70-000c290e1abf:1-9 |
+-------------------+----------+--------------+------------------+------------------------------------------+
 
[root@localhost ~]# mysqlbinlog /var/lib/mysql/master-bin.000001 | tail -100f
# at 2087
#200604 21:52:40 server id 1  end_log_pos 2152 CRC32 0x4ebee83f     GTID    last_committed=8    sequence_number=9   rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= '18f5da07-a096-11ea-8c70-000c290e1abf:9'/*!*/;
# at 2152
#200604 21:52:40 server id 1  end_log_pos 2228 CRC32 0x34ada420     Query   thread_id=7 exec_time=0 error_code=0
SET TIMESTAMP=1591278760/*!*/;
BEGIN
/*!*/;
# at 2228
#200604 21:52:40 server id 1  end_log_pos 2279 CRC32 0x3ee3a3ff     Table_map: `students`.`test` mapped to number 108
# at 2279
#200604 21:52:40 server id 1  end_log_pos 2319 CRC32 0xda7bff0e     Write_rows: table id 108 flags: STMT_END_F
 
BINLOG '
qPzYXhMBAAAAMwAAAOcIAAAAAGwAAAAAAAEACHN0dWRlbnRzAAR0ZXN0AAEDAAH/o+M+
qPzYXh4BAAAAKAAAAA8JAAAAAGwAAAAAAAEAAgAB//7oAwAADv972g==
'/*!*/;
# at 2319
#200604 21:52:40 server id 1  end_log_pos 2350 CRC32 0xf7033eee     Xid = 132
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
 
------------------------------------------------------------------------------------
 
#从库操作
#发现master主机插入的数据,已经在slave主机进行了同步,并且启用了log-bin-updates,在slave主机中的二进制日志记录了master主机操作。
[root@localhost ~]# mysqlbinlog /var/lib/mysql/master-bin.000002 | tail -100f
# at 654
#200604 21:52:40 server id 1  end_log_pos 719 CRC32 0xb6fd0db9  GTID    last_committed=2    sequence_number=3   rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= '18f5da07-a096-11ea-8c70-000c290e1abf:9'/*!*/;
# at 719
#200604 21:52:40 server id 1  end_log_pos 782 CRC32 0xc13ca7e7  Query   thread_id=7 exec_time=0 error_code=0
SET TIMESTAMP=1591278760/*!*/;
BEGIN
/*!*/;
# at 782
#200604 21:52:40 server id 1  end_log_pos 833 CRC32 0x6fb18d98  Table_map: `students`.`test` mapped to number 108
# at 833
#200604 21:52:40 server id 1  end_log_pos 873 CRC32 0xa78d775c  Write_rows: table id 108 flags: STMT_END_F
 
BINLOG '
qPzYXhMBAAAAMwAAAEEDAAAAAGwAAAAAAAEACHN0dWRlbnRzAAR0ZXN0AAEDAAGYjbFv
qPzYXh4BAAAAKAAAAGkDAAAAAGwAAAAAAAEAAgAB//7oAwAAXHeNpw==
'/*!*/;
# at 873
#200604 21:52:40 server id 1  end_log_pos 904 CRC32 0x98a3302b  Xid = 21
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

我们从上面输出可以清楚的看见事务id如下(根据上面提到的,这个是第9个事务):

last_committed=8    sequence_number=9   rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= '18f5da07-a096-11ea-8c70-000c290e1abf:9'/*!*/;

GTID的简单工作流程如下:

  1. 在master上产生一个事务并且提交,并且写入binlog

  2. master上的binlog发送到slave,slave接收完毕并且写入relay log,slave读取到这个GTID,并设置gtid_next的值,例如:

/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= '18f5da07-a096-11ea-8c70-000c290e1abf:9'/*!*/;

然后告诉slave接下来的事务必须使用GTID,并写入到它自己的binlog里。

  1. slave检查并确认这个GTID没有被使用,如果没有被使用,那么开始执行这个事务并写入到它自己的binlog里。

  2. 由于gtid_next的值不是空的,slave不会尝试去生成一个新的gtid,而是通过主从复制来获取GTID。

转自:https://blog.csdn.net/qq_34556414/article/details/106559349

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358