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已经部署完成,下面就可以在一个节点上建库建表写入数据,在其他节点上查看复制是否生效。
参考