Mysql 5.7 Gtid内部学习(四) mysql.gtid_executed表的作用和Previous gtid Event的改变


之所以把mysql.gtid_executed表的作用和Previous gtid Event的改变放到一起进行描述是因为它们后面文章探讨的基础。这部分使用到了我自己使用C语言写的原生binlog解析工具infobin。
百度云盘下载如下:
http://pan.baidu.com/s/1jHIWUN0

一、Gtid event

为什么要先描述什么是Gtid event呢?因为后面会用到,实际上在中其核心元素就是一个形如:

31704d8a-da74-11e7-b6bf-52540a7d243:100009

的一个Gtid处于整个事务event中的开始,用于描述这个事务的Gtid是多少,当然在5.7中为了支持MTS其中还封装了last_commit/sequence_number。那么使用infobin工具查看一个insert单条语句完整事务的event包括如下:

>Gtid Event:Pos:234(0Xea) N_pos:299(0X12b) Time:1513135186 Event_size:65(bytes) 
Gtid:31704d8a-da74-11e7-b6bf-52540a7d243:100009 last_committed=0  sequence_number=1
-->Query Event:Pos:299(0X12b) N_Pos:371(0X173) Time:1513135186 Event_size:72(bytes) 
Exe_time:0  Use_db:test Statment(35b-trun):BEGIN /*!Trx begin!*/ Gno:100009
---->Map Event:Pos371(0X173) N_pos:415(0X19f) Time:1513135186 Event_size:44(bytes) 
TABLE_ID:108 DB_NAME:test TABLE_NAME:a Gno:100009
------>Insert Event:Pos:415(0X19f) N_pos:455(0X1c7) Time:1513135186 Event_size:40(bytes) 
Dml on table: test.a  table_id:108 Gno:100009 
>Xid Event:Pos:455(0X1c7) N_Pos:486(0X1e6) Time:1513135186 Event_size:31(bytes) 
COMMIT; /*!Trx end*/ Gno:100009

当然也可以使用mysqlbinlog进行分析,只是格式稍微不那么友好。

二、gtid_executed表的作用

这一部分是重点中的重点,也是我以前一直疑惑的,请大家细细品读。
官方文档这样描述gtid_executed表

Beginning with MySQL 5.7.5, GTIDs are stored in a table named gtid_executed, in the mysql
database. A row in this table contains, for each GTID or set of GTIDs that it represents, the UUID of the
originating server, and the starting and ending transaction IDs of the set; for a row referencing only a
single GTID, these last two values are the same.

也就是说gtid_executed表是Gtid持久化的一个工具,如前文所描述Gtid_state中的get_executed_gtids/get_lost_gtids/get_gtids_only_in_table/get_previous_gtids_logged这些数据都是存储在内存中的,那么在数据库重启后需要进行初始化,那么这需要读取Gtid持久化的介质,我们可以发现gtid_executed是一个innodb表建表语句如下,并且我们可以手动更改它,但是千万不要这么干:

       Table: gtid_executed
Create Table: CREATE TABLE `gtid_executed` (
  `source_uuid` char(36) NOT NULL COMMENT 'uuid of the source where the transaction was originally executed.',
  `interval_start` bigint(20) NOT NULL COMMENT 'First number of interval.',
  `interval_end` bigint(20) NOT NULL COMMENT 'Last number of interval.',
  PRIMARY KEY (`source_uuid`,`interval_start`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0

那么在5.7.5以前没有gtid_executed表不是也没有问题吗?其实除了gtid_executed表以外我们还有一个Gtid持久化的介质那就是binlog中的Gtid event。所以总结一下Gtid持久化介质:

  • gtid_executed表
  • binlog中的gtid event

那么既然有了binlog的gtid event进行持久化那么为什么还需要gtid_executed表呢?这实际上就是5.7.5过后的一个优化,我们可以反过来思考在5.6中如果使用了Gtid做从库,从库如果不开启binlog并且同时设置log_slave_updates=ture那么从库的执行过的Gtid事务是没有办法持久化的。我们来一段5.6官方文档对于搭建Gtid从库的其中一步:

Step 3: Restart both servers with GTIDs enabled. To enable binary logging with global
transaction identifiers, each server must be started with GTID mode, binary logging, slave update
logging enabled, and with statements that are unsafe for GTID-based replication disabled. In addition,
you should prevent unwanted or accidental updates from being performed on either server by starting
both in read-only mode. This means that both servers must be started with (at least) the options shown
in the following invocation of mysqld_safe:
shell> mysqld_safe --gtid_mode=ON --log-bin --log-slave-updates --enforce-gtid-consistency &

开启binlog同时设置设置log_slave_updates=ture必然造成一个问题,实际上从库很多时候我们是不需要做级联slave,设置log_slave_updates=ture会造成需要额外的空间和性能开销。自然这种情况下我们需要另外的一种Gtid持久化介质,而并不是binlog中的Gtid event。为了解决这个问题,5.7中gtid_executed表应运而生了。然而gtid_executed表是否需要实时更新呢?显然在slave端不开启binlog或者开启binlog不设置log_slave_updates=ture的情况下它需要实时更新,因为I/O thread执行过得Gtid是必须持久化的,而在主库上因为有binlog的Gtid event的存在他是不需要实时更新的,这样不同的对待方式也能够减轻负担提高性能。
同时在官方文档上也有相关描述它分为是否开始binlog进行描述,但是其描述并不是最详细的。所以这部分在后面我会进行详细描述。

三、Previous gtid Event的改变

Previous gtid Event是包含在每一个binlog的开头用于描述所有以前binlog所包含的全部Gtid的一个集合(包括已经删除的binlog)如:

da267088-9c22-11e7-ab56-5254008768e3:1-32

在5.6中如果不开启Gtid,那么binlog是不会包含这个Previous gtid Event的,但是在5.7中不开启Gtid也会包含这个Previous gtid Event,实际这一点的改变其意义也是非常巨大,简单的说他为快速扫描binlog(binlog_gtid_simple_recovery=ture)获得正确Gtid集合提供了基础,否则将会扫描大量的binlog,从而浪费I/O性能,这是5.6中一个非常严重的问题,在5.7的官方文档这样描述:

When binlog_gtid_simple_recovery=TRUE, which is the default in MySQL 5.7.7 and
later, the server iterates only the oldest and the newest binary log files and the values of
gtid_purged and gtid_executed are computed based only on Previous_gtids_log_event
or Gtid_log_event found in these files. This ensures only two binary log files are iterated during
server restart or when binary logs are being purged

当然这部分也会在后面进行详细的描述,这里只是简单提一下。那么我们通过mysqlbinlog 和infobin工具分别确认这一点。

  • 5.6. 26 不开启Gtid

mysqlbinlog:

*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#171211 16:20:10 server id 20155  end_log_pos 120 CRC32 0x12617db7      Start: binlog v 4, server v 5.6.26-74.0-log created 171211 16:20:10
# Warning: this binlog is either in use or was not closed properly.
# at 120
#171211 16:20:14 server id 20155  end_log_pos 192 CRC32 0x696752cb      Query   thread_id=30    

infobin:

------------Detail now--------------
>Format description log Event:Pos:4(0X4) N_pos:120(0X78) Time:1512980410 Event_size:116(bytes) 
-->Query Event:Pos:120(0X78) N_Pos:192(0Xc0) Time:1512980414 Event_size:72(bytes) 
Exe_time:0  Use_db:test Statment(35b-trun):BEGIN /*!Trx begin!*/ Gno:0
---->Map Event:Pos192(0Xc0) N_pos:241(0Xf1) Time:1512980414 Event_size:49(bytes) 
TABLE_ID:91 DB_NAME:test TABLE_NAME:testpo Gno:0
------>Insert Event:Pos:241(0Xf1) N_pos:281(0X119) Time:1512980414 Event_size:40(bytes) 
Dml on table: test.testpo  table_id:91 Gno:0 
>Xid Event:Pos:281(0X119) N_Pos:312(0X138) Time:1512980414 Event_size:31(bytes) 
COMMIT; /*!Trx end*/ Gno:0

我们并没有发现Previous gtid Event,也就是5.6如果不开启Gtid则不包含Previous gtid Event。

  • 5.7.14

mysqlbinlog:

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#171211 16:26:49 server id 1  end_log_pos 123 CRC32 0xf9a36298  Start: binlog v 4, server v 5.7.14-7-debug-log created 171211 16:26:49
# Warning: this binlog is either in use or was not closed properly.
# at 123
#171211 16:26:49 server id 1  end_log_pos 194 CRC32 0x5865633f  **Previous-GTIDs**
# da267088-9c22-11e7-ab56-5254008768e3:1-32
# at 194

infobin:

------------Detail now--------------
>Format description log Event:Pos:4(0X4) N_pos:123(0X7b) Time:1512980809 Event_size:119(bytes) 
>Previous gtid Event:Pos:123(0X7b) N_pos:194(0Xc2) Time:1512980809 Event_size:71(bytes) 
>Anonymous gtid Event:Pos:194(0Xc2) N_pos:259(0X103) Time:1512980814 Event_size:65(bytes) 
Gtid:Anonymous(Gno=0) last_committed=0  sequence_number=1
-->Query Event:Pos:259(0X103) N_Pos:331(0X14b) Time:1512980814 Event_size:72(bytes) 
Exe_time:0  Use_db:test Statment(35b-trun):BEGIN /*!Trx begin!*/ Gno:0
---->Map Event:Pos331(0X14b) N_pos:380(0X17c) Time:1512980814 Event_size:49(bytes) 
TABLE_ID:154 DB_NAME:test TABLE_NAME:testpo Gno:0
------>Insert Event:Pos:380(0X17c) N_pos:420(0X1a4) Time:1512980814 Event_size:40(bytes) 
Dml on table: test.testpo  table_id:154 Gno:0 
>Xid Event:Pos:420(0X1a4) N_Pos:451(0X1c3) Time:1512980814 Event_size:31(bytes) 
COMMIT; /*!Trx end*/ Gno:0

我们清晰的看到这里包含了Previous gtid Event,当然我们还发现了Anonymous gtid Event这也是5.7中变化,5.7中即使不开始Gtid每个事务也包含也一个Anonymous gtid Event,虽然没有Gtid但是它任然包含了 last_committed/sequence_number。

四、本节小结

学习完本节至少能够学习到:

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

推荐阅读更多精彩内容