一、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的基本概念与应用相关推荐

  1. [MySQL 5.6] GTID实现、运维变化及存在的bug

    [MySQL 5.6] GTID实现.运维变化及存在的bug http://www.tuicool.com/articles/NjqQju 由于之前没太多深入关注gtid,这里给自己补补课,本文是我看 ...

  2. mysql 5.6的gtid_mode_[MySQL 5.6] GTID实现、运维变化及存在的bug

    本文的主要目的是记下跟gtid相关的backtrace,用于以后的问题排查.另外也会讨论目前在MySQL5.6.11版本中存在的bug. 前言:什么是GTID 什么是GTID呢, 简而言之,就是全局事 ...

  3. 《深入理解MySQL主从原理32讲》推荐篇

    导读: 作者:高鹏(网名八怪),<深入理解MySQL主从原理32讲>系列文的作者.2008年开始至今一直从事Oracle/MySQL相关工作,现任易极付高级DBA,Oracle Ocm. ...

  4. mysql序列号生成_超详细的mysql数据库GTID介绍—概念、优缺点、原理、生命周期等

    概述 这几天就简单介绍一下GTID好了~这篇是概念篇.. 从MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式.通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID.这种 ...

  5. mysql 基于gtid复制_深入MySQL复制(二):基于GTID复制

    相比传统的MySQL复制,gtid复制无论是配置还是维护都要轻松的多.本文对gtid复制稍作介绍. 1.gtid基本概念 传统的基于binlog position复制的方式有个严重的缺点:如果slav ...

  6. mysql 5.7 gtid 主从_MySQL 5.7基于GTID的主从复制实践

    GTID是基于mysql事务实现的,如果对mysql事务没啥概念的话,建议先看看 不在单独说明如何搭建mysql单点 请参考 然后再看这个gtid的 现在有这样一个需求: 主1mysql 是个单点的m ...

  7. 配置MYSQL基于GTID 主从复制详细解析及步骤

    GTID的概念 全局事务标识:global transaction identifiers GTID是一个事务一一对应,并且全局唯一ID GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或主 ...

  8. MySQL 5.7基于GTID及多线程主从复制

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"1024"领取公众号专属资料 来源:rrd.me/gDJDK MySQL主从同步原理 ...

  9. mysql gtid ha_MySQl新特性 GTID

    GTID简介 概念 全局事务标识符(GTID)是创建的唯一标识符,并与在源(主)服务器上提交的每个事务相关联.此标识符不但是唯一的,而且在给定复制设置中的所有服务器上都是唯一的.所有交易和所有GTID ...

最新文章

  1. 拆位 ---- C. Johnny and Another Rating Drop[位运算,计算每一位的贡献+推导过程]
  2. rust图形编程_国产编程语言“木兰”,你以为是个王者,结果是个玩笑
  3. mysql取出数据外键_mysql数据表有外键,应注意的几点(目前学习所获得的经验)...
  4. ThinkJava-复用类
  5. 从3个科技公司里学到的57条经验(转)
  6. access 日期交集_Access重要知识点
  7. 中文验证码 php_还在苦恼验证码怎么实现?看看这个验证码组件合集,你想要的都有...
  8. Android 对ScrollView滚动监听,实现美团、大众点评的购买悬浮效果
  9. Eclipse自动生成作者、日期注释等功能设置
  10. 计算机网络技术专业一体化课程方案,计算机网络技术专业网络设备的安装与配置...
  11. 学习BMFONT的感想
  12. 我的软件测试修炼之道
  13. 完整的产品管理工作流程
  14. ChucK学习笔记(零)——前言
  15. Linux下parity联盟链的实现
  16. SEC主席Gary Gensler在被问及以太坊是否是证券时,选择了沉默
  17. 韩信点兵python源代码_Python实现“韩信点兵”
  18. WEB浏览器视频流播放方案
  19. 怎样读懂计算机论文算法,最新计算机算法分析论文参考文献 计算机算法分析专著类参考文献有哪些...
  20. 深度学习AI美颜系列----人像静态/动态贴纸特效算法实现

热门文章

  1. TypeScript Dom操作
  2. java使用中国网建sms发送短信
  3. 截取字符串的三个函数的简单使用
  4. 图片识别文字其实很简单,快来看看这几招
  5. 文本分析——分词技术
  6. LVS负载均衡服务器搭建
  7. 移动端真机调试:chrome://inspect/#devices打开inspect后出现空白页
  8. 接口自动化测试第三篇—postman断言
  9. 为什么要用反指纹浏览器?
  10. 估计理论(3):充分统计量的完备性