MySQL 当前存在异步复制、半同步复制,在 5.7.17 引入了组复制模式,这是基于分布式一致性算法 (Paxos 协议的变体) 实现。
一个组允许部分节点挂掉,只要保证多数节点仍然存活并且相互之间可以正常通讯,那么这个组仍然可以对外提供服务,是目前一种被分布式系统广泛使用的技术。
如下,仅简单介绍如何使用。
介绍
MySQL 组复制实现基于插件,建立在现有的 MySQL 复制基础结构上,利用了 binlog、GTID、row-based logging、InnoDB、Corosync(三方);注意最新版本的已经将 Corosync 替换掉。
搭建集群
首先,需要确认当前 MySQL 版本是否支持组复制;实际上,可以简单查看 plugin_dir
目录下是否存在 group_replication.so
动态库即可。
如下是一个简单的配置文件,需要注意的是,默认将 group_replication_start_on_boot
参数关闭,在第一个服务器启动时打开该参数。
# only the last two sub-sections are directly related to Group Replication
[mysqld]
server-id = 2
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
pid-file = /tmp/mysql.pid
log-error = mysqld.log
# replication and binlog related options
binlog-row-image = MINIMAL # 取消后镜像,减小binlog大小
relay-log-recovery = ON # 备库恢复时从relaylog获取位点信息
sync-relay-log = 1 # 每个事务同时将位点信息持久化
sync-master-info = 1000
slave-parallel-workers = 4 # 设置备库的并发
slave-parallel-type = LOGICAL_CLOCK # 利用组提交的逻辑值做并发
binlog-rows-query-log-events = ON # ROW模式binlog添加SQL信息,方便排错
log-bin-trust-function-creators = ON # 同时复制主库创建的函数
slave-preserve-commit-order = ON # 备库的事务提交时,保持与主库相同顺序
log-slave-updates = ON # 备库同时生成binlog
slave-rows-search-algorithms = 'INDEX_SCAN,HASH_SCAN'
slave-type-conversions = ALL_NON_LOSSY
# group replication pre-requisites & recommendations
log-bin = mysql-bin # 开启binlog
binlog-format = ROW # 目前只支持ROW模式
gtid-mode = ON # 设置如下两个参数启动GTID
enforce-gtid-consistency = ON
master-info-repository = TABLE # 主库信息保存在表中
relay-log-info-repository = TABLE # relaylog信息保存在表中
binlog-checksum = NONE # 取消checksum
transaction-isolation = 'READ-COMMITTED' # 间隙锁可能会存在问题
# prevent use of non-transactional storage engines
disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE"
# group replication specific options
plugin-load = group_replication.so # 加载组复制的插件
group_replication = FORCE_PLUS_PERMANENT
transaction-write-set-extraction = XXHASH64 # MURMUR32,NONE
group_replication_start_on_boot = OFF
group_replication_bootstrap_group = OFF
group_replication_group_name = 550fa9ee-a1f8-4b6d-9bfe-c03c12cd1c72
group_replication_local_address = '127.0.0.1:3307'
group_replication_group_seeds = '127.0.0.1:3307,127.0.0.1:3308,127.0.0.1:3309'
InnoDB 的间隙锁在进行多主的冲突检测时存在问题,因此最好不要使用 REPEATABLE-READ 隔离级别,而是使用 READ-COMMITTED 隔离级别。
搭建完之后,可以通过如下命令查看当前组的成员。
mysql> SELECT * FROM performance_schema.replication_group_members;
参考
- 关于 Group Replication 的基本介绍可以参考 High Availability Using MySQL Group Replication (PPT),或者 本地文档 。对于 MySQL 的 Group Replication 介绍,演进过程,设计文档等,可以参考 mysqlhighavailability.com、MySQL Group Replication’s documentation!
- MySQL Group Replication 的实现可以参考论文 The Database State Machine Approach (PDF) 或者 本地文档 。