MySQL的GTID

GTID

@(MySQL)[集群, 复制]

一 、 GTID是什么?

GTID是全局事务标记符,有了这个标记,那么在同一个事务,不可能在一个节点中出现多次.每一个事务在集群中具有了一个唯一性。在原先的环境中,最重要的就是filenameposition。这样有可能出现不一样的情况,而且大多数都是不一样的情况,那么change master的位置是很难确定。
- 根据GTID可以快速知道事务最初是在哪个实例上提交的。
- 根据GTID搭建主从复制更加简单,确保每个事务只会被执行一次
- 基于GTID复制,可以更方便实现Failover。
每次提交一个事务,当前线程都会拿到一个唯一标识符,这个标识符不仅对源Master是唯一,对每个复制环境中的所有MySQL实例都是唯一的。

GTID= source_id:sequence_id

source_id默认是由源服务器的唯一标识,默认由:server_uuid标识。sequence_id在事务提交时,由系统顺序分配的一个序列号。相同的source_id 值的事务对应sequence_id在Binlog文件中是递增的而且是连续有序的。

mysql> show master status;
+------------+----------+--------------+------------------+----------------------------------------+
| File       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------+----------+--------------+------------------+----------------------------------------+
| bin.000006 |      194 |              |                  | 25179ea3-d66e-11e7-afa0-00163e2e10b8:1 |
+------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

GTID是一组全局事务标识符

1.1 GTID的生命周期

Alt text
1. Master产生GTID:在Master端产生一个GTID的信息,并保存到binlog中。
2. 发送Binlog信息到从库上,将binlog信息发送到SLAVE所在的服务器上。将SLAVE中的gtid_next的值设置为GTID的值。
3. SLAVE执行GTID。SLAVE首先验证是否在自己的二进制日志中使用了这个GTID号
4. SLAVE不生成GTID。由于GTID不为空,SLAVE不会尝试为该事务生成新的GTID,而是从gtid_next 中读取GTID值,写入二进制日志中,来标识一个事务的GTID的值。

1.2 使用GTID搭建主从

1.2 .1 配置GTID主从的参数
  • server_id: 设置MySQL实例的server_id,每个server_id不能一样
  • gtid_mode=ON: MySQL实例开启GTID模式
  • enforce_gtid_consitency=ON:使用GTID模式复制时,需要开启参数,用来保证数据的一致性。
  • log-bin: MySQL必须要开启binlog
  • log-slave-updates=1:决定SLAVE从Master接收到更新且执行是否记录到SLAVE的binlog中
  • binlog_format=ROW:
  • skip-slave-start=1: 当SLAVE数据库启动的时候,SLAVE不会启动复制
1.2.2 开启GTID

在一个新键的数据库上面的操作步骤:
- 关闭MASTER的写入,保证SLAVE与MASTER的数据是同步的
- 在SLAVE上配置参数skip-slave-start=1,避免SLAVE启动后,继续使用传统的复制模式
- 修改配置,开启GTID模式
- 重启所有的MySQL数据库

1.2.3 搭建主从

基于GTID的主从搭建的过程:
- 如果MASTER是新搭建的而且没有数据,可以直接利用CHANGE MASTER语句进行搭建。
- 如果MASTER是刚运行没有多久,所有的binlog都保存完整,也可以使用上面的方式直接进行change master。缺点:如果binlog过多,那么SLAVE同步的时间就会很长
- 如果MASTER具有大量的数据,原先的binlog可能已经被删除了,无法从头开始获取所有的GTID的信息,那么需要从MASTER上获取数据和GTID的范围。通过在SLAVE上设置选项(gtid_purged)的方式来跳过这些GTID。
- 利用备份的方式,可以获取MASTER的数据和GTID的范围,包含了gtid_purged=‘uuid:interval’,使用innobackupex备份会将信息保留在xtrabackup_binlog_info文件中。
- 利用备份的数据,搭建SLAVE实例
- 启动SLAVE实例,并且设置gtid_purged的值,跳过这段范围。set @@global.GTID_PURGED='uuid:interval'
- 利用CHANGE MASTER 语句,配置主从复制
- 启动slave复制,slave会自动跳过这段GTID范围

1.2.4 如何跳过一个GTID?

在GTID的模式下,可以通过跳过该事务的方式恢复主从复制,但是需要判断一下出现错误的原因,如果这是因为插入已经有的值,可以跳过。
操作过程:

stop slave 停止节点复制
set GTID_NEXT="出错的GTID号"
begin;commit
set GTID_NEXT='AUTOMATIC'
start slave
1.2.5 利用GTID模式快速改变主从复制关系、

如果将一个主从复制,修改为一个级联复制,
从B<-A->C到A->B->C,执行的操作:

#停止C实例的复制
stop slave;
#调整C实例的复制关系,修改复制源为B节点。
CHANGE MASTER TO MASTER_HOST,MASTER_PORT=3306,MASTER_AUTO_POSITION=1;
#启动C实例
start slave;

在执行了start slave操作之后,C节点和B节点之间的交互过程:
Alt text
- C节点向B节点发送了一个Dump Binlog请求,并将自身已经执行的GTID信息一起发送给B节点。
- B节点通过对比接受到C节点和自身的节点的执行的GTID的信息,将C节点没有执行的Binlog发送会节点C。
- C节点获得这些信息,不断地将这些binlog应有,这个时候B节点还会不断地发送binlog给C节点。
- C节点不停的执行,最终实现C节点和B节点的同步.

GTID的新的特性

在MySQL的GTID中,mysql.gtid_executed表会存入很多GTID信息,并且这些事务的ID构成一个序列。

mysql> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid                          | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| 25179ea3-d66e-11e7-afa0-00163e2e10b8 |              1 |            1 |
+--------------------------------------+----------------+--------------+
1 row in set (0.00 sec)

在MySQL5.7上面

mysql> show create table mysql.gtid_executed\G
*************************** 1. row ***************************
       Table: gtid_executed
Create Table: CREATE TABLE `gtid_executed` (
  `source_uuid` char(36) NOT NULL COMMENT 'uuid of the source where the transaction was originally executed.',
  `interval_start` bigint(20) NOT NULL COMMENT 'First number of interval.',
  `interval_end` bigint(20) NOT NULL COMMENT 'Last number of interval.',
  PRIMARY KEY (`source_uuid`,`interval_start`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

只用当gtid_mode为ON,或者ON_PERMISSIVE,GTID就会保存在表中,简单来说,该表会记录当前执行的GTID。列source对应UUID,列interval_start/interval_end表示的是事务号。在MySQL 5.6中必须配置参数log_slave_updates的最重要原因在于当slave重启后,无法得知当前slave已经运行到的GTID位置,因为变量gtid_executed是一个内存值。
【1】 gtid的一个表
【2】 GTID的特性
MySQL5.6需要扫描binlog文件来获取当前的执行位置。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值