MySQL 5.7.17 Group Replication部署

MySQL Group Relication是MySQL 5.7.17发布的一个重要的功能。 Group Replication组复制是MySQL的一个插件,可以让多个MySQL节点中的数据保持一致。 其中一个节点的数据被修改后,剩余节点会自动同步。

组复制与MySQL主从复制的区别

在组复制之前,MySQL还支持异步复制(Asynchronous Replication)、半同步复制(Semisynchronous Replication)两种复制模式:

  • 异步复制:这是MySQL最早支持的复制模式,提供最基本的主从复制,可以支持一个主库和多个从库之间的复制,主库更新执行之后,基于binlog这些操作会在从库上重新执行(支持STATEMENT,ROW,MIXED三种方式)。主库不需要保证从库接收并执行了binlog,因此是异步的,主从之间数据会有一定的延迟。在对外不停止服务的前提下,如果主库宕机,提升从库为新的主库,有可能丢失数据,出现数据不一致。
  • 半同步复制:MySQL5.5开始以插件形式实现了半同步复制方案,需要在Master和Savle上安装semisync_master.so和semisync_slave.so插件。半同步复制在异步复制的基础上增加了一个同步过程:在从库接收到主库的更新操作时,会通知主库,主库需要接收来自从库的ack。基本原理是:主库提交事务的线程会被锁定,直到至少一个从库收到这个事务。半同步复制只是能保证从库收到了binlog,但并不保证从库执行了事务,可以结合MHA(Master High Availability),如果master宕机,salve可以在apply所有的relay log后切换成master。 半同步复制的优点是更大程度的保证了数据的一致性;缺点是在性能有所下降,而且 如果异常发生,会降级为异步复制模式。

异步复制和半同步复制,都是一个master对应一个或多个slave,都存在延迟,而且如果master出现故障,那么有可能会出现数据不一致和数据丢失的问题,这在有些业务场景下是不能接受的。MySQL 5.7.17的组复制模式似乎就是为这个问题而生的。

组复制通过分布式一致性算法Paxos来实现各节点状态的高一致性,一个组内允许部分节点挂掉,因此提供了容错性,只要大多数节点都OK的话,对外服务是OK的。在组复制模式下,节点的新增和移除都是自动的。

当前组复制支持如下两种模式:

  • 单master模式:自动选举master,所有更新操作在master上进行
  • 多mastere模式: 所有server都是master,可以同时处理更新操作

试验Group Replication

在简单理解了一下组复制之后,下面通过实验体验一下MySQL 5.7.17的组复制。

现在每台机器上编译安装mysql。

试验环境

  • 192.168.61.21 db1
  • 192.168.61.22 db2
  • 192.168.61.23 db3

/etc/hosts

192.168.61.21 db1
192.168.61.22 db2
192.168.61.23 db3

 

编译安装mysql

下载源码:

wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.17.tar.gz
tar -zxvf mysql-5.7.17.tar.gz

wget http://sourceforge.net/projects/boost/files/boost/1.59.0/boost_1_59_0.tar.gz
tar -zxvf boost_1_59_0.tar.gz

 

创建mysql用户:

groupadd mysql
useradd -g mysql -d /var/lib/mysql -s /sbin/nologin mysql

 

编译安装:

yum install -y make cmake ncurses-devel libtool zlib-devel gcc gcc-c++ bison

mkdir /usr/local/mysql
mkdir /var/log/mysql
chown mysql:mysql /var/log/mysql/

cd mysql-5.7.17

cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/var/lib/mysql \
-DSYSCONFDIR=/etc \
-DDOWNLOAD_BOOST=1 \
-DWITH_BOOST=/root/boost_1_59_0

make

make install

 

mysql配置文件:

rm -f /etc/my.cnf
cd /usr/local/mysql
cp ./support-files/my-default.cnf /etc/my.cnf

 

修改/etc/my.cnf:

[mysqld]
basedir=/usr/local/mysql
datadir=/var/lib/mysql

server_id = 1 #各节点分别指定1,2,3
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-storage-engine=INNODB
#Optimize omit
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
log-bin     = binlog
log_bin_trust_function_creators=1
binlog_format = ROW
expire_logs_days = 99
sync_binlog = 0
slow-query-log=1
slow-query-log-file=/var/log/mysql/slow-queries.log
long_query_time = 3
log-queries-not-using-indexes

 

初始化mysql实例:

/usr/local/mysql/bin/mysqld --initialize \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/var/lib/mysql

 

上面的命令会生成mysql root用户的密码,记录一下。

mysql启动脚本:

cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
sed -i 's#^basedir=#basedir='/usr/local/mysql'#' /etc/init.d/mysqld
sed -i 's#^datadir=#datadir='/var/lib/mysql'#' /etc/init.d/mysqld

chmod 755 /etc/init.d/mysqld
chkconfig mysqld on

echo "export PATH=\$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile

 

 

启动mysql:

service mysqld start

 

使用之前生成的随机密码登陆,修改mysql root用户密码。

mysql -uroot -p

SET PASSWORD = PASSWORD('newpassword');

 

多主组复制配置

各节点上创建repl复制用户:

GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.%' IDENTIFIED BY 'repl';
flush privileges;

 

修改各个节点上的/etc/my.cnf:

[mysqld]
......
log-bin     = binlog
log_bin_trust_function_creators=1
binlog_format = ROW
expire_logs_days = 99

relay-log=db1-relay-bin  #针对各个节点指定

gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log_recovery=ON
binlog_checksum=NONE
log_slave_updates=ON

plugin-load=group_replication.so
transaction_write_set_extraction = XXHASH64
loose-group_replication_group_name = "c7edeea5-ff2d-11e6-a6c7-0800279704c8" #组id,可select uuid();生成

loose-group_replication_start_on_boot = off
loose-group_replication_local_address = "db1:13306"  #针对各个节点指定
loose-group_replication_group_seeds = "db1:13306,db2:13306,db3:13306"
loose-group_replication_bootstrap_group= off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE

group_replication_allow_local_disjoint_gtids_join
group-replication-auto-increment-increment=3
......

 

其中loose-group_replication_local_address中分别指定当前机器的地址以及GR监听的端口,该端口独立于MySQL默认3306的端口。 group-replication-auto-increment-increment是组复制时自增列的步长,默认值为7,这里三个节点,设置为3。另外需要注意auto_increment_offset的值默认是server_id

各个节点上重启mysqld,使配置生效。

开启复制

在db1上开启复制:

CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

 

在db2和db3上开启复制:

CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;

 

查看集群状态:

 SELECT * FROM performance_schema.replication_group_members\G
*************************** 1. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: 1b5e2aeb-ff60-11e6-a122-0800279704c8
 MEMBER_HOST: db2
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
*************************** 2. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: 8b180cc7-ff1d-11e6-a970-0800279704c8
 MEMBER_HOST: db3
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
*************************** 3. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: bf19bf76-ff5f-11e6-94ff-0800279704c8
 MEMBER_HOST: db1
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
3 rows in set (0.00 sec)

 

MySQL GR已经部署完成,下面就可以在一个节点上建库建表写入数据,在其他节点上查看复制是否生效。

参考

 

发表评论