什么是GTID

什么是GTID呢, 简而言之,就是全局事务ID(global transaction identifier ),最初由google实现,官方MySQL在5.6才加入该功能。
GTID是事务提交时创建分配的唯一标识符,所有事务均与GTID一一映射。

GTID的格式类似于:
5882bfb0-c936-11e4-a843-000c292dc103:1
这个字符串,用“:”分开,前面表示这个服务器的server_uuid,这是一个128位的随机字符串,在第一次启动时生成(函数generate_server_uuid),对应的variables是只读变量server_uuid。 它能以极高的概率保证全局唯一性,并存到文件
DATADIR/auto.cnf中。因此要注意保护这个文件不要被删除或修改。

第二部分是一个自增的事务ID号,事务id号+server_uuid来唯一标示一个事务。

一个GTID的生命周期包括:
1.事务在主库上执行并提交
给事务分配一个gtid(由主库的uuid和该服务器上未使用的最小事务序列号),该GTID被写入到binlog中。
2.备库读取relaylog中的gtid,并设置session级别的gtid_next的值,以告诉备库下一个事务必须使用这个值
3.备库检查该gtid是否已经被其使用并记录到他自己的binlog中。slave需要担保之前的事务没有使用这个gtid,也要担保此时已读取gtid,但未提交的事务也不能使用这个gtid.
4.由于gtid_next非空,slave不会去生成一个新的gtid,而是使用从主库获得的gtid。这可以保证在一个复制拓扑中的同一个事务gtid不变。
由于GTID在全局的唯一性,通过GTID,我们可以在自动切换时对一些复杂的复制拓扑很方便的提升新主库及新备库,例如通过指向特定的GTID来确定新备库复制坐标。

  1. mysql> show global variables like '%gtid%';
  2. +--------------------------+------------------------------------------+
  3. | Variable_name | Value |
  4. +--------------------------+------------------------------------------+
  5. | enforce_gtid_consistency | ON |
  6. | gtid_executed | 5882bfb0-c936-11e4-a843-000c292dc103:1-6 |
  7. | gtid_mode | ON |
  8. | gtid_owned | |
  9. | gtid_purged | |
  10. +--------------------------+------------------------------------------+
  11. 5 rows in set (0.00 sec)
  12.  
  13. mysql> show global variables like '%uuid%';
  14. +---------------+--------------------------------------+
  15. | Variable_name | Value |
  16. +---------------+--------------------------------------+
  17. | server_uuid | 5882bfb0-c936-11e4-a843-000c292dc103 |
  18. +---------------+--------------------------------------+
  19. 1 row in set (0.00 sec)
  20.  
  21. shell> cat auto.cnf
  22. [auto]
  23. server-uuid=5882bfb0-c936-11e4-a843-000c292dc103

设置GTID复制

  1. 同步主从数据

    1. mysql> SET @@global.read_only = ON;
    2. Query OK, 0 rows affected (0.01 sec)
  2. 停止所有数据库
    1. shell> mysqladmin -u root -p shutdown
  3. 设置开发GTID模式并启动所有数据库

    1. shell> vi my.cnf 添加如下内容
    2. ================================================================
    3. [mysqld]
    4. gtid_mode=ON
    5. log-slave-updates=ON
    6. enforce-gtid-consistency=ON #强制GTID的一致性
    7. ================================================================
  4. 从库指定主库

    1. mysql> CHANGE MASTER TO
    2. -> MASTER_HOST = host,
    3. -> MASTER_PORT = port,
    4. -> MASTER_USER = user,
    5. -> MASTER_PASSWORD = password,
    6. -> MASTER_AUTO_POSITION = 1;
    7.  
    8. mysql> START SLAVE;
    9. Query OK, 0 rows affected (0.04 sec)
  5. 禁止read-only模式

    1. mysql> SET @@global.read_only = OFF;
    2. Query OK, 0 rows affected (0.00 sec)

多线程复制基于库

MySQL 5.6之前的版本,同步复制是单线程的,队列的,只能一个一个执行,在5.6里,可以做到多个库之间的多线程复制,例如数据库里,存放着用户表,商品表,价格表,订单表,那么将每个业务表单独放在一个库里,这时就可以做到多线程复制,但一个库里的表,多线程复制是无效的。 注,每个数据库仅能使用一个线程,复制涉及到多个数据库时多线程复制才有意义

GTID复制的限制

GTID 模式实例和非GTID模式实例是不能进行复制的,要求非常严格,要么都是GTID,要么都不是
gtid_mode 是只读的,要改变状态必须1)关闭实例、2)修改配置文件、3) 重启实例

  • 更新非事务引擎表
    在同一事务中更新事务表与非事务表将导致多个GTIDs分配给同一事务
  1. mysql> cretea table tt (id int) engine=myisam;
  2. mysql> insert into tt values(1),(2);
  3. mysql> cretea table t (id int) engine=innodb;
  4. mysql> insert into t values(1),(2);
  5. mysql> set autocommit = 0
  6. mysql> begin
  7.  
  8. mysql> update t set id = 3 where id =2;
  9. Query OK, 1 row affected (0.00 sec)
  10. Rows matched: 1 Changed: 1 Warnings: 0
  11.  
  12. mysql> update tt set id = 3 where id =2;
  13. ERROR 1785 (HY000): When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, updates to non-transactional tables can
  14. only be done in either autocommitted statements or single-statement transactions, and never in the same
  15. statement as updates to transactional tables.
  • CREATE TABLE … SELECT statements
    不安全的基于语句复制,实际是两个独立的事件,一个用于建表,一个用于向新表插入源表数据。
  1. mysql> create table t engine=innodb as select * from tt;
  2. ERROR 1786 (HY000): CREATE TABLE ... SELECT is forbidden when @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1.
  • 临时表
    事务内部不能执行创建删除临时表语句,但可以在事务外执行,但必须设置set autocommit = 1
  1. mysql> create temporary table tttt(id int);
  2. ERROR 1787 (HY000): When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE TEMPORARY TABLE and
  3. DROP TEMPORARY TABLE can be executed in a non-transactional context only, and require that AUTOCOMMIT = 1.
  4. mysql> set autocommit = 1;
  5. Query OK, 0 rows affected (0.00 sec)
  6.  
  7. mysql> create temporary table tttt(id int);
  8. Query OK, 0 rows affected (0.04 sec)
  • 不执行不支持的语句
    启用--enforce-gtid-consistency选项启动GTID模式,上述不支持的语句将会返回错误。

运维操作

a. 忽略复制错误
当备库复制出错时,传统的跳过错误的方法是设置sql_slave_skip_counter,然后再START SLAVE。
但如果打开了GTID,就会设置失败:

  1. mysql> stop slave;
  2. Query OK, 0 rows affected (0.03 sec)
  3.  
  4. mysql> set global sql_slave_skip_counter = 1;
  5. ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON.
  6. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction

提示的错误信息告诉我们,可以通过生成一个空事务来跳过错误的事务。
我们手动产生一个备库复制错误:

  1. [slave]
  2. mysql> alter table t add primary key pk_id(id);
  3. Query OK, 2 rows affected (0.12 sec)
  4. Records: 2 Duplicates: 0 Warnings: 0
  5.  
  6. mysql> insert into t values(1);
  7. mysql> insert into t values(4);
  8. mysql> insert into t values(5);
  9.  
  10. mysql> show master status ;
  11. +-------------------+----------+--------------+------------------+-------------------------------------------+
  12. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
  13. +-------------------+----------+--------------+------------------+-------------------------------------------+
  14. | mysql-info.000004 | 914 | | | 5882bfb0-c936-11e4-a843-000c292dc103:1-17 |
  15. +-------------------+----------+--------------+------------------+-------------------------------------------+
  16. 1 row in set (0.00 sec)
  17.  
  18. mysql> show slave status \G
  19. *************************** 1. row ***************************
  20. ...
  21. Slave_IO_Running: Yes
  22. lave_SQL_Running: No
  23. Last_Errno: 1062
  24. Last_Error: Could not execute Write_rows event on table db_test.t; Duplicate entry '1' for key 'PRIMARY',
  25. Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-info.000004, end_log_pos 401
  26. Retrieved_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-15
  27. Executed_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-14,
  28. f1e6584a-c935-11e4-a840-000c29348dbe:1
  29. Auto_Position: 1
  30. 1 row in set (0.00 sec)
  31.  
  32. mysql> SET @@SESSION.GTID_NEXT= '5882bfb0-c936-11e4-a843-000c292dc103:15';
  33. Query OK, 0 rows affected (0.00 sec)
  34.  
  35. mysql> begin;
  36. Query OK, 0 rows affected (0.00 sec)
  37.  
  38. mysql> commit;
  39. Query OK, 0 rows affected (0.00 sec)
  40.  
  41. mysql> SET SESSION GTID_NEXT = AUTOMATIC;
  42.  
  43. mysql> start slave;
  44.  
  45. mysql> show slave status\G
  46. *************************** 1. row ***************************
  47. Slave_IO_Running: Yes
  48. Slave_SQL_Running: Yes
  49. Last_Errno: 0
  50. Retrieved_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-17
  51. Executed_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-17,
  52. f1e6584a-c935-11e4-a840-000c29348dbe:1
  53. Auto_Position: 1
  54. 1 row in set (0.00 sec)

再查看show slave status,就会发现错误事务已经被跳过了。这种方法的原理很简单,空事务产生的GTID加入到GTID_EXECUTED中,
这相当于告诉备库,这个GTID对应的事务已经执行了,此时主从数据不一致。

b.重指主库

使用change master to …. , MASTER_AUTO_POSITION=1;
注意在整个复制拓扑中,都需要打开gtid_mode

c.适当减小binlog文件的大小

如果开启GTID,理论上最好调小每个binlog文件的最大值,以缩小扫描文件的时间。
 
参考:http://mysqllover.com/?p=594    ##比较深入,源码级别
   http://www.iyunv.com/thread-22122-1-1.html
   http://blog.itpub.net/29733787/viewspace-1462550/

MySQL GTID复制的更多相关文章

  1. MySQL GTID复制Slave跳过错误事务Id以及复制排错问题总结

    GTID复制典型的复制错误有两种:1,数据对象级别的错误,包括主库上update的数据在从库上不存在,主从逐渐冲突,库表索引等对象的冲突等等,   如果是纯粹的跳过错误的话,这一类的错误需要跳过思路是 ...

  2. MYSQL GTID 复制

    MySQL5.7以后都基本用GTID方式复制了,相对于binlog和position号方式,在failover时候减少很多人工切换操作 GTID,global transaction identiti ...

  3. MySQL GTID复制错误处理之跳过错误

    某Slave报错信息: mysql> show slave status\G; mysql> show slave status\G; ************************** ...

  4. 【3.2】【mysql基本实验】mysql GTID复制(基于空数据的配置)

    概述:本质上和传统异步复制没什么区别,就是加了GTID参数. 且可以用传统的方式来配置主从,也可以用GTID的方式来自动配置主从. 这里使用GTID的方式来自动适配主从. 需要mysql5.6.5以上 ...

  5. (5.8)mysql高可用系列——MySQL中的GTID复制(实践篇)

    一.基于GTID的异步复制(一主一从)无数据/少数据搭建 二.基于GTID的无损半同步复制(一主一从)(mysql5.7)基于大数据量的初始化 正文: [0]概念 [0.5]GTID 复制(mysql ...

  6. 与MySQL传统复制相比,GTID有哪些独特的复制姿势?

    与MySQL传统复制相比,GTID有哪些独特的复制姿势? http://mp.weixin.qq.com/s/IF1Pld-wGW0q2NiBjMXwfg 陈华军,苏宁云商IT总部资深技术经理,从事数 ...

  7. mysql之 MySQL 主从基于 GTID 复制原理概述

    一. 什么是GTID ( Global transaction identifiers ):MySQL-5.6.2开始支持,MySQL-5.6.10后完善,GTID 分成两部分,一部分是服务的UUid ...

  8. mysql之 mysql 5.6不停机主从搭建(一主一从基于GTID复制)

    环境说明:版本 version 5.6.25-log 主库ip: 10.219.24.25从库ip:10.219.24.22os 版本: centos 6.7已安装热备软件:xtrabackup 防火 ...

  9. MySQL的GTID复制与传统复制的相互转换

    主库:192.168.225.128:3307从库1:192.168.225.129:3307 Gtid作为5.6版本以来的杀手级特性,却因为不支持拓扑结构内开关而饱受诟病.如果你需要从未开启GTID ...

随机推荐

  1. Hashed Indexes Geospatial Index

    Indexes — MongoDB Manual https://docs.mongodb.com/manual/indexes/ 地理索引 哈希索引

  2. hibernate面试点

    1.谈谈你对hibernate的认识和理解 01.全自动的ORM框架 02.子项目 03.面向对象的思想来解决操作数据库 01.hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JD ...

  3. SpringMVC 学习笔记(四) 处理模型数据

    Spring MVC 提供了下面几种途径输出模型数据: – ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体就可以通过该对象加入模型数据 – Map及Model: ...

  4. super究竟是个啥?

    引子: 一直以为oc的super跟java中的super是一回事,没有去深究它的本质,直到工作的时候遇到一个并不能按我的理解能解释的情况. 剖析: 在此之前先看一段代码: 有两个类 SuperClas ...

  5. css3中我们不知道的一些属性

    1.图片作为边框:border-image; 2.圆角问题:border-radius:上.下.左.右: 3.字体的阴影与自动换行: 阴影: h1 {text-shadow: 5px 5px 5px ...

  6. COGS-2049 疯狂动物城

    Description 你意外来到了一个未知的星球, 这里是一个动物乌托邦, 生活着一群拥有非凡智力的动物. 你遇到了一个叫做尼克的狐狸, 他准备给他的 GF 过生日 . 他将制作一个巨大的多层蛋糕, ...

  7. sid, pid, gid

    (一) 参考 :https://unix.stackexchange.com/questions/18166/what-are-session-leaders-in-ps 命令: ps xao pid ...

  8. CoderForces343D:Water Tree(dfs序+线段树&&特殊处理)

    Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a res ...

  9. java web项目的目录结构

  10. 整合ssh的时候出现空指针java.lang.NullPointerException

    转自:https://blog.csdn.net/koudailidexiaolong/article/details/9468857 HTTP Status 500 - type Exception ...