MySQL 5.6 的 GTIDs : 新复制协议和中断复制的新方法 【已翻译100%】

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

旧的协议往往简单直接即:首先从服务器上在一个特定的偏移量那里连接到一个给定的二进制日志文件,然后主服务器在从那里发送所有的事务。
新协议稍有不同:slave首先会发送它已经执行过的GTID的范围,然后master发送每一个丢失的事务. 它也确保了一个给定的GTID只可以在一个特定的slave中执行一次.

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

使用老协议的话,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? 就是因为新的复制协议!

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

让我们假设 sql_slave_skip_counter 可以用并且已经被用在S2上用于跳过trx2. 如果你吧S2设置成S1的一个slave将会发生什么呢?
两个服务器会互相交换被执行了GTID的范围,并且S1将会意识到其必须将trx2发送给S2. 然后会发生的事情有两种可能:

  • 如果 trx 2 仍然在S1的二进制日志中,它将会被发送给S2,而事务在也不会被跳过了.
  • 如果 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
时间: 2024-09-26 07:26:53

MySQL 5.6 的 GTIDs : 新复制协议和中断复制的新方法 【已翻译100%】的相关文章

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

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

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

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

复制策略与复制的方式 【已翻译100%】(1/2)

注意: 我写一些短篇的博客已经有些日子了. 我认为是时候改变下了.我不确定这篇博客会带来什么影响,但应该会是很大的影响.请让我知道你觉得更好的方法和理由.这个问题我已经想了几天了. 我试图想找出通用的复制解决方案能够应用到其他解决方案上去. 如果这个问题解决了,我们就能提供更多的功能组到更多的场景上. 但在之前,我们要谈谈怎么去实现复制, 哪些类型的复制. 我们假设有一个单独的数据库 (没分片,在不同的节点). 普通情况下, 将有下面的选项: 主/从 (Master/slaves) 主/次 (P

复制策略与复制的方式 【已翻译100%】(2/2)

服务器宕机意味着相关的日志变化部分会在尺度上增加,直到同伴节点再次运行起来,或者我们从复制目标中移除这个服务器条目. 到目前为止,这与你要组织 oplog 的方式非常相似.主要的不同是,组织需要记录的真实数据的方式.从 oplog 角度看,你准备向系统中写入发生的变化.并且,对之施行的唯一方式就是以它产生的相同顺序将其应用到 oplog 中.这会导致你只能一直拥有一个单主节点的系统.并且会引发在"大脑分裂"时数据丢失或需要手工合并的场景. 就多重可写组合而言,我们要保持足够的上下文(通

简短介绍 C# 6 的新特性 【已翻译100%】

几周前我在不同的地方读到了有关C#6的一些新特性.我就决定把它们都收集到一起,如果你还没有读过,就可以一次性把它们都过一遍.它们中的一些可能不会如预期那样神奇,但那也只是目前的更新. 你可以通过下载VS2014或者安装这里针对visual studio2013的Roslyn包来获取它们. 那么让我们看看吧: 1. $ sign 使用它的目的是简化基于索引的字符串,仅此而已.它不是像现在C#的一些动态特性,因为其内部使用了正规的索引功能. 为了编译理解请看下面的示例: var col = new

戏剧化的 LibreDWG —— 结束还是一个新的开始? 【已翻译100%】(2/2)

正如你所见,为FreeCAD和LibreCAD解决这个问题需要一个精心策划的运动.需要引入一个聪明的策略.并且在你达到一个可以对DWG文件进行高质量的读写的阶段之前,需要花费数年的时间.所以,我们在讨论的是一个关于无期限的耐心,同时要保持热情以及一些管理技巧的事. 我相信:一定有一个CAD的版本可以宣称"接受挑战"(译者注:语出<老爸老妈浪漫史>中巴尼的名言"Challenge accepted").说不定就是你?

为什么 Docker 在引领虚拟化和云计算的新浪潮 【已翻译100%】

又是一年的OSCON之际,今年的技术领域关注在人们热烈讨论的云基础建设.其中更有趣的是刚开始起步的Docker,这是一个超轻量化容器应用,充满潜力. 我对Docker的服务副总裁James Turnbull非常着迷,他将会在大会上带来一场Docker的速成班.除了探究Docker是什么之外,我们还将导论云,开源贡献和得到一份真正的工作. 您曾经出版过关于不同linux方面的著作.您开始是如何探索linux的呢?是什么让您对linux如此热衷呢? 我想我第一次接触linux是在Debian刚发布不

MySQL复制表与表数据到新表的方法

在 MySQL 中拷贝表,将 old_table 表拷贝为 new_table 表. 1. 不拷贝表数据,只拷贝结构.  代码如下 复制代码 CREATE TABLE new_table LIKE old_table2 . 通过 SELECT 查询来拷贝,new_table 表会丢失主键.索引等信息. 引用  代码如下 复制代码 CREATE TABLE new_table AS (     SELECT *     FROM old_table ) 3. 完全拷贝表  代码如下 复制代码 CR

Mysql复制表结构、表数据的方法_Mysql

本文给大家分享了好几种复制表结构.表数据的示例介绍,具体详情请看下文吧. 1.复制表结构及数据到新表 CREATE TABLE 新表SELECT * FROM 旧表 这种方法会将oldtable中所有的内容都拷贝过来,当然我们可以用delete from newtable;来删除. 不过这种方法的一个最不好的地方就是新表中没有了旧表的primary key.Extra(auto_increment)等属性.需要自己用"alter"添加,而且容易搞错. 2.只复制表结构到新表 CREAT