MySQL系列(16)--GTID介绍

在MySQL 5.5中,复制的方法使用的是基于日志点的复制,什么意思呢?当从服务器要从主服务器复制数据时,需要指定从主服务器的哪个二进制日志文件和二进制日志文件的位置来进行数据的复制操作。由于这种依赖日志点进行数据复制的特性,所有复制是单线程的(如果有多线程复制会出现数据不一致情况)。而主库是多线程写入,所有主从复制延迟就变成了很长见了。
加入了全局事务ID (Global Transaction ID) 来强化数据库的主备一致性,故障恢复,以及容错能力。用于取代过去通过binlog文件偏移量定位复制位置的传统方式。借助GTID,在发生主备切换的情况下,MySQL的其它Slave可以自动在新主上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。

基于GTID的复制有什么优点?

1)在传统的复制里面,当发生故障,需要主从切换,需要找到binlog和pos点,然后change master to指向新的master,相对来说比较麻烦,也容易出错。在MySQL 5.6里面,不用再找binlog和pos点,我们只需要知道master的ip,端口,以及账号密码就行,因为复制是自动的,MySQL会通过内部机制GTID自动找点同步。

2)多线程复制(基于库),在MySQL 5.6以前的版本,slave的复制是单线程的。一个事件一个事件的读取应用。而master是并发写入的,所以延时是避免不了的。唯一有效的方法是把多个库放在多台slave,这样又有点浪费服务器。在MySQL 5.6里面,我们可以把多个表放在多个库,这样就可以使用多线程复制,当只有1个库,多线程复制是没有用的。

基于GTIDs复制实现的工作原理?

1)master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。

2)slave端的i/o 线程将变更的binlog,写入到本地的relay log中。

3)sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录(所以MySQL5.6 SLAVE必须要开启二进制日志记录)。

4)如果有记录,说明该GTID的事务已经执行,slave会忽略。

5)如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。

6)在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。

多线程复制

MySQL 5.6之前的版本,同步复制是单线程的,队列的,只能一个一个执行,在5.6里,可以做到多个库之间的多线程复制,例如数据库里,存放着用户表,商品表,价格表,订单表,那么将每个业务表单独放在一个库里,这时就可以做到多线程复制,但一个库里的表,多线程复制是无效的(因为同一个库进行多线程复制到从服务器上时会造成问题)。

注:每个数据库仅能使用一个线程,复制涉及到多个数据库时多线程复制才有意义。从服务器上多线程复制的参数Slave-parallel-workers=0(0表示禁用多线程功能)

GTID的限制:

1.不支持非事务引擎
2.不支持create table … select 语句复制(主库直接报错)
原理:( 会生成两个sql,一个是DDL创建表SQL,一个是insert into 插入数据的sql。
由于DDL会导致自动提交,所以这个sql至少需要两个GTID,但是GTID模式下,只能给这个sql生成一个GTID )
3.不允许一个SQL同时更新一个事务引擎表和非事务引擎表
4.在一个复制组中,必须要求统一开启GTID或者是关闭GTID
5.开启GTID需要重启(5.7除外)
6.开启GTID后,就不再使用原来的传统复制方式
7.对于create temporary table 和 drop temporary table语句不支持
8.不支持sql_slave_skip_counter

https://yq.aliyun.com/articles/57731

猜你喜欢

转载自blog.csdn.net/duanxiaobin2010/article/details/81743739