文章目录
- 前言
- 一、传统的主从复制:
- 1 原理:
- 2 缺点:
- 二、半同步复制(Semi-Synchronous Replication):
- 三、组复制:
- 1 原理:
- 2 实现:
- 2.1 myql 实例安装:
- 2.1 myql 实例安装:
- 2.2 防火墙端口放行:
- 2.3 开启组复制:
- 2.4 查看主节点:
- 2.5 节点选举:
- 2.6组复制搭建过程遇到的问题:
- 总结
- 参考:
前言
本文对mysql的传统主从复制,半同步复制和组复制进行介绍。
一、传统的主从复制:
1 原理:
Master 数据库只要发生变化,立马记录到Binlog 日志文件中,Slave数据库启动一个I/0 thread连接Master数据库,请求Master变化的二进制日志。Save I/0获取到的二进制日志,保存到自己的Relay log 日志文件中。Slave 有一个 SQL thread定时检查Realy log是否变化,变化那么就更新数据;
2 缺点:
主从复制在正常情况下是可以保证数据一致性的,即从节点的数据和主节点的数据是完全一致的。主从复制的机制是主节点将写入的数据记录成二进制日志(binlog),然后从节点通过读取和解析主节点的binlog来进行数据复制。
主从数据不一致可能在以下情况下出现:
- 网络问题:如果主节点和从节点之间的网络连接发生故障或不稳定,可能会导致binlog传输中断,进而导致数据不一致。
- 主节点故障:如果主节点发生故障,而在发生故障的瞬间还有未被同步到从节点的binlog,那么在故障恢复后,从节点可能会缺失这部分数据。
- 误操作或数据库错误:如意外执行了误删除/更新操作,或数据库出现了错误,从节点按照主节点的操作纪录执行了相同的操作,导致数据不一致。
虽然主从复制可以保证数据一致性,但在某些极端情况下,如主节点和从节点同时出现故障,则可能无法避免数据不一致。因此,对于一些对数据一致性要求非常高的场景,可以考虑使用更可靠的复制方案,如半同步复制或组复制。
二、半同步复制(Semi-Synchronous Replication):
- 半同步复制是主从复制的一种扩展,它确保至少一个从节点确认已成功接收和写入主节点的二进制日志数据。
- 当主节点接收到一个事务时,它将等待至少一个从节点(半同步节点)确认已写入该事务后才会继续进行下一个事务。
- 半同步复制提供了更高的数据一致性和可靠性,但也增加了延迟和性能开销。
三、组复制:
主从复制只是做了数据的容灾备份,但是没有做到高可用,怎么实现在一个节点挂掉后,不影响整体的业务:
1 原理:
组复制是MySQL InnoDB Cluster中使用的一种多主复制技术,它基于Paxos协议实现了分布式和多主写入的能力。下面是组复制的基本原理:
-
组成员(Group Members):组复制由多个MySQL实例组成,这些实例彼此协作并形成一个复制组(replication group)。每个实例都是组成员,可以是主节点或从节点。
-
角色与状态:在组复制中,每个成员可以有三种角色:原始(Primary)、次要(Secondary)和离线(Offline)。原始成员负责处理写操作,其他次要成员则复制原始成员的数据。离线成员指的是暂时不参与复制的成员。
-
消息通信:组成员之间通过组复制通信层进行消息传递和协调。它提供了成员加入、状态变更、数据同步等功能。在组通信期间,成员之间通过消息传递来达成一致性。
-
选举与协商:组成员使用Paxos协议来选举原始成员和进行决策。选举过程中会协商并选择一个成员作为原始成员,该成员负责处理写操作并将更改广播到其他成员。
-
数据一致性:每个成员都维护着自己的事务日志,并通过组复制通信层将已提交的事务广播给其他成员。在事务提交后,组通信确保所有成员的数据是一致的。
-
自动故障转移:如果原始成员出现故障,组复制会自动选举新的原始成员来接替。选举过程中会基于Paxos协议确保一致的数据状态,从而实现自动的故障转移。
通过上述机制,组复制允许多个节点同时进行写操作,并保证数据的一致性和可靠性。它提供了高可用性、自动故障转移以及简化的管理和扩展能力,适用于分布式环境和多主写入场景。
2 实现:
基于组复制搭建一个高可用的mysql 集群
2.1 myql 实例安装:
-
环境准备:3 台虚拟机:
192.168.75.128
192.168.75.129
192.168.75.130 -
docker 在每个虚拟机上安装一个mysql实例:
docker run -itd --name mysql -e MYSQL_ROOT_PASSWORD=123456 mysql
- 在每个虚拟机上创建mysql 的目录文件:
# 创建mysql 目录
mkdir /root/mysql
# 创建mysql data 目录
mkdir /root/mysql/data
- 在每个虚拟机上复制容器的my.cnf 配置文件
docker cp mysql:/etc/my.conf /root/mysql
2.1 myql 实例安装:
- 每个虚拟机都按照mysql实例:
docker run -itd --name mysql-3806 \
--net=host \
--privileged=true \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /root/mysql3806/data:/var/lib/mysql/ \
-v /root/mysql3806/my.cnf:/etc/my.cnf mysql
--net=host 设置mysql 的docker 容器和虚拟机共享网络
- my.cnf 增加配置:
# 服务实例id,注意每个实例需要保持唯一 ,注意修改
# 192.168.75.129 的server_id=2222
# 192.168.75.130 的server_id=3333
server_id=1111
# 开启事务的强一致性
gtid_mode=ON
enforce_gtid_consistency=ON
# 存储方式为table
master_info_repository=TABLE
# 使用旧版密码的通讯方式
default_authentication_plugin=mysql_native_password
# 同步配置
# binlog的日志格式
binlog_format=ROW
# 不使用binlog校验和
binlog_checksum=NONE
# 开启binlog 并且以binlog 前置文件命名
log_bin=binlog
# 作为从库同步事务后,记录至数据表
relay_log_info_repository=TABLE
# 从服务记录事件其他从服务器可以继续复制从服务器的二进制日志
log-slave-updates=on
# 组复制配置
# 加载组复制插件
plugin_load_add="group_replication.so"
# UUID,分组的节点需配置一致
loose-group_replication_group_name="89c88c78-c46e-11ec-a8aa-0800271ee0d3"
# 启动MySQL时不自动开启组复制
loose-group_replication_start_on_boot=OFF
# 关闭此MySQL实例的组引导
loose-group_replication_bootstrap_group=OFF
# 关闭单主模式,即使用多主模式
# loose-group_replication_single_primary_mode=OFF
# 在多主模式下,建议开启此选项,严格检查一致性
# loose-group_replication_enforce_update_everywhere_checks=ON
# 组复制节点通信禁用SSL
loose-group_replication_ssl_mode=DISABLED
# 当前MySQL实例的组复制通信地址: 33061 为mysql 默认的组内通信端口
# 每个虚拟机的配置自己的mysql 实例ip 地址
loose-group_replication_local_address="192.168.75.128:33061"
# 组复制的节点通信地址
loose-group_replication_group_seeds="192.168.75.128:33061,192.168.75.129:33061,192.168.75.130:33061"
# 通信白名单配置此处配置192.168.75 段的ip 可以进行通信
loose-group_replication_ip_whitelist="192.168.75.0/24,127.0.0.1"
# 绑定本机ip 地址: 注意每个mysql 实例配置自己的ip
bind-address=192.168.75.128
# 向组内通信 报备的 通信ip 地址 注意每个mysql 实例配置自己的ip
report_host=192.168.75.128
# mysql 的服务端口
port=3806
配置完成记得重启mysql 实例
2.2 防火墙端口放行:
# 需要开放的端口
firewall-cmd --permanent --zone=public --add-port={3806,33061}/tcp
# 防火墙重新加载
firewall-cmd --reload
# 查看开放的端口
firewall-cmd --zone=public --list-ports
2.3 开启组复制:
- 每个mysql 实例创建组复制用户:
set sql_log_bin=0;
create user repl@'%' identified by '666666';
grant replication slave on *.* to repl@'%';
set sql_log_bin=1;
flush privileges;
- 使用账户密码登录其他MySQL节点
change master to master_user='repl', master_password='666666' for channel 'group_replication_recovery';
- 组复制:
在 192.168.75.128 mysql 实例中引导组复制
set global group_replication_bootstrap_group=on;
start group_replication;
set global group_replication_bootstrap_group=off;
在 192.168.75.129 和 192.168.75.130 mysql 实例中开启组复制
start group_replication;
如果启动失败,先重置一次,再启动
reset master;
start group_replication;
- 查看组复制集群情况:
select * from performance_schema.replication_group_members;
2.4 查看主节点:
- 方式1 :
-- 获取主机主节点的id
SHOW STATUS LIKE 'group_replication_primary_member';
-- 对比查看每个mysql 实例的uid
sELECT @@server_uuid;
- 方式2:
show variables like '%read_only%';
主服务器:
从服务器:
2.5 节点选举:
当主节点挂掉之后使用Paxos协议 从slave 节点得到新的 master,当修复好后可以重新加入组复制,启动mysql 实例后:
change master to master_user='repl', master_password='666666' for channel 'group_replication_recovery';
start group_replication;
2.6组复制搭建过程遇到的问题:
- mysql 组复制提示 There is no local IP address matching the one configured for the local node:
msyql docker 实例组内通信的ip 地址问题,涉及到的参数:
loose-group_replication_local_address="192.168.75.128:33061"
loose-group_replication_group_seeds="192.168.75.128:33061,192.168.75.129:33061,192.168.75.130:33061"
问题原因:msyql docker 实例内部不认识 192.168.75.128 ip 所以无法通信,需要在安装mysql 实例的时候增加 --net=host 参数,是mysql docker 实例与虚拟机共享网络空间;
- ip/端口 Can’t start server: Bind on TCP/IP port: Cannot assign requested address:
检查防火墙是否开放 mysql 实例的端口和33061 端口;
- Hostname 192.168.75.12 in Allowlist configuration was not resolvable. Please check your Allowlist configuration:
ip 的白名单设置有问题,涉及参数:loose-group_replication_ip_whitelist ,检查ip 是否在白名单中;
-
通信的MEMBER_HOST 问题: There was an error when connecting to the donor server. Please check that group_replication_recovery channel credentials and all MEMBER_HOST column values of performance_schema.replication_group_members table are correct and DNS resolvable;
涉及参数:report_host=192.168.75.128 ,配置正确的ip 地址;
总结
本文对mysql 的传统主从异步复制,半同步复制,组内复制进行了对比,已经通过3台虚拟机搭建了组内复制架构。
参考:
1 部署高可用、负载均衡的MySQL集群服务;
添加链接描述
2 MGR集群搭建及配置过程;