从mysql5.6开始引入全局事务标识符(GTID),即每个事务都有一个唯一的标识符。服务器上的每个事务都被分配一个唯一的事务标识符,这是一个64位非零的数值,根据事务提交的顺序分配。GTID的构成是由服务器的Uuid和事务的提交顺序两部分组成的。

复制事务的时候如果启用了全局事务标识符,不管事务被复制了多少次,事务的GTID保持不变。

注意的是:GTID被写入二进制日志,并且只会分配给已经写入二进制日志的事务。也就是说,如果关闭二进制日志,事务就不会分配GTID了。不管master还是slave都是这样。所以,如果想使用slave做故障转移,需要开启二进制日志,如果没有开启二进制日志,slave就不会记下事务的GTID。

首先来配置GTID复制

首先在从上清除当前的基于filename和pos的复制状态

mysql>stop slave;

Query OK,0 rows affected (0.01sec)

mysql> reset slave all;

Query OK,0 rows affected (0.02sec)

mysql>show slave status\G

Emptyset (0.00 sec)

主和从均开启GTID,设置GTID复制!因为之前两台服务器时主从复制,因此状态是一致的,因此不用再拷贝数据!

同步数据,设置复制账户都需要做!因为之前已经是主从,复制账户已经存在。

#主从均做如下设置log-bin=log_slave_updates

gtid-mode=onenforce-gtid-consistency

log-bin= #在基于filename和pos做主从时,没有开启备用服务器的二进制日志,做gtid复制时,需要开启二进制日志,原因后面会提到!

log_slave_updates: 这个是在基于filename和pos做主从时,用于做级联复制,在MySQL5.6中左gtid好像必须要开启这个参数,MySQL5.7不再强制必须!

gtid-mode=on: 开启gitd模式enforce-gtid-consistency:确保如果语句的记录与全局事务标识符不一致,语句就报错。

设置完之后重启服务器:

在从上做如下设置

mysql> change master to master_host="10.0.102.214", master_port=3306,master_user="repl",master_password="123456",master_auto_position=1;

Query OK,0 rows affected, 2 warnings (0.02sec)mysql> start slave;

Query OK, 0 rows affected (0.02 sec)

# master_auto_position使slave在连接master的时候,自动与master协商应该发送什么事务。

mysql> show slave status\G #与之前的复制相比,多了gitd的信息

*************************** 1. row ***************************

...........

Master_UUID: 4687e05d-f37f-11e8-8fc7-fa336351fc00 #master的UUID

Retrieved_Gtid_Set: 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-2

Executed_Gtid_Set: 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-2

Retrieved_Gtid_Set:这是从master获取而来的,存储在中继日志中的一组GTID.

Executed_Gtid_Set: 这是slave上执行,并且已经写入slave的二进制日志的一组GTID。

在从上查看二进制日志

mysql>show binlog events; #默认读取当前正在使用的二进制日志+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+

| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |

+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+

| test2-bin.000001 | 4 | Format_desc | 3 | 123 | Server ver: 5.7.22-log, Binlog ver: 4 |

| test2-bin.000001 | 123 | Previous_gtids | 3 | 154 | |

| test2-bin.000001 | 154 | Gtid | 5 | 219 | SET @@SESSION.GTID_NEXT= '4687e05d-f37f-11e8-8fc7-fa336351fc00:1' |

| test2-bin.000001 | 219 | Query | 5 | 348 | use `mytest`; create table tb2(id int auto_increment primary key) |

| test2-bin.000001 | 348 | Gtid | 5 | 413 | SET @@SESSION.GTID_NEXT= '4687e05d-f37f-11e8-8fc7-fa336351fc00:2' |

| test2-bin.000001 | 413 | Query | 5 | 476 | BEGIN |

| test2-bin.000001 | 476 | Table_map | 5 | 524 | table_id: 108 (mytest.tb2) |

| test2-bin.000001 | 524 | Write_rows | 5 | 564 | table_id: 108 flags: STMT_END_F |

| test2-bin.000001 | 564 | Xid | 5 | 595 | COMMIT /*xid=9*/ |

+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+

9 rows in set (0.01 sec)

#在二进制日志事件中可以看到Executed_Gtid_Set的gitd集合已经在slave上执行

gitd的复制是怎么找到二进制日志的复制点的?

在我们做filename和pos的复制时,手动指定了二进制日志的文件和位置,但是gtid怎么找到二进制日志的复制点的?从上面的二进制日志看到,event有一个Previous_gtids事件,这个事件指定的是前一个二进制日志事件的最后的gtid的数值,把当前从执行到的gtid与Previous_gtids比较,确定二进制日志的文件,然后再对比gtid的大小,确定日志的位置!因为当前是一个新开始的gitd复制,因此Previous_gtids值为0,我们强制轮换主的二进制,查看数据如下!

mysql>flush logs; #强制轮换二进制日志,会进行一次显式刷新磁盘

Query OK,0 rows affected (0.00sec)

mysql> show binlog events in "test3-bin.000006"; #因为之前的执行了两个事务,因此Previous_gtids指向为1-2.+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+

| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |

+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+

| test3-bin.000006 | 4 | Format_desc | 5 | 123 | Server ver: 5.7.22-log, Binlog ver: 4 |

| test3-bin.000006 | 123 | Previous_gtids | 5 | 194 | 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-2 |

| test3-bin.000006 | 194 | Gtid | 5 | 259 | SET @@SESSION.GTID_NEXT= '4687e05d-f37f-11e8-8fc7-fa336351fc00:3' |

| test3-bin.000006 | 259 | Query | 5 | 333 | BEGIN |

| test3-bin.000006 | 333 | Table_map | 5 | 381 | table_id: 109 (mytest.tb1) |

| test3-bin.000006 | 381 | Write_rows | 5 | 421 | table_id: 109 flags: STMT_END_F |

| test3-bin.000006 | 421 | Xid | 5 | 452 | COMMIT /*xid=40*/ |

| test3-bin.000006 | 452 | Gtid | 5 | 517 | SET @@SESSION.GTID_NEXT= '4687e05d-f37f-11e8-8fc7-fa336351fc00:4' |

我们知道GTID是由服务器的UUID+事务的执行顺序组成的,服务器的UUID存在于datadir指定目录下面:

mysql> show variables like"datadir";+---------------+--------------+

| Variable_name | Value |

+---------------+--------------+

| datadir | /data/mysql/ |

+---------------+--------------+

1 row in set (0.00sec)

mysql> system cat /data/mysql/auto.cnf; #服务器的UUID[auto]server-uuid=4687e05d-f37f-11e8-8fc7-fa336351fc00

上面我们搭建了一个简易的GITD复制,那么GTID是怎么复制的,GTID的复制原理是什么?

master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。

slave端的i/o线程将变更的binlog,写入到本地的relay log中。

sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。【对比本地的binlog中是否有记录,因此slave需要开通二进制日志】

如果有记录,说明该GTID的事务已经执行,slave会忽略。

如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。

查看当前master和从的二进制日志点和gtid值!

##在master上

mysql>show master status;+------------------+----------+--------------+------------------+------------------------------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+------------------------------------------+

| test3-bin.000006 | 1226 | | | 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-6 |

+------------------+----------+--------------+------------------+------------------------------------------+

1 row in set (0.00sec)

mysql>#在从上执行

mysql>show master status;+------------------+----------+--------------+------------------+------------------------------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+------------------------------------------+

| test2-bin.000002 | 194 | | | 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-6 |

+------------------+----------+--------------+------------------+------------------------------------------+

1 row in set (0.00 sec)

#可以看到日志名称不一样,日志的pos不一样,但是gtid却是一样的

测试在从上插入一条数据:

mysql> insert into tb1 select null; #插入的是自增主键的数值

Query OK,1 row affected (0.01sec)

Records:1 Duplicates: 0 Warnings: 0#查看二进制日志中的事件,是在begin开始一个事务之前,写入了GTID的数值| test3-bin.000006 | 1226 | Gtid | 5 | 1291 | SET @@SESSION.GTID_NEXT= '4687e05d-f37f-11e8-8fc7-fa336351fc00:7' |

| test3-bin.000006 | 1291 | Query | 5 | 1365 | BEGIN |

| test3-bin.000006 | 1365 | Table_map | 5 | 1413 | table_id: 109 (mytest.tb1) |

| test3-bin.000006 | 1413 | Write_rows | 5 | 1453 | table_id: 109 flags: STMT_END_F |

| test3-bin.000006 | 1453 | Xid | 5 | 1484 | COMMIT /*xid=67*/

mysql> show variables like "binlog_format"; #日志格式是row

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW  |

+---------------+-------+

1 row in set (0.00 sec) |

在从上查看二进制日志

#前面执行了flush logs命令!

mysql> show binlog events in "test2-bin.000002";+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+

| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |

+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+

| test2-bin.000002 | 4 | Format_desc | 3 | 123 | Server ver: 5.7.22-log, Binlog ver: 4 |

| test2-bin.000002 | 123 | Previous_gtids | 3 | 194 | 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-6 |

| test2-bin.000002 | 194 | Gtid | 5 | 259 | SET @@SESSION.GTID_NEXT= '4687e05d-f37f-11e8-8fc7-fa336351fc00:7' |

| test2-bin.000002 | 259 | Query | 5 | 322 | BEGIN |

| test2-bin.000002 | 322 | Table_map | 5 | 370 | table_id: 110 (mytest.tb1) |

| test2-bin.000002 | 370 | Write_rows | 5 | 410 | table_id: 110 flags: STMT_END_F |

| test2-bin.000002 | 410 | Xid | 5 | 441 | COMMIT /*xid=40*/ |

+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+

7 rows in set (0.00 sec)

使用GTID做故障转移

#主从上都有一张这样的表,数据是一样的

mysql> desctb2;+-------+---------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+---------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

+-------+---------+------+-----+---------+----------------+

1 row in set (0.00sec)

#现在在从从上插入一条数据

mysql> insert into tb2 select 4;

Query OK,1 row affected (0.01sec)

Records:1 Duplicates: 0 Warnings: 0#在主上也插入一条数据

mysql> insert into tb2 select 4;

Query OK,1 row affected (0.01sec)

Records:1 Duplicates: 0 Warnings: 0

mysql>show slave status\G*************************** 1. row ***************************Slave_IO_State: Waitingfor master tosend event

Master_Host:10.0.102.214Master_User: repl

Master_Port:3306Connect_Retry:60Master_Log_File: test3-bin.000007Read_Master_Log_Pos:452Relay_Log_File: test2-relay-bin.000007Relay_Log_Pos:407Relay_Master_Log_File: test3-bin.000007Slave_IO_Running: Yes

Slave_SQL_Running: No

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno:1062Last_Error: Coordinator stopped because there were error(s)in the worker(s). The most recent failure being: Worker 1 failed executing transaction '4687e05d-f37f-11e8-8fc7-fa336351fc00:8' at master log test3-bin.000007, end_log_pos 421. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.

Skip_Counter:0Exec_Master_Log_Pos:194Relay_Log_Space:959Until_Condition: None

Until_Log_File:

Until_Log_Pos:0Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master:NULLMaster_SSL_Verify_Server_Cert: No

Last_IO_Errno:0Last_IO_Error:

Last_SQL_Errno:1062Last_SQL_Error: Coordinator stopped because there were error(s)in the worker(s). The most recent failure being: Worker 1 failed executing transaction '4687e05d-f37f-11e8-8fc7-fa336351fc00:8' at master log test3-bin.000007, end_log_pos 421. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.

Replicate_Ignore_Server_Ids:

Master_Server_Id:5Master_UUID: 4687e05d-f37f-11e8-8fc7-fa336351fc00

Master_Info_File:/data/mysql/master.info

SQL_Delay:0SQL_Remaining_Delay:NULLSlave_SQL_Running_State:

Master_Retry_Count:86400Master_Bind:

Last_IO_Error_Timestamp:

Last_SQL_Error_Timestamp:181203 10:01:08Master_SSL_Crl:

Master_SSL_Crlpath:

Retrieved_Gtid_Set: 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-8Executed_Gtid_Set: 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-7,

e2bd1bae-f5cb-11e8-9c8c-fa1dae125200:1Auto_Position:1Replicate_Rewrite_DB:

Channel_Name:

Master_TLS_Version:1 row in set (0.00sec)

mysql>

show slave status查看复制状态

#错误说明

Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction '4687e05d-f37f-11e8-8fc7-fa336351fc00:8' at master log test3-bin.000007, end_log_pos 421. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.

Retrieved_Gtid_Set: 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-8 #从接收到的gtid, gtid为8的序列没有执行,Executed_Gtid_Set: 4687e05d-f37f-11e8-8fc7-fa336351fc00:1-7, #从执行的gtid,但是却执行了下面的一个gtid

e2bd1bae-f5cb-11e8-9c8c-fa1dae125200:1

我们知道是重复了数值,因此忽略掉这一条gitd的执行事务即可!

mysql> select @@gtid_next; #查看下一个要执行的事务,默认是自动选择+-------------+

| @@gtid_next |

+-------------+

| AUTOMATIC |

+-------------+

1 row in set (0.00sec)

mysql> set gtid_next="4687e05d-f37f-11e8-8fc7-fa336351fc00:8"; #我们把gtid_next设置为要忽略的哪一个事务的gtid

Query OK,0 rows affected (0.00sec)

mysql> begin; #执行一个空的事务

Query OK,0 rows affected (0.00sec)

mysql> commit;

Query OK,0 rows affected (0.01sec)

mysql> set gtid_next="AUTOMATIC"; #把gtid_next设置为原来的AUTOMATIC

Query OK,0 rows affected (0.00sec)

mysql>start slave sql_thread; #开启sql线程

Query OK,0 rows affected (0.02sec)

mysql> show slave status\G #查看复制已经恢复正常

mysql gtid 复制_MySQL的GTID复制相关推荐

  1. mysql 组复制和传统复制_MySQL的GTID复制与传统复制的相互切换

    1. GTID复制转换成传统复制 1.1 环境准备 类型 ip prot server-id master 192.168.56.100 3307 1003307 slave 192.168.56.2 ...

  2. mysql gtid 复制_MySQL 使用GTID进行复制

    1. GTID的格式和存储 GTID即全局事务ID(global transaction identifier),GTID实际上是由server_uuid:transaction_id组成的.其中se ...

  3. mysql半备份_MySQL半同步复制与增强半同步复制详解及安装

    一.基础 1.目前MySQL主要有三种复制方式 1)异步复制 2)半同步复制 3)增强半同步复制 推荐使用:对性能要求较高的推荐使用异步复制 ,如果运行的金融类业务推荐使用增强半同步复制,并使用ROW ...

  4. mysql 半同步复制_Mysql半同步复制原理及问题排查

    mysql半同步复制和异步复制的差别如上述架构图所示:在mysql异步复制的情况下,Mysql Master Server将自己的Binary Log通过复制线程传输出去以后,Mysql Master ...

  5. mysql半复制_mysql半同步复制

    从MySQL5.5开始,MySQL以插件的形式支持半同步复制.如何理解半同步呢?首先我们来看看异步,全同步的概念 异步复制(Asynchronous replication) MySQL默认的复制即是 ...

  6. mysql多源gtid复制_mysql的GTID复制和多源复制

    配置基于GTID的复制 -------------------------------------------- 在参数文件/etc/my.cnf增加下面内容: 主库 master_info_repo ...

  7. list存入mysql乱序_MySQL案例-并行复制乱序提交引起的同步异常

    现象描述 Slave在开启并行复制后, 默认会乱序提交事务, 可能会引起同步中断; Slave端表现为同步的SQL线程抛出异常, 为主键重复, 修改的数据行不存在等; GTID信息类似于: 9a2a5 ...

  8. mysql 备份表_MySQL中表的复制以及大型数据表的备份教程

    表复制mysql拷贝表操作我们会常常用到,下面就为您详细介绍几种mysql拷贝表的方式,希望对您学习mysql拷贝表方面能够有所帮助. 假如我们有以下这样一个表: id username passwo ...

  9. MySQL多元复制_MySQL多源复制解决方案

    MySQL轻松实现一主多从,但要将多个实例的数据复制到一个实例中就比较难啦,幸好在MariaDB中已经实现multi-master replication 功能: 在介绍MariaDB的功能前,我们先 ...

最新文章

  1. 设计模式(35)-----设计模式阶段性总结(一句话概括一个模式)
  2. 【Python之旅】第五篇(三):Python Socket多线程并发
  3. 三套JSP源代码的安装部署过程和遇到的问题图解
  4. 推荐一款代码神器,代码量至少省一半!
  5. 经典C语言程序100例之六六
  6. .NET Core Tools 1.0 版本
  7. 上传 jar 包到 nexus3、上传本地 jar 包到 maven 私服
  8. github推荐好玩项目
  9. typescript设置默认值_TypeScript输入参数的默认值一例,以及对应生成的JavaScript代码分析...
  10. python邮件发送_Python实现邮件发送
  11. 海南计算机考研和培训哪个比较好,海南考研集训营前十排名
  12. AttributeError: module 'tensorflow' has no attribute 'python'
  13. 在idea配置jetty和创建(包、文件)javaWeb以及Servlet简单实现
  14. 喜马拉雅音频下载+x2m文件转换
  15. 软件开发技术文档编写规范
  16. 计算机网络 中国大学MOOC 哈尔滨工业大学 习题答案
  17. linux网络设备驱动之dm9000驱动源码框架解析
  18. 防火墙开放21端口linux,linux防火墙开放80,3306,21,443端口
  19. android平板电脑手写笔应用,四款最佳手写笔平板推荐
  20. Python 自动化教程(5) : 自动生成Word文件

热门文章

  1. C++(一)——HelloWorld
  2. Linux - SquashFS文件系统
  3. 微伴助手与企鲸客scrm的功能差别是什么
  4. 华宇物流 十年磨一剑
  5. Hive 的 SerDe 是什么?
  6. JavaScript算法题整理
  7. 【Mysql系列】工作常用sql集锦(持续更新)
  8. 碎碎念No.05 走丢的侠客|CSDN创作打卡
  9. 数论基础之中国剩余定理(附证明)
  10. python 直接退出程序_python 退出程序 Python程序运行后直接退出