天天看点

MySQL5.7杀手级新特性:GTID原理与实战MySQL5.7杀手级新特性:GTID原理与实战

gtid 架构

a) gtid = server_uuid:transaction_id

b) server_uuid 来源于 auto.cnf

c) gtid: 在一组复制中,全局唯一

gtid在binlog中的结构

MySQL5.7杀手级新特性:GTID原理与实战MySQL5.7杀手级新特性:GTID原理与实战

gtid event 结构

MySQL5.7杀手级新特性:GTID原理与实战MySQL5.7杀手级新特性:GTID原理与实战

previous_gtid_log_event

previous_gtid_log_event 在每个binlog 头部都会有 每次binlog rotate的时候存储在binlog头部 previous-gtids在binlog中只会存储在这台机器上执行过的所有binlog,不包括手动设置gtid_purged值。 换句话说,如果你手动set global gtid_purged=xx; 那么xx是不会记录在previous_gtid_log_event中的。

gtid和binlog之间的关系是怎么对应的呢

如何才能找到gtid=?对应的binlog文件呢?

gtid相关参数

参数

comment

gtid_executed

执行过的所有gtid

gtid_purged

丢弃掉的gtid

gtid_mode

gtid模式

gtid_next

session级别的变量,下一个gtid

gtid_owned

正在运行的gtid

enforce_gtid_consistency

保证gtid安全的参数

重要参数如何持久化

1) 如何持久化gtid_executed [ log-bin=on,log_slave_update=on ]

2) 如何持久化重置的gtid_purged值?

reset master; set global gtid_purged=$a:a-b;

3)如何持久化gtid_purged [ log-bin=on,log_slave_update=on ]

mysql 5.6

mysql 5.7

mysql5.7.13 or higher

slave sends to master range of identifiers of executed transactions to master

master send all other transactions to slave

同样的gtid不能被执行两次,如果有同样的gtid,会自动被skip掉。

MySQL5.7杀手级新特性:GTID原理与实战MySQL5.7杀手级新特性:GTID原理与实战

slave1 : 将自身的uuid1:1 发送给 master,然后接收到了 uuid1:2,uuid1:3 event

slave2 : 将自身的uuid1:1,uuid1:2 发送给 master,然后接收到了uuid1:3 event

重要函数

name

description

gtid_subset(subset,set)

returns true (1) if all gtids in subset are also in set

gtid_subtract(set,subset)

returns only those gtids from set that are not in subset

wait_for_executed_gtid_set(gtid_set[, timeout])

wait until the given gtids have executed on slave.

wait_until_sql_thread_after_gtids(gtid_set, timeout)

wait until the given gtids have executed on slave

新语法

MySQL5.7杀手级新特性:GTID原理与实战MySQL5.7杀手级新特性:GTID原理与实战
MySQL5.7杀手级新特性:GTID原理与实战MySQL5.7杀手级新特性:GTID原理与实战

不安全的事务

设置enforce-gtid-consistency=on
<a href="http://dev.mysql.com/doc/refman/5.7/en/replication-solutions-unexpected-slave-halt.html">http://dev.mysql.com/doc/refman/5.7/en/replication-solutions-unexpected-slave-halt.html</a>

关于crash safe , 可以参考官方文档列出的安全配置

单线程复制

non-gtid 推荐配置: relay_log_recovery=1,relay_log_info_repository=table,master_info_repository=table gtid 推荐配置:master_auto_position=on,relay_log_recovery=0
MySQL5.7杀手级新特性:GTID原理与实战MySQL5.7杀手级新特性:GTID原理与实战

多线程复制

non-gtid 推荐配置: relay_log_recovery=1, sync_relay_log=1,relay_log_info_repository=table,master_info_repository=table gtid 推荐配置: master_auto_position=on, relay_log_recovery=0
MySQL5.7杀手级新特性:GTID原理与实战MySQL5.7杀手级新特性:GTID原理与实战

step 1: 让所有server处于同一个点

step 2: 关闭所有mysql

step 3: 重启所有mysql,并开启gtid

当然,在my.cnf中配置好最佳

step 4: change master

step 5: 让master 可读可写

step 1: 备份

step 2: 在新服务器上reset master,导入备份

step 3: change master

offline 的方式升级最简单。全部关机,然后配置好gtid,重启,change master to master_auto_position=1。
这里先介绍几个重要gtid_mode的value

gtid_mode = off : 不产生normal_gtid,只接受来自master的anonymous_gtid

gtid_mode = off_permissive : 不产生normal_gtid,可以接受来自master的anonymous_gtid &amp; normal_gtid

gtid_mode = on_permissive : 产生normal_gtid,可以接受来自master的anonymous_gtid &amp; normal_gtid

gtid_mode = on : 产生normal_gtid,只接受来自master的normal_gtid

master和slave的gtid_mode 组合搭配矩阵图

水平的gtid_mode为:master , 垂直的gtid_mode为:slave

off(master)

off_permissive(master)

on_permissive(master)

on(master)

off(slave)

y

n

off_permissive(slave)

y(auto_position可以开启)

on_permissive(slave)

on(slave)

归纳总结:

1) 当master产生normal_gtid的时候(on_permissive,on),如果slave的gtid_mode(off)不能接受normal_gtid,那么就会报错

2) 当master产生anonymous_gtid的时候(off_permissive,off),如果slave的gtid_mode(on)不能接受anonymous_gtid,那么就会报错

3) 设置auto_position的条件: 当master gtid_mode=on时,slave可以为off_permissive,on_permissive,on。除此之外,都不能设置auto_position = on

下面罗列下,如何online 升级为gtid模式。

step 1: 每台server执行

检查错误日志,直到没有错误出现,才能进行下一步

step 2: 每台server执行

step 3: 每台server执行

不用关心一组复制集群的server的执行顺序,只需要保证每个server都执行了,才能进行下一步

step 4: 每台server执行

step 5: 在每台server上执行,如果ongoing_anonymous_transaction_count=0就可以

不需要一直为0,只要出现过0一次,就ok

step 6: 确保所有anonymous事务传递到slave上了

step 7: 每台server上执行

step 8: 在每台server上将my.cnf中添加好gtid配置

step 9: change master

配置好loss-less semi-sync replication,可以更可靠的保证数据零丢失。 以下说的都是crash 后,起不来的情况

binlog 在master还有日志没有传递到 slave

binlog 已经传递到slave

以上操作,在传统模式复制下,只能通过mha来实现,mha比较复杂。

现在,在gtid模式下,实现起来非常简单,且非常方便。

使用gtid后,对原来传统的运维有不同之处了,需要调整过来。 使用row模式且复制配置正确的情况下,基本上很少发现有复制出错的情况。 slave 设置 super_read_only=on
出现这种问题基本有两种情况 复制参数没有配置正确,当slave crash后,会出现重复键问题 dba操作不正确,不小心在slave上执行了事务

对于第一个重复键问题

传统模式

对于第二种不小心多执行了事务

这种情况就比较难了,这样已经导致了数据不一致,大多数情况,建议slave重做 如何避免: slave 设置 super_read_only=on
这里说下inject empty transction的隐患

当slave上inject empty transction,说明有一个master的事务被忽略了(这里假设是 $uuid:100)

事务丢失一:如果此时此刻master挂了,这个slave被选举为新master,那么其他的slave如果还没有执行到$uuid:100,就会丢失掉$uuid:100这个事务。

事务丢失二:如果从备份中重新搭建一个slave,需要重新执行之前的所有事务,而此时,master挂了, 又回到了事务丢失一的场景。

设置gtid_executed

设置gtid_purged