MySQL Replication--全局参数gtid_executed和gtid_purged
参数定义
gtid_executed,全局参数,GTID集合包含所有在该服务器上执行过的事务编号和使用set gtid_purged语句设置过的事务编号,使用SHOW MASTER STATUS和SHOW SLAVE STATUS命令得到的Executed_Gtid_Set列值就取自于全局参数gitd_executed。
gtid_purged,全局参数,GTID集合包含从binlog中purged掉的事务ID,该集合是全局参数gtid_executed的子集。
官方参数解释:
gtid_executed
When used with global scope, this variable contains a representation of the set of all transactions executed on the server and GTIDs that have been set by a SET gtid_purged statement. This is the same as the value of the Executed_Gtid_Set column in the output of SHOW MASTER STATUS and SHOW SLAVE STATUS.
gtid_purged
The set of all transactions that have been purged from the binary log. This is a subset of the set of transactions in gtid_executed.
参数更新机制
当复制主库关闭binlog时:
1. 事务提交不会生成GTID,mysql.gtid_executed表/gtid_executed变量/gtid_purged变量均不更新。
当复制主库开启binlog时:
1. 事务提交需要生成Binlog,GTID在Binlog的ordered_commit flush阶段生成。
2. 表mysql.gtid_executed在实例重启或flush log或binlog文件写满等造成binlog发生切换是保存上一个binlog执行过的全部gtid,属于非实时更新。
3. 全局变量gtid_executed在事务commit阶段更新,属于实时更新。
4. 全局变量gtid_purged在执行purge binary log命令或binlog超过保持期进行清理binlog时更新,属于非实时更新。
当复制从库关闭binlog或关闭log_slave_update时:
1. 在从库上应用主库binlog时不会生成新的GTID,也不会写入复制从库的binlog文件。
2. 表mysql.gtid_executed在应用主库binlog事务时更新,并与事务一起提交,属于实时更新。
3. 全局变量gtid_executed在主库binlog事务commit阶段更新,属于实时更新。
4. 全局变量gtid_purged在主库binlog事务commit阶段更新,属于实时更新。
当复制从库开启binlog或开启log_slave_update时:
1. 在从库上应用主库binlog时不会生成新的GTID,但会写入复制从库的binlog文件。
2. 表mysql.gtid_executed在实例重启或flush log或binlog文件写满等造成binlog发生切换是保存上一个binlog执行过的全部gtid,属于非实时更新。
3. 全局变量gtid_executed在事务commit阶段更新,属于实时更新。
4. 全局变量gtid_purged在执行purge binary log命令或binlog超过保持期进行清理binlog时更新,属于非实时更新。
参数重置机制
在某些场景下,需要修改全局变量gtid_purged和gtid_executed的值,执行对全局变量gtid_purged进行赋值时,会报以下错误:
ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
设置@@GLOBAL.GTID_EXECUTED需要通过RESET MASTER命令,该命令会情况当前服务器上的Binlog文件,并将@@GLOBAL.GTID_EXECUTED和@@GLOBAL.GTID_PURGED的值重置为空,重新初始化binlog文件序号,重新初始化GTID的事务ID起始值.
参数恢复机制
参数binlog_gtid_simple_recovery用于控制在实例重启时,如何计算全局变量gtid_executed和gtid_purged。在MySQL 5.7.7及之后版本中该参数默认为True
binlog_gtid_simple_recovery=FALSE
• To initialize gtid_executed, binary log files are iterated from the newest file, stopping at the first binary log that has any Previous_gtids_log_event. All GTIDs from Previous_gtids_log_event and Gtid_log_events are read from this binary log file. This GTID set is stored internally and called gtids_in_binlog. The value of gtid_executed is computed as the union of this set and the GTIDs stored in the mysql.gtid_executed table.
This process could take a long time if you had a large number of binary log files without GTID events, for example created when gtid_mode=OFF.
• To initialize gtid_purged, binary log files are iterated from the oldest to the newest, stopping at the first binary log that contains either a Previous_gtids_log_event that is non-empty (that has at least one GTID) or that has at least one Gtid_log_event. From this binary log it reads Previous_gtids_log_event. This GTID set is subtracted from gtids_in_binlog and the result stored in the internal variable gtids_in_binlog_not_purged. The value of gtid_purged is initialized to the value of gtid_executed, minus gtids_in_binlog_not_purged.
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.
在实例重启后,全局变量gtid_executed和gtid_purged的值取决于:
1、从binlog文件头读取Previous_gtids_log_event获取该binlog之前的gtid_set
2、从binlog文件的所有事件中获取该binlog中包含的gtid_set
3、从mysql.gtid_executed表获取到执行过的gtid_set
通过上面三个集合算出当前实例执行过的gtid_set和当前BINLOG中包含的gtid_set。
mysql.gtid_executed表更新机制
在MySQL 5.6版本中,开启GTID模式必须打开参数log_slave_updates,即从库必须在记录一份binlog,以保证在从库重启后,可以通过扫描最后一个二进制日志获得当前从库执行过的GTID集合。
在MySQL 5.7.5版本中引入mysql.gtid_executed表来存放gtid信息,因此在GTID模式下不要求开启log_slave_update参数。
在MySQL 5.7版本中,对mysql.gtid_executed表的更新策略分为:
1、主库服务器,未开启log_bin参数,则不对mysql.gtid_executed表进行更新。
2、主库服务器,开启log_bin参数,当二进制文件进行rotation时或者关闭实例时对mysql.gtid_executed进行更新。
3、从库服务器,未开启log_bin参数或未开启log_slave_updates参数,在用户事务执行时对mysql.gtid_executed进行更新,并与用户事务一起进行提交。
4、从库服务器,开启log_bin参数和开启log_slave_updates参数,当二进制文件进行rotation时或者关闭实例时对mysql.gtid_executed进行更新。
当主库开启log_bin参数或从库开启log_slave_update参数时,执行或应用事务所生成的binlog会写入磁盘,当二进制文件进行rotation时或者关闭实例时对mysql.gtid_executed进行更新,表mysql.gtid_executed中不能提供完整的GTID集合数据,需以参数gtid_executed为准,如果实例异常重启,最近的GTID集合数据没有更新到mysql.gtid_executed表中,当实例恢复时,通过扫描最后一个binlog文件来获得最新的GTID集合数据。
当从库未开启log_bin参数或未开启log_slave_updates参数时,应用主库所传递过来的事务不会产生新的binlog,在执行事务开始便可以获取到该事务的GTID,因此可以随着事务一起提交,类似于MySQL 5.6版本中随事务一起更新mysql.slave_master_info表一样。
当执行RESET MASTER时,表mysql.gtid_executed会被清空。
mysql.gtid_executed表压缩
当从库未开启log_slave_updates参数时,由于每个事务都会向mysql.gtid_executed表写入记录,为防止mysql.gtid_executed表数据量暴增,MySQL 5.7引入参数gtid_executed_compression_period来控制每执行N个事务后,对mysql.gtid_executed表进行一次压缩,将多个连续的gtid值合并为gtid集合。如果gtid_executed_compression_period被设置为0,则不会进行压缩。
当主库开启log_bin参数或从库开启log_slave_update参数时,参数gtid_executed_compression_period并不会被使用,只有当二进制文件进行Rotation时才会进行GTID压缩。
Xtrabackup备份恢复
在使用Xtrabackup热备+BINLOG位点方式搭建主从复制的场景中,会发现从库上存在GTID空隙。
由于所有数据库服务器都配置开启log_bin参数和log_slave_updates参数,因此每次执行事务不会更新mysql.gtid_executed表。
在使用Xtrabackup热备搭建主从复制时,假设:
1、T1时间点开始热备。
2、T2时间点备份到mysql.gtid_executed表。
3、T3时间点mysql.gtid_executed表最后一次更新。
4、T4时间点热备完成
在使用Xtrabackup热备恢复后,新实例上mysql.gtid_executed表为T3时间点的gtid_set,而新实例上没有任何BINLOG文件,因此新实例上全局参数gtid_executed和gtid_purged的值为T3时间点的gtid_set。而使用基于位点的方式搭建复制,新从库从T4时间点后的BINLOG日志开始应用。最终导致T3时间点到T4时间点的gtid_set没有包含在新从库的全局参数gtid_executed中,出现GTID空隙。
MySQL Replication--全局参数gtid_executed和gtid_purged的更多相关文章
- mysql数据库全局只读和会话只读问题解析
对于系统的发布是经常有的事情,有些时候需要隔绝外界对数据库的更改但是还要求可以读取数据,对于mss sql 这个就是很简单,直接属性—>选项—>只读 ,但是对于mysql这是不同的,今天仔 ...
- MySQL 各种超时参数的含义
MySQL 各种超时参数的含义 今日在查看锁超时的设置时,看到show variables like '%timeout%';语句输出结果中的十几种超时参数时突然想整理一下,不知道大家有没有想过,这么 ...
- gtid_executed和gtid_purged变量是如何初始化的
一.官方释义 1.1.gtid_executed.gtid_purged https://dev.mysql.com/doc/refman/5.7/en/replication-options-gti ...
- MySQL Replication需要注意的问题
MySQL Replication 大家都非常熟悉了,我也不会写怎么搭建以及复制的原理,网上相关文章非常多,大家可以自己去搜寻.我在这里就是想总结一下mysql主从复制需要注意的地方.有人说主从复制很 ...
- MySQL Replication 优化和技巧、常见故障解决方法
MySQL 主从同步错误(error)解决(转) sql_slave_skip_counter参数 附: 一些错误信息的处理,主从服务器上的命令,及状态信息. 在从服务器上使用show slave s ...
- 浅谈MySQL Replication(复制)基本原理
1.MySQL Replication复制进程MySQL的复制(replication)是一个异步的复制,从一个MySQL instace(称之为Master)复制到另一个MySQL instance ...
- 搭建mysql主从复制---Mysql Replication
主从复制原理 Mysql的Replication是一个异步的复制过程,从一个Mysql Instance(master)复制到另一个Mysql Instance(slave).中间需要三个线程slav ...
- 浅析 MySQL Replication(本文转自网络,非本人所写)
作者:卢飞 来源:DoDBA(mysqlcode) 0.导读 本文几乎涵盖了MySQL Replication(主从复制)的大部分知识点,包括Replication原理.binlog format.复 ...
- 第 13 章 可扩展性设计之 MySQL Replication
前言: MySQL Replication 是 MySQL 非常有特色的一个功能,他能够将一个 MySQL Server 的 Instance 中的数据完整的复制到另外一个 MySQL Server ...
随机推荐
- xml解析与生成的学习资料
xml解析与生成的学习资料:http://blog.csdn.net/u012325167/article/category/6129813 ----------------------------- ...
- Map中根据条件删除元素
今天在写程序过程中,需要根据判断条件删除一个Map中的相应数据,我自然而然想到可以通过调用Map中的remove(Object key)函数进行删除:代码如下: public Map<Doubl ...
- html回顾随笔JS(*^__^*)
---恢复内容开始--- map遍历 function b(){ var week = new Map(); week.set("Mon","星期一"); we ...
- easyui 日期控件限制起始相差30天
$('#lendDateStart').datebox('calendar').calendar({ validator: function(date){ var endDateStr = $('#l ...
- 从命令行模式运行Windows管理工具。
从命令行模式运行Windows管理工具. 分类: Play Windows 2004-08-06 16:39 6076人阅读 评论(3) 收藏 举报 1.可以直接在开始-〉运行里面输入的管理工具: 文 ...
- 单字段去重 distinct 返回其他多个字段
select a.*, group_concat(distinct b.attribute_name) from sign_contract_info a left join sign_temp_at ...
- [深入理解Java虚拟机]<垃圾收集器与内存分配策略>
Overview 垃圾收集考虑三件事: 哪些内存需要回收? 什么时候回收? 如何回收? 重点考虑Java堆中动态分配和回收的内存. Is Object alive? 引用计数法 给对象添加一个引用计数 ...
- ESP8266 上线
1.首先配置esp8266 WIFI模块 使用USB转 TTL 连接 esp8266 WIFI模块,波特率115200 //查询固件版本 AT+GMR //设置WiFi应用模式为Station AT+ ...
- CentOS部署PHP环境
1.安装apache yum -y install httpd httpd-devel 2.启动apache systemctl start httpd.service 检查apache状态 syst ...
- python day10 参数,命名空间
一.函数的参数--动态传参 1.动态接收位置参数 1.1在参数位置编写*表示接收任意多个内容 def chi(*food): print("我要吃", food) chi(&quo ...