MySQL-router MGR on Docker Compose
Contents
MGR介绍
MGR 即 MySQL Group Replication
MGR 的特点
高一致性,基于原生复制及 paxos 协议的组复制技术,并以插件的方式提供,提供一致数据安全保证
主从复制分析
传统主从复制,一主多从,主库提供读写功能,从库提供写功能。当一个事务在 master 提交成功时,会把 binlog 文件同步到从库服务器上落地为 relay log 给 slave 端执行,这个过程主库是不考虑从库是否有接收到 binlog 文件,有可能当主库 commit 一个事务后,数据库发生宕机,刚好它的 binlog 还没来得及传送到 slave 端,这个时候任何一个 slave 端都会丢失这个事务,造成数据不一致情况
为了避免出现主从数据不一致的情况,MySQL 引入了半同步复制,添加了从库反馈机制,反馈机制有两种方式:
-
主库执行完事务后,同步 binlog 给从库,从库 ack 反馈接收到 binlog,主库提交 commit 反馈给客户端,释放会话
-
主库执行完事务后,主库提交 commit,同步 binlog 给从库,从库 ack 反馈接收到 binlog 反馈给客户端,释放会话 但还是有问题,虽然满足了一主多从、读写分离、数据一致,依旧有两个弊端:
-
写操作集中在 master 服务器上
-
master 宕机后,需要人为选择新主并重新给其它的 slave 端执行 change master(可自行写第三方工具实现,但是 mysql 的复制就是没提供,所以也算是弊端)
于是官方于 2016 年 12月 12 日正式发布了 MySQL Group Replication
MGR优点
-
可以有多个主节点,在同一个 group 里边的所有实例,每一个实例都可以执行读写操作,需要注意的是,多主情况下,当执行一个事务时,需要确保同个组内的每个实例都认可这个事务无冲突异常,才可以 commit,如果设置的是单主,其它实例 ReadOnly,则不需要进行上面的判断。多主情况下,事务并发冲突问题就凸显出来了,如何避免呢?数据库内部有一个认证程序,当不同实例并发对同一行发起修改,在同个组内广播认可时,会出现并发冲突,那么会按照先执行的提交,后执行的回滚
-
弹性,同个 Group Replication 中,节点的加入或者移除都是自动调整,如果新加入一个节点,该节点会自动从 Group 的其他节点同步数据,直到与其他节点一致。如果移除一个节点,那么剩下的实例会自动更新,不再向这个节点广播事务操作,当然,这里要注意,假设一个 Group 的节点有 n 个(max (n) =9,同个 Group 最多节点数为 9)移除或者宕机的节点数应该小于等于( (n-1)/2) 并且是向下取整。如果是单主模式,宕机的是单主,则需要人为选择新主后,其它节点也会自动从新主同步数据
-
更高性能的同步机制
一个复制组由若干个节点(数据库实例)组成,组内各个节点维护各自的数据副本(Share Nothing)通过一致性协议 paxos 实现原子消息和全局有序消息,来实现组内实例数据的一致
扩展:paxos 协议,paxos 用于解决分布式系统中一致性问题。分布式一致性算法(Consensus Algorithm)是一个分布式计算领域的基础性问题,其最基本的功能是为了在多个进程之间对某个(某些)值达成一致(强一致)简单来说就是确定一个值,一旦被写入就不可改变。paxos 用来实现多节点写入来完成一件事情。paxos 协议只是一个协议,不是具体的一套解决方案。目的是解决多节点写入问题。paxos 协议用来解决的问题可以用一句话来简化:将所有节点都写入同一个值,且被写入后不再更改
-
高容错性,只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制
-
高扩展性,节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其它节点自动更新组信息,自动维护新的组信息
-
高灵活性,有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;多主模式下,所有 server 都可以同时处理更新操作
MGR要求
- 引擎必须为 innodb,因为需事务支持在 commit 时对各节点进行冲突检查
- 每个表必须有主键,在进行事务冲突检测时需要利用主键值对比
- 必须开启 binlog 且为 row 格式
- 开启 GTID,且主从状态信息存于表中(–master-info-repository=TABLE 、–relay-log-info-repository=TABLE)–log-slave-updates 打开
- 一致性检测设置 –transaction-write-set-extraction=XXHASH64
扩展:什么是 GTID?
GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。GTID 实际上是由 UUID+TID 组成的。其中 UUID 是一个 MySQL 实例的唯一标识。TID 代表了该实例上已经提交的事务数量,并且随着事务提交单递增。GTID 的具体形式如:3E11FA47-71CA-11E1-9E33-C80AA9429562:23
MGR使用限制
- 和普通复制 binlog 校验不能共存,需设置 –binlog-checksum=none
- 不支持 gap lock(间隙锁)隔离级别需设置为 read_committed
- 不支持对表进行锁操作(lock/unlock table)不会发送到其他节点执行,影响需要对表进行加锁操作的情况,列入 mysqldump 全表备份恢复操作
- 不支持 serializable(序列化)隔离级别
- DDL 语句不支持原子性,不能检测冲突,执行后需自行校验是否一致
- 多主模式下不支持外键,单主模式不存在此问题
- 最多支持 9 个节点,超过 9 台 server 无法加入组
部署MGR集群
docker-compose.yaml
|
|
部署:docker-compose build
运行:docker-compose up -d xbd-cluster-1 xbd-cluster-2 xbd-cluster-3