MySQL 组复制(多主模式)
官网:https://dev.mysql.com/doc/refman/5.7/en/group-replication.html
简介
- MySQL组复制是一个MySQL Server插件,使您可以创建弹性的,高可用性的,容错的复制拓扑。基于GTID。
- 组复制是一种可用于实施容错系统的技术。复制组是一组服务器,每个服务器都有自己的完整数据副本(无共享复制方案),并通过消息传递相互交互。
多主模式
多主模式特点:去中心化
故障检测
- 组复制包括故障检测机制,该机制能够找到并报告哪些服务器处于静默状态,并因此认为已死机。一种投票机制,当服务器发现组中某台服务器失联,就会标记为,客观下线,当投票数足够,也就是多台服务器,认为故障服务器下线,这时故障服务器则会主观下线,被移除组。
容错
- 组复制目前,可以成为一个复制组成员的MySQL服务器的最大数量为9。
- MySQL组复制建立在Paxos分布式算法的实现之上,以提供服务器之间的分布式协调。因此,它需要大多数服务器处于活动状态才能达到法定人数,从而做出决定。这直接影响了系统可以容忍的故障数量,而不会损害自身及其整体功能。
服务器实例配置
- server_id=N
唯一服务器标识符。 - gtid_mode=ON
全局事务标识符打开。 - enforce_gtid_consistency=ON
服务器通过允许仅执行可以使用GTID安全记录的语句来实现GTID一致性。 - master_info_repository=TABLE
复制信息存储库。复制应用程序需要将源元数据写入 mysql.slave_master_info。 - relay_log_info_repository=TABLE
复制信息存储库。复制应用程序需要将副本元数据写入mysql.slave_relay_log_info表。 - binlog_checksum=NONE
二进制日志校验和关闭。 - log_slave_updates=ON
已记录副本更新。 - log_bin=binlog
二进制日志处于活动状态。二进制日志文件命名为 binlog - binlog_format=ROW
二进制日志行格式。
组复制设置
组复制系统变量说明官网:https://dev.mysql.com/doc/refman/5.7/en/group-replication-options.html
- plugin_load_add=‘group_replication.so’
plugin-load-add将组复制插件添加到服务器在启动时加载的插件列表中。 - transaction_write_set_extraction=XXHASH64
定义用于生成哈希的算法,该哈希标识与事务关联的写入。如果使用组复制,则哈希值用于分布式冲突检测和处理。在运行组复制的64位系统上,建议将其设置为 XXHASH64,以避免不必要的哈希冲突,该冲突会导致认证失败和用户事务回滚。 - group_replication_group_name=“aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa”
告诉插件将其加入或创建的组命名为“ aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaaa”。 - group_replication_start_on_boot=off
以off指示插件在服务器启动时不自动启动操作。这在设置组复制时很重要,因为它可以确保您可以在手动启动插件之前配置服务器。一旦配置了成员,就可以设置为on以便在服务器启动时自动启动组复制。 - group_replication_local_address= “172.25.9.1:33061”
设置成员用于与组中其他成员进行内部通信的网络地址和端口。所有组成员都必须解析由 配置的网络地址 。 - group_replication_group_seeds= “172.25.9.1:33061,172.25.9.2:33061,172.25.9.3:33061”
设置组成员的主机名和端口,新成员用来建立其与组的连接。 - group_replication_bootstrap_group=off
指示插件是否引导组。在这种情况下,即使s1是组的第一个成员,我们也会在选项文件中将此变量设置为off。 - group_replication_ip_whitelist=“172.25.9.0/24,127.0.0.1/8”
指定允许连接到该组的主机的允许列表。 - group_replication_single_primary_mode=OFF
指示组自动选择一台服务器作为处理读/写工作负载的服务器。关闭单主模式,请用多主模式。 - group_replication_enforce_update_everywhere_checks=ON
需要强制检查一些语句防止冲突的发生 - group_replication_allow_local_disjoint_gtids_join
允许服务器加入组,即使该服务器具有组中不存在的本地事务也是如此。在5.7.21版中已弃用,并计划在以后的版本中将其删除。
实验
主机 | IP |
---|---|
server1 | 172.25.9.1 |
server2 | 172.25.9.2 |
server3 | 172.25.9.3 |
【注意】:如果数据库没什么实验环境的话,建议重新初始化,保证数据一致性,尽可能避免的避免错误。
初始化数据目录:
# 先停止已经运行的MySQL
/etc/init.d/mysqld stop
# 删除数据目录中的数据
rm -fr /usr/local/mysql/data/*
# 初始化数据目录,建议使用初始的配置文件初始化
mysqld --initialize --user=mysql
server1 配置
# 编辑配置文件
vim /etc/my.cnf
[mysqld]
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/data/mysql.sock
symbolic-links=0
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "172.25.9.1:33061"
group_replication_group_seeds= "172.25.9.1:33061,172.25.9.2:33061,172.25.9.3:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="172.25.9.0/24,127.0.0.1/8"
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
# 配置文件修改成功后,启动MySQL
/etc/init.d/mysqld start
# 之前只做了数据目录初始化,并未做安全初始化这里需要更改超户密码
mysql -p
alter user root@localhost identified by 'westos';
# 禁用二进制日志记录,设置此变量OFF 可防止将GTID分配给二进制日志中的事务。
SET SQL_LOG_BIN=0;
# 创建用于复制的用户并授权
CREATE USER rpl_user@'%' IDENTIFIED BY 'westos';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
FLUSH PRIVILEGES;
# 启用二进制日志记录
SET SQL_LOG_BIN=1;
# 将实例添加到组
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='westos' FOR CHANNEL 'group_replication_recovery';
# 启动 group_replication_bootstrap_group插件(组中需要有一个引导主机的组插件)
SET GLOBAL group_replication_bootstrap_group=ON;
# 启动组
START GROUP_REPLICATION;
# 关闭插件,避免server1 出问题修复重新加入后,继续作为引导机,出现脑裂
SET GLOBAL group_replication_bootstrap_group=OFF;
# 查询
SELECT * FROM performance_schema.replication_group_members;
server2 配置
# 先参照上面做数据目录初始化
# 修改配置文件
vim /etc/my.cnf
[mysqld]
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/data/mysql.sock
symbolic-links=0
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "172.25.9.2:33061"
group_replication_group_seeds= "172.25.9.1:33061,172.25.9.2:33061,172.25.9.3:33061"
group_replication_bootstrap_group=off
group_replication_ip_whitelist="172.25.9.0/24,127.0.0.1/8"
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
group_replication_allow_local_disjoint_gtids_join=ON
/etc/init.d/mysql start
mysql -p
alter user root@localhost identified by 'westos';
SET SQL_LOG_BIN=0;
CREATE USER rpl_user@'%' IDENTIFIED BY 'westos';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='westos' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;
# 查询组中主机状态,配置成功的话,目前应该显示,server1 与 server2 为online
SELECT * FROM performance_schema.replication_group_members;
server3 配置
# 与配置 server 2没啥区别,改一下,配置文件中的 server_id 和 group_replication_local_address 即可
vim /etc/my.cnf
……
server_id=2
……
group_replication_local_address= "172.25.9.3:33061"
……
测试
CREATE DATABASE test;
USE test;
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
INSERT INTO t1 VALUES (1, 'Luis');
# 只在一台插入数据,其它两台,均可看到数据。表示配置成功。至此组复制配置完成。
select * from test.t1;
示例截图
模拟故障