MGR部署MySQL5.7
MySQL高可用工具
MGR
- MGR(MySQL Group Replication)是一种数据库集群技术,允许多个 MySQL 服务器协同工作,形成一个高可用的数据库集群。当一个mysql出现故障时,其他mysql可以继续工作,确保服务的连续性和数据的高可用性。
- MGR允许多个 MySQL 实例组成一个组,这些实例之间会自动同步数据,确保数据的一致性和高可用性。如果某个实例出现故障,其他实例会继续工作,从而保持服务的连续性。
- MGR是mysql原生带有的,不需要安装插件。MGR集群也有一些限制和要求,例如需要使用==InnoDB==存储引擎。
适用于需要高度自动化和数据一致性的场景。它提供了内置的高可用性解决方案,适合不希望依赖第三方工具的用户。
MMM
- MMM(MySQL Multi-Master Replication Manager)是一种用于管理 MySQL 主从复制的工具。它允许你配置多个主节点和从节点,并在主节点发生故障时自动进行故障转移。MMM 可以帮助你实现读写分离,提升系统性能。
适用于需要复杂复制拓扑和读写分离的场景。它允许配置多个主节点和从节点,但需要手动管理和监控。
MHA
- MHA(Master High Availability Manager and tools)MHA 是一种用于 MySQL 主从复制环境中的高可用性管理工具。它在主节点发生故障时,能够自动选举一个新的主节点,并重新配置复制关系,从而实现快速故障转移。
适用于需要快速故障转移和高可用性的主从复制环境。它能够自动处理主节点故障,但不支持多主复制。
部署MGR一主多从集群
环境准备
| IP | hostname | Port | ServerID | OS |
|---|---|---|---|---|
| 192.168.40.100 | xianchaomaster1 | 3306 | 63 | CentOS 7.9 |
| 192.168.40.101 | xianchaomaster2 | 3306 | 64 | CentOS 7.9 |
| 192.168.40.102 | xianchaomaster3 | 3306 | 62 | CentOS 7.9 |
安装mysql
- 配置三台hosts文件
tee -a /etc/hosts <<'EOF'
192.168.40.102 xianchaomaster3
192.168.40.100 xianchaomaster1
192.168.40.101 xianchaomaster2
EOF
- 安装mysql
#所有节点,上传预先准备好的压缩包:mysql-5.7.tar.gz,包括了安装mysql5.7主要的软件包
tar xvf mysql-5.7.tar.gz
yum -y install ./mysql*.rpm
systemctl start mysqld
#启动MySQL会生成临时密码。
#在MySQL的配置文件/etc/my.cnf中关闭密码强度审计插件,并重启MySQl服务。
vim /etc/my.cnf
#修改MySQL的配置文件,在[myqld]标签处末行添加以下项:
validate-password=OFF #不使用密码审计插件
systemctl restart mysqld
grep 'password' /var/log/mysqld.log #获取临时密码。
- 登录mysql修改root密码
mysql -u root -p'buL.UJp!T2Od' #使用临时密码登录MySQl,注意临时密码要引号
mysql> set password for root@localhost = password('123456');
#修改root用户密码为123456
mysql> use mysql;
mysql> update user set host = '192.168.40.%' where user = 'root';
mysql> update user set host = '%' where user = 'root';
mysql> flush privileges;
配置master1主节点
#group_name可以通过uuidgen生成
uuidgen
#服务器xianchaomaster1配置/etc/my.cnf
#参考:官网配置https://dev.mysql.com/doc/refman/5.7/en/group-replication-configuring-instances.html
vim /etc/my.cnf
#在 [mysqld] 配置组中,增加以下红色内容:
server_id = 63
#这个设置给当前 MySQL 服务分配了一个唯一的标识号码,用来在复制和集群中区分不同的服务。
gtid_mode = ON
#开启全局事务标识(GTID),用于在数据库复制和高可用性方案中确保事务的唯一性和一致性。
enforce_gtid_consistency = ON
#强制 GTID 一致性,确保所有数据库节点上执行的事务顺序和一致性。
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'
#加载并启用 MySQL 的组复制插件,用于实现多个数据库实例之间的同步和协作。
transaction_write_set_extraction=XXHASH64
#使用哈希算法将事务写入集提取为散列,有助于数据库更有效地处理和记录事务。
group_replication_group_name="ce9be252-2b71-11e6-b8f4-00212844f856"
#设置组复制的唯一标识符,确保每个参与组复制的数据库实例都能识别并加入正确的组。
group_replication_start_on_boot=off
#设置数据库实例不会在启动时自动加入组复制,需要手动控制启动过程。
group_replication_local_address="xianchaomaster1:33063"
#指定本地 MySQL 实例接受其他组成员的连接的地址和端口号。
group_replication_group_seeds="xianchaomaster1:33063, xianchaomaster2:33064, xianchaomaster3:33062"
#指定组成员的地址和端口,用于初始化组复制中的初始通信和连接。
group_replication_bootstrap_group=off
#禁用组引导功能,避免在启动时自动创建一个新的复制组。
#重启MySQL服务
systemctl restart mysqld
配置参数详解
- server_id = 63:每个MySQL服务都像一个独特的身份证号码一样,以便在集群中识别和区分不同的服务器。
- gtid_mode = ON:开启了一个全球唯一的事务ID,可以用来标识数据库中的每个事务,有助于跟踪和管理数据库复制。
- enforce_gtid_consistency = ON:确保在数据库复制时,所有事务都以一致的方式被复制到其他服务器,以避免数据不一致问题。
- master_info_repository = TABLE 和 relay_log_info_repository = TABLE:将有关主服务器和中继日志的一些关键信息保存在MySQL系统表中,以便服务器能够管理和访问这些信息。
- binlog_checksum = NONE:关闭了对二进制日志的数据完整性检查,可能会提高性能,但要小心数据一致性问题。
- log_slave_updates = ON:从服务器可以记录自己的二进制日志,允许其他服务器复制这个从服务器的数据。
- log_bin = binlog 和 binlog_format = ROW:将数据库的更改操作以二进制形式记录,以行的方式记录每个操作的详细信息。
- plugin_load_add='group_replication.so':启用一个名为group_replication.so的插件,用于启用MySQL的组复制功能。
- transaction_write_set_extraction=XXHASH64:用一种特定的哈希算法来处理事务的写入操作。
- group_replication_group_name:为组复制集群起一个唯一的名称,以便其他服务器可以加入这个集群。
- group_replication_start_on_boot=off:不要在服务器启动时自动开始组复制,需要手动启用。
- group_replication_local_address:指定服务器在哪个IP地址和端口上接收其他组成员的连接请求。
- group_replication_group_seeds:告诉服务器在哪些IP地址和端口上可以找到其他组成员,以便它们可以建立连接。
- group_replication_bootstrap_group=off:不要启动一个新的组,而是让服务器加入一个已经存在的组。
- master1配置复制账号
mysql -u root -p123456
mysql> set SQL_LOG_BIN=0; #停掉日志记录
mysql> grant replication slave on *.* to repl@'192.168.40.%' identified by '123456';
#创建一个用户名为 repl 的用户,并允许该用户从 192.168.40.* 范围内的任何 IP 地址以123456这个密码连接到 MySQL 服务,同时授予该用户进行数据复制所需的权限
mysql> grant replication slave on *.* to repl@'%' identified by '123456';
#创建一个用户repl,后期用于其他节点,同步数据。
mysql> flush privileges; #重新加载授权表,从而使对用户权限所做的更改立即生效
mysql> set SQL_LOG_BIN=1; #开启日志记录
为什么创建repl用户需要关闭二进制日志功能?
因为用于同步数据的用户名repl和密码,必须在所有节点上有,且用户名和密码必须一样。所以,创建用户和密码时,先关闭二进制日志功能,这样不产生二进制日志数据。创建成功后,再开启二进制日志功能。这样repl用户信息,每台机器上都有了,而且不会在MGR同步数据时产生冲突。
mysql> change master to master_user='repl',master_password='123456' for channel 'group_replication_recovery';
CHANGE MASTER TO 命令说明
- CHANGE MASTER TO: 这是 MySQL 的命令,用于修改从节点的复制配置。
- MASTER_USER='repl': 指定连接主节点的用户名为 repl,这是一个在主节点上用于复制的已授权用户。
- MASTER_PASSWORD='123456': 指定连接主节点的密码,这里设置为 123456,以确保从节点能够安全地连接到主节点进行数据复制。
- FOR CHANNEL 'group_replication_recovery': 指定这个配置是为名为 group_replication_recovery 的复制通道进行的。在MySQL 组复制中,每个从节点都会为复制通道分配一个唯一的标识符,这里使用通道名称来区分不同的复制配置。
#查看MySQL服务器xianchaomaster1上安装的group replication插件,这个组件在my.cnf配置文件中,plugin_load_add='group_replication.so'有指定。
mysql> show plugins;
#如果没有安装成功,可以执行这个命令,手动再次安装:安装插件
mysql> install PLUGIN group_replication SONAME 'group_replication.so';
#启动服务器xianchaomaster1上MySQL的group replication
#设置group_replication_bootstrap_group为ON,表示这台机器是集群中的master,以后加入集群的服务器都是salve。引导只能由一台服务器完成。
mysql> set global group_replication_bootstrap_group=ON;
- 作为首个节点启动mgr集群
mysql> start group_replication;
mysql> set global group_replication_bootstrap_group=OFF; #启动成功后,这台服务器已经是master了。有了master后,引导器就没有用了,就可以关闭了。
- 查看mgr的状态
#查询表performance_schema.replication_group_members
mysql> select * from performance_schema.replication_group_members;
- 测试服务器xianchaomaster1上的MySQL
mysql> create database test;
mysql> use test;
mysql> create table t1 (id int primary key,name varchar(20)); #注意创建主键
mysql> insert into t1 values (1,'man');
mysql> select * from t1;
mysql> show binlog events;
集群中添加master2主机
- 复制组添加新实例xianchaomaster2
#在master2上面,修改/etc/my.cnf 配置文件,方法和之前相同。
vim /etc/my.cnf #在mysqld配置,追加以下内容
server_id=64 #注意服务ID不能一样
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="ce9be252-2b71-11e6-b8f4-00212844f856" #这保持和master一样
group_replication_start_on_boot=off
group_replication_local_address="xianchaomaster2:33064" #以本机端口33064接受来自组中成员的传入连接
group_replication_group_seeds="xianchaomaster1:33063, xianchaomaster2:33064, xianchaomaster3:33062" #组成员列表
group_replication_bootstrap_group=off
systemctl restart mysqld
- 用户授权
mysql -u root -p123456
mysql> set SQL_LOG_BIN=0; #停掉日志记录
mysql> grant replication slave on *.* to repl@'192.168.40.%' identified by '123456';
mysql> grant replication slave on *.* to repl@'%' identified by '123456';
mysql> flush privileges;
mysql> set SQL_LOG_BIN=1; #开启日志记录
mysql> change master to master_user='repl',master_password='123456' for channel 'group_replication_recovery'; #构建group replication集群
- 把实例添加到之前的复制组
#master2上
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
mysql> start group_replication;
#去master1上面查看复制组状态
mysql> select * from performance_schema.replication_group_members;
#master2上可以看到数据已经同步
mysql> select * from test.t1;
集群中标添加master3主机
- 修改配置
#master3上
vim /etc/my.cnf
server_id=62 #注意服务id不一样
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="ce9be252-2b71-11e6-b8f4-00212844f856"
group_replication_start_on_boot=off
group_replication_local_address="xianchaomaster3:33062"
group_replication_group_seeds="xianchaomaster1:33063, xianchaomaster2:33064, xianchaomaster3:33062"
group_replication_bootstrap_group=off
systemctl restart mysqld
- 用户授权
#用户授权
mysql -u root -p123456
mysql> set SQL_LOG_BIN=0; #停掉日志记录
mysql> grant replication slave on *.* to repl@'192.168.40.%' identified by '123456';
mysql> grant replication slave on *.* to repl@'%' identified by '123456';
mysql> flush privileges;
mysql> set SQL_LOG_BIN=1; #开启日志记录
mysql> change master to master_user='repl',master_password='123456' for channel 'group_replication_recovery'; #构建group replication集群
- 添加到复制组
#把实例添加到之前的复制组
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
mysql> start group_replication;
#在xianchaomaster1上查看复制组状态
mysql> select * from performance_schema.replication_group_members;
测试集群读写
#xianchaomaster1查看集群参数设置列表:
mysql> show variables like 'group_replication%';
#显示与组复制(Group Replication)相关的系统变量的信息。
#查看xianchaomaster1是否只读,发现xianchaomaster1 master,可读可写。
mysql> show variables like '%read_only%';
#另外两台查看,发现xianchaomaster2和xianchaomaster3,是只读的
mysql> show variables like '%read_only%';
Multi-primary多主模式实现多节点同时读写
由单主模式修改为多主模式
#1、关闭xianchaomaster1单主模式,在原来单主模式的主节点执行操作如下:
mysql -u root -p123456
mysql> stop GROUP_REPLICATION;
mysql> set global group_replication_single_primary_mode=OFF;
#关闭单master模式
mysql> set global group_replication_enforce_update_everywhere_checks=ON;
#设置多主模式下各个节点严格一致性检查,启用了这个功能,MySQL 将会在执行更新操作前检查所有节点,确保更新操作在所有节点都能够成功执行,以避免数据不一致的情况发生。
mysql> SET GLOBAL group_replication_bootstrap_group=ON; #启动组复制的引导过程
mysql> START GROUP_REPLICATION; #这条命令启动了组复制。在引导过程中,此命令用于启动组复制服务,使得当前 MySQL 实例可以加入到已经存在的复制组中,或者创建一个新的复制组。
mysql> SET GLOBAL group_replication_bootstrap_group=OFF; #关闭组复制的引导模式
#2、master2上
mysql -u root -p123456
mysql> stop GROUP_REPLICATION;
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON; #允许本地节点加入即使 GTIDs 不完全一致,可以在某些情况下(如节点数据恢复或加入新节点时)帮助系统更灵活地进行复制管理和数据同步。
mysql> set global group_replication_single_primary_mode=OFF;
mysql> set global group_replication_enforce_update_everywhere_checks=ON;
mysql> start group_replication;
#查看是否只读的参数
mysql> show variables like '%read_only%';
#3、master3上
mysql -u root -p123456
mysql> stop GROUP_REPLICATION;
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
mysql> set global group_replication_single_primary_mode=OFF;
mysql> set global group_replication_enforce_update_everywhere_checks=ON;
mysql> start group_replication;
mysql> show variables like '%read_only%';
测试集群读写
#查看组复制成员
mysql> select * from performance_schema.replication_group_members;
#测试 Multi-primary多主模式实现多节点同时读写
#xianchaomaster1上执行
mysql> insert into test.t1 values (2,'aa');
#xianchaomaster2上执行:
mysql> insert into test.t1 values (3,'cc');
#xianchaomaster3上执行:
mysql> insert into test.t1 values (6,'cc');
mysql> select * from test.t1;
测试节点故障
#测试MGR集群中一些节点坏了, 数据还可以正常读写
#xianchaomaster1
systemctl stop mysqld
#xianchaomaster3
systemctl stop mysqld
#xianchaomaster2
mysql -u root -p123456
mysql> select * from performance_schema.replication_group_members;
mysql> insert into test.t1 values (5,'ff');
mysql> select * from test.t1;
#master1\3重新加回到集群
systemctl start mysqld
mysql -u root -p123456
mysql> select * from test.t1;
mysql> stop GROUP_REPLICATION;
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
mysql> set global group_replication_single_primary_mode=OFF;
mysql> set global group_replication_enforce_update_everywhere_checks=ON;
mysql> start group_replication;
mysql> select * from test.t1;
mysql> select * from performance_schema.replication_group_members;
基于nginx+keepalived实现MGR Mysql高可用
安装nginx主备
#master1\2上安装nginx
yum install epel-release -y
yum install nginx-mod-stream -y
yum install nginx keepalived -y
#主备修改配置文件
tee /etc/nginx/nginx.conf <<'EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
# 四层负载均衡,为两台Master apiserver组件提供负载均衡
stream {
log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
access_log /var/log/nginx/k8s-access.log main;
upstream mysql-server {
server 192.168.40.100:3306 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.40.101:3306 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.40.102:3306 weight=5 max_fails=3 fail_timeout=30s;
}
server {
listen 13306; # 由于nginx与master节点复用,这个监听端口不能是3306,否则会冲突
proxy_pass mysql-server;
}
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80 default_server;
server_name _;
location / {
}
}
}
EOF
keepalived配置
#master1主keepalived
tee /etc/keepalived/keepalived.conf <<'EOF'
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_MASTER
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
}
vrrp_instance VI_1 {
state MASTER
interface ens33 # 修改为实际网卡名
virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的
priority 100 # 优先级,备服务器设置 90
advert_int 1 # 指定VRRP 心跳包通告间隔时间,默认1秒
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟IP
virtual_ipaddress {
192.168.40.199/24
}
track_script {
check_nginx
}
}
EOF
#vrrp_script:指定检查nginx工作状态脚本(脚本返回状态码(0为工作正常,非0不正常)判断是否故障转移。)
#master2备keepalived
tee /etc/keepalived/keepalived.conf <<'EOF'
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_BACKUP
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.40.199/24
}
track_script {
check_nginx
}
}
EOF
#主备添加判断nginx存活的脚本
tee /etc/keepalived/check_nginx.sh <<'EOF'
#!/bin/bash
#1、判断Nginx是否存活
counter=`ps -C nginx --no-header | wc -l`
if [ $counter -eq 0 ]; then
#2、如果不存活则尝试启动Nginx
service nginx start
sleep 2
#3、等待2秒后再次获取一次Nginx状态
counter=`ps -C nginx --no-header | wc -l`
#4、再次进行判断,如Nginx还不存活则停止Keepalived,让地址进行漂移
if [ $counter -eq 0 ]; then
service keepalived stop
fi
fi
EOF
chmod +x /etc/keepalived/check_nginx.sh
启动服务
#主备
systemctl daemon-reload
systemctl enable nginx keepalived
systemctl start nginx
systemctl start keepalived
#测试通过VIP访问mysql
mysql -uroot -h192.168.40.199 -P13306 -p
#输入密码:123456可以访问MySQL。
#模拟xianchaomaster1、xianchaomaster2、xianchaomaster3机器任意两个mysql被停掉,基于VIP均可访问mysql
相关笔记
- Database/MySQL入门 - MySQL基础入门
- Database/源码安装redis-6.2.6-centos7 - Redis安装部署