mysql - 组复制MGR

传统主从的缺陷

传统主从模式,主节点负责写日志,从节点照着日志,执行完全相同的操作,从而实现数据同步。

缺点:极端情况下,在主节点坏掉的瞬时,日志没发送到从节点,导致出现少量的差异。

优点:主节点不需要关注从节点的状态,更新数据的效率最高。

尽管存在缺点,但是有些系统,容忍这种问题的存在:像是办公、调度、报表系统,如果出现问题,可以通过人工干预的手段,事后进行数据恢复。

双主模式的缺陷

原理还是主从复制(master-slave),是比较另类的用法,主节点和从节点,都可以进行读写,互相同步对方的数据;

因为原理也是主从复制,所以自然也有主从的缺陷,除此之外,是双写带来的事务冲突问题,两个节点很凑巧的改到同一条数据。

总之就是别用,一旦出现问题,一般就是大问题,数据出现差异之后,如果不产生事务冲突,短期内都不会影响使用,要等很久之后才会发现问题。

组复制

已经知道了主从的问题,那么,假设一个事务,需要等从库收到数据,才能最终提交,是不是就能解决这个问题?

是的,这就引出了“组复制”,它做到了这一点。

MGR(Mysql Group Replication)是 5.7 版本新加的特性,是一个 MySQL 插件(使用的时候需要额外安装)。

(主从复制和组复制,中间有个过渡产品:半同步复制,有兴趣可以自己研究一下。)

my.cnf

[mysqld]
# 软件路径
basedir=D:/soft/mysql/
# 数据路径,log/pid/sock 等文件默认都会放到这个路径
datadir=D:/soft/mysql/data/
# socket文件
#socket=D:/soft/mysql/data/mysql.sock
# 错误日志
#log-error=D:/soft/mysql/data/error.log
# pid文件
#pid-file=D:/soft/mysql/data/mysql.pid

# 文件软连接,允许 datadir 指定的目录,软连接到其它磁盘(类似于超链接)
#symbolic-links=1

# 服务 id:做集群的时候,需要保证唯一
server-id = 1

# 最大连接数
#max-connections=1000
# 解决高版本产生 1055 异常报错的问题
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

# binlog 日志的存储路径和文件名,一般只要写文件名,默认会放到 datadir 下
# log-bin=D:/soft/mysql/data/binlog
# 集群同步时忽略的数据库
# binlog-ignore-db=mysql

# 是否只读,1 代表只读, 0 代表读写
# read-only=0

# 监听的ip地址
# port = 3306  
# 监听端口
# bind-address = 0.0.0.0 

# 开启 GTID
gtid_mode=ON
# 强制 GTID 一致性
enforce_gtid_consistency=ON
# 将 master.info 文件的内容,存储到 mysql.slave_master_info 表,内容包含主备复制的位置信息
master_info_repository=TABLE
# 将 relay-log.info 文件的内容,存储到 mysql.slave_relay_log_info 表,内容包含主备复制的位置信息
relay_log_info_repository=TABLE
# 从主库获取的数据,也写到 binlog 文件中,既是主又是从,的时候开启
log_slave_updates=ON
# 使用基于行的格式
binlog_format=ROW
# 禁用二进制日志校验
binlog_checksum=NONE


# WriteSet 是一种复制方式,这个参数用于指定哈希算法,可选值:OFF、MURMUR32、XXHASH64,默认值 XXHASH64
transaction_write_set_extraction=XXHASH64      
# 组的名字可以随便起,但不能用主机的GTID! 所有节点的这个组名必须保持一致
loose-group_replication_group_name="5db40c3c-180c-11e9-afbf-005056ac6820" 
# server 启动的时候,不自动启动组复制    
loose-group_replication_start_on_boot=off    
# 为了避免每次启动自动引导具有相同名称的第二个组,所以设置为OFF。
loose-group_replication_bootstrap_group=off

# 关闭单主模式的参数  
loose-group_replication_single_primary_mode=off      
# 开启多主模式的参数
loose-group_replication_enforce_update_everywhere_checks=on  

# 插件使用的IP地址,用于接受来自其它成员的连接
loose-group_replication_local_address= "192.168.1.200:24901"
# 允许加入组复制的客户机来源的ip白名单
loose-group_replication_ip_whitelist="192.168.1.0/24,127.0.0.1/8"   
# 组成员
loose-group_replication_group_seeds= "192.168.1.200:24901,192.168.1.210:24901,192.168.1.201:24901" 



[mysql]

# prompt命令可以在mysql提示符中显示当前用户、数据库、时间等信息
#mysql -uroot -p --prompt="\\u@\\h:\\d \\r:\\m:\\s>"

同步账号

专门构建一个账号,用于同步数据,注意前后两行,不能省略,否则会影响到后续安装

-- 不记录二进制日志,必须使用这个命令,想通过 reset master 清除日志,是没效果的
set sql_log_bin=0;   

-- 建立账号(mysql8)
create user 'slave' identified with mysql_native_password by 'slave1122..';

-- 建立账号(mysql5)
create user 'slave' identified by 'slave1122..';

-- 授权
grant replication slave,replication client on *.* to 'slave';

-- 重置日志
reset master;

-- 刷新
flush privileges;

-- 记录二进制日志
set sql_log_bin=1;  

安装插件

开启组复制,需要安装新的插件 group_replication.so,插件的位置在 /lib/plugin 目录,可以先提前检查一下文件是否完整

-- 登录账号之后,执行命令即可完成安装
install plugin group_replication soname 'group_replication.so';

-- 查看已安装的插件
show plugins;

-- 设置主机的账号、密码
change master to master_user='slave', master_password='slave1122..' for channel 'group_replication_recovery';

主机设置

第一台机子启用组复制,需要前后两行命令。

SET GLOBAL group_replication_bootstrap_group=ON;

    
START GROUP_REPLICATION;

    
SET GLOBAL group_replication_bootstrap_group=OFF;

需要注意的是 START GROUP_REPLICATION 之前的数据,也会被其它机子同步;

比如:你需要初始化一些数据,不论你在 START GROUP_REPLICATION 步骤之前初始化,还是在之后初始化,数据都会被其它机子同步,最终的结果都是一样的;

因此,这会导致一个问题,你给每一台机子都初始化了数据,然后才开启组复制,因为会互相同步对方的数据,最后反而出现了问题。

从机设置

其它机子启用组复制

START GROUP_REPLICATION;

停用组复制

如果组复制发生故障,需要手动调整数据,则需要下列命令

-- 停用组复制,所有主机都执行
STOP GROUP_REPLICATION;

-- 清理 binlog 文件
RESET MASTER;
RESET SLAVE ALL;

重启机子

更复杂的设计,重启的方式也变得更加复杂。

服务重启之后,重新加入组复制,需要手动执行命令

-- 这一步需要手动执行,数据会自动更新到最新
START GROUP_REPLICATION;

相关重启报错

-- 报错1
-- ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log.

-- 报错原因:缺失主节点,使用下面这个命令,让其中一个节点成为主节点
mysql> set global group_replication_bootstrap_group = ON;
mysql> start group_replication;

-- 报错2
-- Plugin group_replication reported: ‘The member contains transactions not present in the group. The member will now exit the group.’
-- Plugin group_replication reported: ‘To force this member into the group you can use the group_replication_allow_local_disjoint_gtids_join option’

-- 根据报错提示,则设置这个参数
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
mysql> start group_replication;

-- 报错3
-- 如果节点存在未提交的事务(数据存在差异),会显示该节点状态是:recovering,这就是最麻烦的情况了,需要根据实际情况,想办法手动同步数据;
-- 首次开启组复制,也很容易报 recovering,一般是因为创建账号步骤中,没有执行 set sql_log_bin=0。

posted on 2024-04-08 17:41  疯狂的妞妞  阅读(6)  评论(0编辑  收藏  举报

导航