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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

之所以把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的改变意味着什么。

作者微信:


270
微信.jpg
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
存储 关系型数据库 MySQL
|
23天前
|
存储 SQL 关系型数据库
【MySQL】4. 表的操作
【MySQL】4. 表的操作
21 0
|
存储 关系型数据库 MySQL
|
17天前
|
SQL 存储 关系型数据库
6本值得推荐的MySQL学习书籍
本文是关于MySQL学习书籍的推荐,作者在DotNetGuide技术社区和微信公众号收到读者请求后,精选了6本值得阅读的MySQL书籍,包括《SQL学习指南(第3版)》、《MySQL是怎样使用的:快速入门MySQL》、《MySQL是怎样运行的:从根儿上理解MySQL》、《深入浅出MySQL:数据库开发、优化与管理维护(第3版)》以及《高性能MySQL(第4版)》和《MySQL技术内幕InnoDB存储引擎(第2版)》。此外,还有12本免费书籍的赠送活动,涵盖《SQL学习指南》、《MySQL是怎样使用的》等,赠书活动有效期至2024年4月9日。
|
22天前
|
SQL 关系型数据库 MySQL
轻松入门MySQL:深入学习数据库表管理,创建、修改、约束、建议与性能优化(3)
轻松入门MySQL:深入学习数据库表管理,创建、修改、约束、建议与性能优化(3)
|
22天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
22天前
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
|
2天前
|
存储 SQL 关系型数据库
MySQL学习手册(第一部分)
mysql日常使用记录
59 0
|
23天前
|
关系型数据库 MySQL
【MySQL】12. 表的内连和外连(重点)
【MySQL】12. 表的内连和外连(重点)
13 0
|
存储 SQL 关系型数据库