GTID的基本概念与应用
一、GTID
1.1 gtid的基本概念
gtid的全称为全局事务标识符(global transaction identifiner),是MySQL 5.6引入的一个特性。gtid保证了MySQL的每一个事务都有一个全局唯一的标识,该标识在本实例甚至主从复制环境都保证全局唯一。
GTID = server_uuid:sequence_id
server_uuid是一个32字节+1字节(/0)的字符串,MySQL第一次启动时生成,并将该信息写入datadir目录下的auto.cnf文件。如果该文件丢失,MySQL会重新生成一个新的server_uuid。相同的server_uuid下的事务对应的sequence_id在binlog文件中是递增且连续有序的,他们以集合的方式呈现。
1.2 gtid带来的便利性
1)通过gtid定位该事务来自哪个实例
2)搭建主从复制不再需要指定binlog文件以及具体的位点信息,而是通过全局唯一的gtid来做复制,MySQL通过gtid来验证冲突并确保每个事务只会被执行一次。
3)方便DBA的运维管理,快速改变主从复制关系
1.3 GTID在主从复制中如何工作?
1)master执行的每一个变更操作都生成一个gtid值,并且会把该值记录在binlog中用来主从复制,后续择机更新gtid_executed表记录
2)主从复制模式下,start slave后,从库会将自身执行过的gtid集合信息发送给主库,主库将从库未执行过的binlog信息发送给从库
3)从库读取relaylog中把该值设置为当前的gtid_next值,对具体的事务进行应用,择机更新gtid_executed表记录。期间主库不断的将新产生的binlog event发送至从库
从库应用主库的事务时不会生成新的gtid值,而是将读取的gtid_next的值记录在自己的binlog文件中
1.4 gtid的维护
1、gtid_executed表
1)MySQL 5.7.5之前
- 该版本下从库必须开始binlog并且设置log_slave_updates=on来保证从库执行过的gtid信息全部记录在binlog中
2)MySQL 5.7.5之后
- MySQL 5.7.5之后新增的mysql.gtid_executed表
- 若不开启binlog,每个事务的gtid信息都会记录到gtid_executed表中
- 若开启binlog且开启log_slave_updates,每个事务的gtid信息不仅会记录到gtid_executed表中,也会在记录在binlog日志中的GTID_LOG_EVENT中
3)概览
- gtid持久化介质
- gtid_executed表会随着数据库的不断更新而存储较多的gtid信息
- MySQL对定期对gtid_executed表进行压缩,通过参数gtid_executed_compression_period进行控制,默认该表记录1000条记录后就进行一次压缩
- MySQL binlog日志切换也会模式对该表进行一次压缩
2、gtid_executed变量
- 该变量为一个gtid set的形式,存储在内存中,表示当前实例执行了哪些gtid事务
- “show slave status\G”、"show master status"中记录的Executed_Gtid_Set都来自该参数的值
3、gtid_purged变量
- 该变量为gtid set的形式,存储在内存中,表示当前实例已经丢失了(执行过)哪些gtid事务
- 通过purge命令或者expire_logs_days参数自动删除历史binlog文件后,会导致历史gtid信息丢失
- 在搭建从库时,我们可以手动指定gtid_purge值来表示当前从库已经执行过了哪些gtid,从该gtid之后重新开始复制
4、gtid_mode
gtid_mode值 | 含义 |
---|---|
ON | 使用gtid模式,新生产的事务为gtid事务,且只能复制gtid事务 |
ON_PERMISSIVE | 新生成的事务为gtid事务,同时可以复制gtid事务或者匿名事务 |
OFF_PERMISSIVE | 新生成的事务为匿名事务,同时可以复制gtid事务或者匿名事务 |
OFF | 关闭gtid模式,新生成的事务为匿名事务,且只能复制匿名事务 |
5、enforce_gtid_consistency
enforce_gtid_consistency值 | 含义 |
---|---|
ON | 不允许任何交易违反GTID一致性 |
WARN | 允许所有事务违反GTID一致性,但是在这种情况下会生成警告,MySQL 5.7.6新增 |
OFF | 允许所有事务违反GTID一致性 |
6、在主/从库中gtid_executed表、gtid_executed变量、gtid_purged变量更新时机
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bzvv6DUI-1593157274284)(http://note.youdao.com/yws/res/56812/FD085068A28544C9A48478E0440293BC)]
7、GTID模块初始化以及binlog_gtid_simple_recovery参数的理解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kUzYKNIB-1593157274289)(http://note.youdao.com/yws/res/56820/33267B0128BE4C9C82E3A5BBCE732C9C)]
二、gtid的应用
2.1 gtid搭建主从
1、gtid相关参数设置
root@mysql57 15:30: [(none)]> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery | ON | //默认为on,不建议关闭。为快速从binlog日志中找到gtid信息
| enforce_gtid_consistency | ON | //该参数必须设置为on,保证gtid的一致性
| gtid_executed_compression_period | 1000 | //指定gtid_executed表压缩
| gtid_mode | ON | //打开gtid模式
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-----------+
8 rows in set (0.00 sec)
2、搭建主从需要关注参数
server_id //主从库server-id必须不一样
log_bin //主库必须打开binlog日志
binlog_format=row //建议使用row模式
gtid_mode=on //开启gtid
enforce_gtid_consitency=on //保证gtid一致性
log_slave_updates //5.6版本中使用gtid必须开启该参数,5.7.5以后该参数决定gtid信息持久化介质是哪些
3、使用gtid模式搭建主从复制
CHANGE MASTER TOMASTER_HOST='master2.example.com',MASTER_USER='replication',MASTER_PASSWORD='password',MASTER_PORT=3306,MASTER_AUTO_POSITION=1;
2.2 传统复制架构 -> gtid复制架构
1、在MySQL 5.7.6之前,需要重启数据库修改
1)关闭主库,停止业务写入
2)等待从库追上主库的复制
3)修改主库、从库配置文件,添加“gtid_mode=on,enforce_gtid_consitency=on”,启动从库时指定–skip-slave-start避免从库启动时继续使用传统模式复制
4)检查主从复制是否修改为gtid模式,且复制状态是否正常
2、在MySQL 5.7.6之后,支持在线修改
1)在每台服务器上设置enforce_gtid_consistency=warn,允许所有事务可以违反gtid的一致性
root@mysql57 20:43: [(none)]> set global enforce_gtid_consistency=warn;
Query OK, 0 rows affected (0.00 sec)root@mysql57 20:43: [(none)]> show variables like '%enforce%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| enforce_gtid_consistency | WARN |
+--------------------------+-------+
1 row in set (0.01 sec)
2)在每台服务器上设置enforce_gtid_consistency=on,保证所有事务都不可以违反gtid的一致性
root@mysql57 20:44: [(none)]> set global enforce_gtid_consistency=on;
Query OK, 0 rows affected (0.00 sec)root@mysql57 20:44: [(none)]> show variables like '%enforce%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| enforce_gtid_consistency | ON |
+--------------------------+-------+
1 row in set (0.00 sec)
3)在每台服务器上设置gtid_mode=off_permissive,表示新事务是匿名事务,同时允许复制的事务是gtid或是匿名事务
root@mysql57 20:47: [repl_test]> show variables like '%gtid%';
+----------------------------------+----------------+
| Variable_name | Value |
+----------------------------------+----------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed_compression_period | 1000 |
| gtid_mode | OFF_PERMISSIVE |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+----------------+
8 rows in set (0.00 sec)
4)在每台服务器上设置gtid_mode=on_permissive,表示新的事务是gtid事务,同时允许复制的事务是gtid或者匿名事务
root@mysql57 20:47: [repl_test]> set global gtid_mode=on_permissive;
Query OK, 0 rows affected (0.02 sec)root@mysql57 20:48: [repl_test]> show variables like '%gtid%';
+----------------------------------+---------------+
| Variable_name | Value |
+----------------------------------+---------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON_PERMISSIVE |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+---------------+
8 rows in set (0.00 sec)
5)在每台从服务器上等待状态参数Ongoing_anonymous_transaction_count的状态值为0,该参数表示正在处理的匿名事务数,只有该状态值降为0才可进行下一步
root@mysql 20:48: [(none)]> show global status like '%transaction%';
+-------------------------------------+-------+
| Variable_name | Value |
+-------------------------------------+-------+
| Ongoing_anonymous_transaction_count | 0 |
+-------------------------------------+-------+
1 row in set (0.00 sec)
6)在每台服务器上设置gtid_mode=on,此后从库只会复制gtid事务
root@mysql57 20:49: [repl_test]> set global gtid_mode=on;
Query OK, 0 rows affected (0.02 sec)root@mysql57 20:50: [repl_test]> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-----------+
8 rows in set (0.00 sec)
7)修改配置文件“gtid_mode=on,enforce_gtid_consitency=on”,保证数据库重启后仍是gtid
8)修改当前复制为gtid复制
root@mysql 20:51: [(none)]> stop slave;
Query OK, 0 rows affected (0.01 sec)root@mysql 20:51: [(none)]>
root@mysql 20:51: [(none)]> change master to master_auto_position=1;
Query OK, 0 rows affected (0.01 sec)
9)检查复制状态以及复制模式
root@mysql 20:51: [(none)]> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Executed_Gtid_Set: ca3051f8-a265-11ea-923e-00163e15aea9:1-6
Auto_Position: 1
2.3 gtid复制架构 -> 传统复制架构
1)转笔从库主从复制,并修改当前复制为传统复制模式
##停止主从复制,并查看当前复制的位点信息
root@mysql 22:46: [(none)]> stop slave;
Query OK, 0 rows affected (0.00 sec)root@mysql 22:46: [(none)]> show slave status\GMaster_Log_File: binlog.000005Read_Master_Log_Pos: 1968Auto_Position: 1##修改gtid复制为传统复制
root@mysql 22:46: [(none)]> change master to master_log_file='binlog.000005',master_log_pos=1968,master_auto_position=0;
Query OK, 0 rows affected (0.02 sec)root@mysql 22:47: [(none)]> start slave;
Query OK, 0 rows affected (0.01 sec)##检查复制模式以及复制状态
root@mysql 22:47: [(none)]> show slave status\GMaster_Log_File: binlog.000005Read_Master_Log_Pos: 2775Auto_Position: 0
2)将每个服务器的gtid_mode设置为on_permissive,表示新的事务还是使用gtid,同时允许复制gtid事务和匿名事务
root@mysql 22:47: [(none)]> set global gtid_mode=on_permissive;
Query OK, 0 rows affected (0.01 sec)root@mysql 22:51: [(none)]> show variables like '%gtid%';
+----------------------------------+---------------+
| Variable_name | Value |
+----------------------------------+---------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON_PERMISSIVE |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+---------------+
8 rows in set (0.00 sec)
3)将每个服务器的gtid_mode设置为off_permissive,表示新的事务为匿名事务,同时允许复制gtid事务和匿名事务
root@mysql 22:51: [(none)]> set global gtid_mode=off_permissive;
Query OK, 0 rows affected (0.01 sec)root@mysql 22:51: [(none)]> show variables like '%gtid%';
+----------------------------------+----------------+
| Variable_name | Value |
+----------------------------------+----------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed_compression_period | 1000 |
| gtid_mode | OFF_PERMISSIVE |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+----------------+
8 rows in set (0.00 sec)
4)查看从库gtid_owned,等待该参数为空,表示当前已经无正在复制中的gtid事务,且后续全部都是匿名事务
root@mysql 22:54: [(none)]> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed_compression_period | 1000 |
| gtid_mode | OFF |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-----------+
8 rows in set (0.00 sec)
5)关闭从库的gtid模式
root@mysql 22:54: [(none)]> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed_compression_period | 1000 |
| gtid_mode | OFF |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-----------+
8 rows in set (0.00 sec)##若主库此刻修改gtid_mode会出现报错:
root@mysql57 22:54: [repl_test]> set global gtid_mode=off;
ERROR 3111 (HY000): SET @@GLOBAL.GTID_MODE = OFF is not allowed because replication channel '' is configured in AUTO_POSITION mode. Execute CHANGE MASTER TO MASTER_AUTO_POSITION = 0 FOR CHANNEL '' before you set @@GLOBAL.GTID_MODE = OFF..
6)修改配置文件,保证重启后也不再使用gtid
gtid_mode=off
enforce_gtid_consistency=off
三、gtid的限制
由于gtid对事务一致性的要求,会导致以下一些问题无法支持:
1、事务中包含对多个存储引擎的查询更新,会导致对该事务分配多个gtid
2、主从库存储引擎不一致的情况下,会导致数据不一致
3、无法使用create table … select 的语句
root@mysql57 23:49: [repl_test]> create table t5 select * from t1;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
row模式下,create table … select其实会转换为两个单独的事务,一个是create table,一个是insert数据。当在事务中执行该语句时,一些情况下会导致两个事务分配了相同的事务id,这意味着从库会忽略掉插入数据的事务,从而导致主从数据不一致
4、只有在acticommit=1的情况下,才支持使用create temporary table和drop temporary table语句
root@mysql57 23:34: [repl_test]> show master status;
+---------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------------------------------+
| binlog.000010 | 1430 | | | ca3051f8-a265-11ea-923e-00163e15aea9:1-21 |
+---------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec)root@mysql57 23:50: [repl_test]> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.00 sec)root@mysql57 23:50: [repl_test]> create temporary table tmp_t1 like t1;
Query OK, 0 rows affected (0.00 sec)root@mysql57 23:50: [repl_test]> show master status;
+---------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------------------------------+
| binlog.000010 | 1430 | | | ca3051f8-a265-11ea-923e-00163e15aea9:1-21 |
+---------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec)root@mysql57 23:51: [repl_test]> drop temporary table tmp_t1;
Query OK, 0 rows affected (0.00 sec)root@mysql57 23:51: [repl_test]> show master status;
+---------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------------------------------+
| binlog.000010 | 1644 | | | ca3051f8-a265-11ea-923e-00163e15aea9:1-22 |
+---------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec)##从库
root@mysql 23:51: [repl_test]> show tables;
+---------------------+
| Tables_in_repl_test |
+---------------------+
| t1 |
| t2 |
| t3 |
| t4 |
+---------------------+
4 rows in set (0.00 sec)root@mysql 23:51: [repl_test]> show master status;
+------------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------------------------------+
| mysql-bin.000013 | 1588 | | | ca3051f8-a265-11ea-923e-00163e15aea9:1-22 |
+------------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec)root@mysql 23:51: [repl_test]> show slave status\G
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventSlave_IO_Running: YesSlave_SQL_Running: YesSlave_SQL_Running_State: Slave has read all relay log; waiting for more updatesRetrieved_Gtid_Set: ca3051f8-a265-11ea-923e-00163e15aea9:18-22Executed_Gtid_Set: ca3051f8-a265-11ea-923e-00163e15aea9:1-22Auto_Position: 1
master创建临时表不产生gtid信息,导致从库无法同步该操作,而后续删除临时表的操作会产生相应的gtid信息并同步到从库,这种情况下就会导致主从复制报错中断
5、不推荐在开启gtid模式的实例上使用mysql_upgrate
GTID的基本概念与应用相关推荐
- [MySQL 5.6] GTID实现、运维变化及存在的bug
[MySQL 5.6] GTID实现.运维变化及存在的bug http://www.tuicool.com/articles/NjqQju 由于之前没太多深入关注gtid,这里给自己补补课,本文是我看 ...
- mysql 5.6的gtid_mode_[MySQL 5.6] GTID实现、运维变化及存在的bug
本文的主要目的是记下跟gtid相关的backtrace,用于以后的问题排查.另外也会讨论目前在MySQL5.6.11版本中存在的bug. 前言:什么是GTID 什么是GTID呢, 简而言之,就是全局事 ...
- 《深入理解MySQL主从原理32讲》推荐篇
导读: 作者:高鹏(网名八怪),<深入理解MySQL主从原理32讲>系列文的作者.2008年开始至今一直从事Oracle/MySQL相关工作,现任易极付高级DBA,Oracle Ocm. ...
- mysql序列号生成_超详细的mysql数据库GTID介绍—概念、优缺点、原理、生命周期等
概述 这几天就简单介绍一下GTID好了~这篇是概念篇.. 从MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式.通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID.这种 ...
- mysql 基于gtid复制_深入MySQL复制(二):基于GTID复制
相比传统的MySQL复制,gtid复制无论是配置还是维护都要轻松的多.本文对gtid复制稍作介绍. 1.gtid基本概念 传统的基于binlog position复制的方式有个严重的缺点:如果slav ...
- mysql 5.7 gtid 主从_MySQL 5.7基于GTID的主从复制实践
GTID是基于mysql事务实现的,如果对mysql事务没啥概念的话,建议先看看 不在单独说明如何搭建mysql单点 请参考 然后再看这个gtid的 现在有这样一个需求: 主1mysql 是个单点的m ...
- 配置MYSQL基于GTID 主从复制详细解析及步骤
GTID的概念 全局事务标识:global transaction identifiers GTID是一个事务一一对应,并且全局唯一ID GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或主 ...
- MySQL 5.7基于GTID及多线程主从复制
点击上方"朱小厮的博客",选择"设为星标" 后台回复"1024"领取公众号专属资料 来源:rrd.me/gDJDK MySQL主从同步原理 ...
- mysql gtid ha_MySQl新特性 GTID
GTID简介 概念 全局事务标识符(GTID)是创建的唯一标识符,并与在源(主)服务器上提交的每个事务相关联.此标识符不但是唯一的,而且在给定复制设置中的所有服务器上都是唯一的.所有交易和所有GTID ...
最新文章
- 拆位 ---- C. Johnny and Another Rating Drop[位运算,计算每一位的贡献+推导过程]
- rust图形编程_国产编程语言“木兰”,你以为是个王者,结果是个玩笑
- mysql取出数据外键_mysql数据表有外键,应注意的几点(目前学习所获得的经验)...
- ThinkJava-复用类
- 从3个科技公司里学到的57条经验(转)
- access 日期交集_Access重要知识点
- 中文验证码 php_还在苦恼验证码怎么实现?看看这个验证码组件合集,你想要的都有...
- Android 对ScrollView滚动监听,实现美团、大众点评的购买悬浮效果
- Eclipse自动生成作者、日期注释等功能设置
- 计算机网络技术专业一体化课程方案,计算机网络技术专业网络设备的安装与配置...
- 学习BMFONT的感想
- 我的软件测试修炼之道
- 完整的产品管理工作流程
- ChucK学习笔记(零)——前言
- Linux下parity联盟链的实现
- SEC主席Gary Gensler在被问及以太坊是否是证券时,选择了沉默
- 韩信点兵python源代码_Python实现“韩信点兵”
- WEB浏览器视频流播放方案
- 怎样读懂计算机论文算法,最新计算机算法分析论文参考文献 计算机算法分析专著类参考文献有哪些...
- 深度学习AI美颜系列----人像静态/动态贴纸特效算法实现