在MySQL中使用GTIDs复制协议和中断协议的教程

 更新时间:2015年04月22日 10:25:36   投稿:goldensun  
这篇文章主要介绍了在MySQL中使用GTIDs复制协议和中断协议的教程,主要用于多个服务器之间的通信,需要的朋友可以参考下

 MySQL5.6有很多新的特性,其中很多人都感兴趣的一条就是全局事务序号功能(GTIDs)。而大家都对这一特性很感兴趣的原因也很好理解,即:本来重新连接从服务器和一个新的主服务器一直是件很麻烦的事,然而在启用GTIDs功能之后就变得简单易行。可是,GTIDs的使用不单单是用单独的标识符替换旧的二进制日志文件/位置,它也采用了新的复制协议。假如你还不太明白这些,那你可以在这篇文章里学点什么。
复制协议:新的 VS 旧的

旧的协议往往简单直接即:首先从服务器上在一个特定的偏移量那里连接到一个给定的二进制日志文件,然后主服务器在从那里发送所有的事务。


新协议稍有不同:slave首先会发送它已经执行过的GTID的范围,然后master发送每一个丢失的事务. 它也确保了一个给定的GTID只可以在一个特定的slave中执行一次.

实践中,这会改变任何东西吗? 使得,它会改变很多东西. 想象一下下面的场景: 你想要从trx 4开始复制,但是trx2在slave上因为某种缘故丢失了. 

2015422100429095.png (529×265)

 使用老协议的话,trx 2再也不会被执行一次,而使用新协议,它就会被自动的再执行一次.

下面是两个你可以在实践中看到新协议的通用场景.

跳过事务

众所周知老的 SET GLOBAL sql_slave_skip_counter = N 在你想要跳过一个事务时不再提供支持,而GTID就可以被启用了. 换用 GTID XXX:N 来跳过事务, 你须得 注入一个空的事务:
 

mysql> SET gtid_next = 'XXX:N';
mysql> BEGIN; COMMIT;
mysql> SET gtid_next = 'AUTOMATIC';

为什么我们不能使用 sql_slave_skip_counter? 就是因为新的复制协议!

想象一下我们拥有如下图所示的三台服务器: 

2015422100610975.png (529×416)

 让我们假设 sql_slave_skip_counter 可以用并且已经被用在S2上用于跳过trx2. 如果你吧S2设置成S1的一个slave将会发生什么呢?


两个服务器会互相交换被执行了GTID的范围,并且S1将会意识到其必须将trx2发送给S2. 然后会发生的事情有两种可能:

  1.     如果 trx 2 仍然在S1的二进制日志中,它将会被发送给S2,而事务在也不会被跳过了.
  2.     如果 trx 2 不再存在于S1的二进制日志中,你将会得到一个复制错误.

很明显这不安全,这就是为什么 sql_slave_skip_counter 在使用GTID时是不能用的. 要想跳过一个事务,唯一安全的选择就是去执行一个虚拟的事务,而不是一个真实的事务.
 
错误的事务

如果你在一个slave上本地执行了一个事务 (在MySQL文档中被称为错误事务), 如果你被这个事务推送到新的master上时会发生什么呢?

使用老协议,基本上没啥事(准确点说,新的master和其slave之间的数据将会出现不一致,但那在稍后就可能会被修复).

使用新协议,错误的事务将会被识别成为在每个地方都丢失了,并且将会自动在容错备份上被执行,这样就将会导致打断复制的隐患.

比方说,你拥有一个master(M)和两个slave (S1 和 S2). 这里有两种将slave重连到新的master将会发生(带有不同复制错误的)失败的场景:

# 场景 1
 

# S1
mysql> CREATE DATABASE mydb;
# M
mysql> CREATE DATABASE IF NOT EXISTS mydb;
# Thanks to 'IF NOT EXITS', replication doesn't break on S1. Now move S2 to S1:
# S2
mysql> STOP SLAVE; CHANGE MASTER TO MASTER_HOST='S1'; START SLAVE;
# This creates a conflict with existing data!
mysql> SHOW SLAVE STATUS\G
[...]
Last_SQL_Errno: 1007
        Last_SQL_Error: Error 'Can't create database 'mydb'; database exists' on query. Default database: 'mydb'. Query: 'CREATE DATABASE mydb'
[...]

# 场景 2
 

# S1
mysql> CREATE DATABASE mydb;
# Now, we'll remove this transaction from the binary logs
# S1
mysql> FLUSH LOGS;
mysql> PURGE BINARY LOGS TO 'mysql-bin.000008';
# M
mysql> CREATE DATABASE IF NOT EXISTS mydb;
# S2
mysql> STOP SLAVE; CHANGE MASTER TO MASTER_HOST='S1'; START SLAVE;
# The missing transaction is no longer available in the master's binary logs!
mysql> SHOW SLAVE STATUS\G
[...]
Last_IO_Errno: 1236
        Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
[...]

你可以这样理解,错误的事务应该借助基于GTID的服务得以避免. 如果你需要运行一个本地事务,最好的选择是针对那条特定的语句禁用二进制日志:
 

mysql> SET SQL_LOG_BIN = 0;
mysql> # Run local transaction

结论

GTIDs在让我们方便重新和其他服务器连接副本方面是个不小的进步。然而同样的在运维方面我们也因此面临新的困难和挑战。假如你打算开始使用GTIDs,那么你就得确实理解新的复制协议,否则你就会以一种想不到的方式结束复制过程。

相关文章

  • MySQL七大JOIN的具体使用

    MySQL七大JOIN的具体使用

    本文主要介绍了MySQL七大JOIN的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • MySQL交换分区的实例详解

    MySQL交换分区的实例详解

    这篇文章主要介绍了MySQL交换分区的实例详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • mysql实现向某个字段前或后添加字符

    mysql实现向某个字段前或后添加字符

    这篇文章主要介绍了mysql实现向某个字段前或后添加字符,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • MySQL因配置过大内存导致无法启动的解决方法

    MySQL因配置过大内存导致无法启动的解决方法

    这篇文章主要给大家介绍了关于MySQL因配置过大内存导致无法启动的解决方法,文中给出了详细的解决示例代码,对遇到这个问题的朋友们具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-06-06
  • MySQL控制流函数(-if ,elseif,else,case...when)

    MySQL控制流函数(-if ,elseif,else,case...when)

    这篇文章主要介绍了MySQL控制流函数(-if ,elseif,else,case...when),文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-07-07
  • MySQL关闭SSL的简单方法

    MySQL关闭SSL的简单方法

    这篇文章主要介绍了MySQL关闭SSL的简单方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • mysql创建表分区的实现示例

    mysql创建表分区的实现示例

    表分区是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分,本文主要介绍了mysql创建表分区的实现示例,感兴趣的可以了解一下
    2024-01-01
  • mysql中workbench实例详解

    mysql中workbench实例详解

    在本篇文章里小编给大家分享了关于mysql中workbench实例内容,有兴趣的朋友们学习下。
    2019-01-01
  • mysql递归函数with recursive的用法举例

    mysql递归函数with recursive的用法举例

    在实际开发的过程中,我们会遇到一些数据是层级关系的、要展示数据子父级关系的时候,下面这篇文章主要给大家介绍了关于mysql递归函数with recursive的用法举例,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • MySQL8.0实现窗口函数计算同比环比

    MySQL8.0实现窗口函数计算同比环比

    本文主要介绍了MySQL8.0实现窗口函数计算同比环比,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06

最新评论