mysq5.5和mysq5.6事务区别

先说一下mysql5.5跳过事务方法

GTID跳过有两种方法,一种是普通的跳过一个事务的方法,另外一个是在基于主库搭建新的slave的时候.
一、普通跳过一个事务的方法。
通过show slave status\G找到冲突的GTID号.
然后执行
SET gtid_next = ‘冲突的GTID号’;
BEGIN;COMMIT;
SET gtid_next = ‘AUTOMATIC’;
START SLAVE;
这就可以跳过一个事务了,原理在于通过执行一个空事务代替master传递过来的冲突事务.

二、通过备份的dump.sql文件搭建新的slave.
开启gtid以后,使用mysqldump备份,一般系统会要求你使用–all-databases参数,避免主库和从库有部分数据不一致。
备份以后,dump.sql里面会有这样一条语句.

SET @@GLOBAL.GTID_PURGED='0140505e-4230-11e4-b7c9-000c29da163d:1-8,dd079e18-4244-11e4-b851-000c29da163e:1-2';

这个就是当前主库已经执行过的GTID,也就是dump.sql里面的数据已经包含的GTID,对于这些GTID,slave是不用执行了,所以我们需要设置slave从这些
GTID以后开始复制.方法就是上面这条sql.
将dump.sql直接导入到slave以后.就可以直接change master了.

如果你是想通过这个方法跳过某个或者某些GTID,那么有点不同了.
set @@GLOBAL.GTID_PURGED是有要求的,也就是GTID_PURGED必须为空才可以设置,如何把GTID_PURGED清空呢.也就是需要执行

(root:hostname)[test]> show global variables like '%gtid%';
+--------------------------+-------------------------------------------------------------------------------------------------------------------------------+
| Variable_name            | Value                                                                                                                         |
+--------------------------+-------------------------------------------------------------------------------------------------------------------------------+
| enforce_gtid_consistency | ON                                                                                                                            |
| gtid_executed            | 0140505e-4230-11e4-b7c9-000c29da163d:1-25,
dd079e18-4244-11e4-b851-000c29da163e:1-2,
dda2f003-4244-11e4-b851-000c29da163f:1-3 |
| gtid_mode                | ON                                                                                                                            |
| gtid_owned               |                                                                                                                               |
| gtid_purged              | 0140505e-4230-11e4-b7c9-000c29da163d:1-8,
dd079e18-4244-11e4-b851-000c29da163e:1-2                                            |
+--------------------------+-------------------------------------------------------------------------------------------------------------------------------+
5 rows in set (0.00 sec)

(root:hostname)[test]> reset master;
Query OK, 0 rows affected (0.02 sec)

(root:hostname)[test]> show global variables like '%gtid%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| enforce_gtid_consistency | ON    |
| gtid_executed            |       |
| gtid_mode                | ON    |
| gtid_owned               |       |
| gtid_purged              |       |
+--------------------------+-------+
5 rows in set (0.00 sec)
(root:hostname)[test]> stop slave;  //清掉SLAVE信息.
(root:hostname)[test]> reset slave all;
然后设置gtid_purged,这个ID就是你要跳过过的GTID,注意这里GTID还要包含gtid_executed里面其他UUID的GTID(本机的可以不再设置了)。

(root:hostname)[test]> set @@global.gtid_purged='0140505e-4230-11e4-b7c9-000c29da163d:1-25,dd079e18-4244-11e4-b851-000c29da163e:1-2';
Query OK, 0 rows affected (0.03 sec)

(root:hostname)[test]> CHANGE MASTER TO MASTER_HOST='192.168.153.150', MASTER_PORT=3306, MASTER_USER='slave',MASTER_PASSWORD='slave', master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.20 sec)

(root:hostname)[test]> start slave;
Query OK, 0 rows affected, 1 warning (0.03 sec)
CHANGE MASTER TO MASTER_HOST='192.168.1.136', MASTER_PORT=3306, MASTER_USER='dbadmin',MASTER_PASSWORD='123456', master_auto_position=1;

mysql 5.6 gids新特性


GTIDs是mysql-5.6用户比较感兴趣的新特性之一,感兴趣的原因在于,以前slave连接到master是一件有挑战的事情,但是启用了GTIDs以后,这件事情变得极其简单。

然而,使用GTIDs不是简单的使用唯一标识替换原来的binlog和偏移量,他是一种全新的复制协议,如果你没有认识到这一点,那么你很容易受伤.

复制协议对比:OLD VS NEW
老的协议相当于直接转发:slave连接一个指定的binary log文件和offset,master从这里开始发送所有的transactions。
新的协议有些不同:slave开始发送自己执行过的GTIDs给master,然后master发送所有slave丢失的transaction,并且保证所有一个事务对应的GTIDs只会发送给指定的slave一次.

在实际使用中,会有哪个不同呢?在下面这种情况,master执行了trx1,trx2,trx3,trx4这几个事务,slave执行了trx1,trx3这两个事务,某些原因导致了slave上trx2事务丢失.

在老的复制协议中,trx2将会丢失,而新的复制协议中,trx2将会被自动的执行。

关于skipping transactions
你需要知道以前的 set global sql_slave_skip_counter = N 在GTIDs协议中不在支持,代替方法是如果你要跳过GTID xxx:N,你需要插入一个空的transaction:

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

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

在一个环境中,有master,slave1,slave2.当slave2跳过了某一个trx以后.将slave2的master切换到slave1,这个时候将会出现两种情况

1、如果slave2丢失的trx存在于slave1的binlog中,那么slave2将再次执行这个trx,导致跳过sql_slave_skip_counters失效

2、如果slave2丢失的trx不存在于slave1的binlog中,那么你会得到一个复制错误。

使用sql_slave_skip_counter是非常不安全的,这也是GTIDs不支持它的原因.唯一安全的方法跳过一个transaction,就是执行一个伪造的transaction代替真实的transaction.

Errant transactions
如果你在slave本地执行的transaction,被称为Errant transactions。如果你把此slave提升为master,会发生什么?

如果使用的老的复制协议,基本上不会发生任何事情(正确的说,主从数据会存在不一致的问题.但是稍后可以修复).

如果使用新的复制协议,Errant transaction将会在failover的时候,定义为所有slave都缺失这个transaction,然后自动的让每个slave都执行.这可能会导致复制失败。

场景一

# 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'
场景二:

# 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.'

你需要知道,如果使用GTIDs协议复制,需要尽量避免Errant transactions.如果你需要本地运行一个事务,可以使用关闭binlog的方式。使用这种方法也是非常危险的,一定要主要关闭的是session的,并且操作完,一定要打开。

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

总结:
GTIDs能够让slave自动的从新连接到其他服务器复制,是mysql复制的一个伟大进步,但是同时也带来了新的维护挑战,如果你计划使用GTIDs,你需要正确的理解GTIDs协议,不然的话你可能会遇见新的或者其他意向不到的问题导致复制失败。

你可能感兴趣的:(mysql,事务)