MySQL主从搭建

参考:https://www.cnblogs.com/Sol-wang/p/17122439.html

规划

1.机器规划

# 单台虚拟机 
192.168.239.128:3306 master
192.168.239.128:3307 slave1
192.168.239.128:3308 slave2

2.目录规划

# 相关目录
/usr            # 存放系统自带的软件包 通过系统包管理器(如 yum、apt)安装的软件
/usr/local      # 存放本地编译安装的软件 管理员手动编译安装的程序
/usr/local/src  # 存放本地编译安装的软件源码 软件包和源代码的存储位置
/opt            # 存放第三方打包的独立软件 例如 mysql-xxx.tar.xz 解压后的软件
​
# 规划
/usr/local/src  # 压缩包mysql-xxx.tar.xz
/usr/local/     # 解压包
​
/etc/mysql/3306/my.cnf    # 配置文件
/data/3306/data/          # 数据文件 

清理环境

1.停止 MySQL 服务

# 查找并停止所有 MySQL 服务
ps -ef | grep mysql
​
# 如果有 systemd 服务
systemctl stop mysqld  
​
# 强制终止 MySQL 进程
pkill mysql 

2.删除所有 MySQL 相关目录

find / -name mysql
find / -name mysqld
​
# 删除找到的所有 mysql 目录和文件
rm -rf /usr/local/mysql
rm -rf /home/yungu/mysql-8.0.24-linux-glibc2.12-x86_64
rm -rf /usr/lib64/mysql
rm -rf /usr/share/mysql
rm -f /etc/init.d/mysqld
​
# 删除服务相关文件
rm -f /run/lock/subsys/mysql
​
# 删除数据相关文件
rm -rf /data

3.删除配置文件

find / -name my*.cnf
​
# 删除可能的配置文件
rm -f /etc/my.cnf
rm -f /etc/my.cnf.d/*
rm -rf /etc/my.cnf.d/
rm -f /etc/systemd/system/mysqld.service

4.删除用户和组

# 删除 mysql 用户和组(如果存在)
id mysql >/dev/null 2>&1 && userdel mysql
getent group mysql >/dev/null 2>&1 && groupdel mysql

# 1. 检查 mysql 用户是否存在
# 2. 如果存在(id 命令成功)→ 删除该用户
# 3. 如果不存在(id 命令失败)→ 不执行删除操作

5.删除环境变量

vim /etc/profile
​
# 重新加载 /etc/profile
source /etc/profile
​
# 重新加载 systemd 配置
systemctl daemon-reload

  

下载安装包

1.地址

https://dev.mysql.com/downloads/mysql/

2.选择

Product Version: 8.4.6 LTS
​
Operating System: Linux-Generic
​
OS Version: Linux-Generic(glibc 2.17)(x86,64-bit)
​
CPU架构:x86, 64-bit
​
包类型:Compressed TAR Archive
​
Archived Versions : 存档版本
​
Innovation Release  创新版
LTS Release         长期支持版  (Long Term Support)

3.mysql版本

GA (General Availability):正式发布版,生产可用
RC (Release Candidate):发布候选版,接近正式版
DMR (Development Milestone Release):开发里程碑版本
Beta:测试版
Alpha:早期测试版

4.glibc版本

# 查看 CentOS 7.9 系统中的 glibc 版本
# ldd 是 Linux 系统中的一个命令行工具,用于显示动态链接库的依赖关系。
ldd --version
​
#使用 rpm 查询 glibc 版本
rpm -q glibc

5.下载后上传服务器

yum install -y lrzsz
​
cd /usr/local/src
​
#上传
rz
​
#两个文件
mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz      # MySQL 软件包
mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz.asc  # GPG 签名文件 用不到
​
#md5验证
#计算文件的 MD5 值
md5sum mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz  # 计算结果和官方给的值相同即正确
​
MD5: 51b6576dedc974e255461cbefa246785   
Size: 869.6M

6.图片

image-20250820135354027

 

 

安装

1.创建用户组和用户

#添加Linux组(可选)
groupadd mysql
​
#添加linux组员 即用户 (可选)
useradd -r -g mysql -s /bin/false mysql

2.解压缩

#解压
tar xvf /usr/local/src/mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz  -C  /usr/local/
 
#软链接
#必须全路径
ln -s  /usr/local/mysql-8.4.6-linux-glibc2.17-x86_64  /usr/local/mysql

3.环境变量

# 修改环境变量
vi /etc/profile 
末尾加
  export PATH=/usr/local/mysql/bin:$PATH
  
# 测试环境变量
mysql -V

4.创建数据目录

# 创建数据目录
mkdir -p /data/330{6..8}/data
​
# 创建日志目录
#注意: 日志和数据分开存储
mkdir -p /data/330{6..8}/log
​
# 授权
chown -R mysql.mysql /data/*

5.创建配置文件

# 创建配置文件
vi /etc/mysql/3306/my.cnf
vi /etc/mysql/3307/my.cnf
vi /etc/mysql/3308/my.cnf

  

[mysqld]                                  # MySQL 服务端配置
# 基本路径配置
basedir=/usr/local/mysql                       # MySQL 安装目录
datadir=/data/3306/data                        # 数据文件存储目录
socket=/tmp/mysql3306.sock                     # Unix socket 文件路径(本地连接可使用)
​
# 网络配置
server_id=51                                   # 服务器唯一标识
port=3306                                      # TCP/IP 连接使用的端口号
​
# 日志配置
log_error=/data/3306/log/mysql-err.log         # 错误日志的存储位置
log_bin=/data/3306/log/mysql-bin               # 二进制日志文件目录的存储位置
binlog_format=row                              # 设置二进制日志格式 ROW 模式记录每行数据的变化
slow_query_log=1                               # 慢查询日志开关:1启用
slow_query_log_file=/data/3306/log/slow.log    # 慢查询日志文件的存储位置
general_log=on                                 # 普通日志开关:on启用
general_log_file=/data/3306/log/genlog         # 普通日志文件的存储位置
​
# 安全配置
secure-file-priv=/tmp        # 限制文件操作的目录LOAD DATA INFILE 和 SELECT ... INTO OUTFILE
​
# 用户配置(重要)
user=mysql                   # 指定 MySQL 服务运行的系统用户(限制mysql进程对系统的访问权限)
​
# GTID 配置
gtid-mode=off                             # 关闭 GTID(全局事务标识)不使用 GTID 复制模式
enforce-gtid-consistency=off
​
[mysql]                                   # MySQL 客户端配置
socket=/tmp/mysql3306.sock
prompt=db01                               # 设置 MySQL 客户端命令行提示符为 "db01"

  

进程1

[mysqld] 
basedir=/usr/local/mysql 
datadir=/data/3306/data 
socket=/tmp/mysql3306.sock
server_id=51 
port=3306 
log_error=/data/3306/log/mysql-err.log 
log_bin=/data/3306/log/mysql-bin 
slow_query_log=1 
slow_query_log_file=/data/3306/log/slow.log
general_log=on                                 
general_log_file=/data/3306/log/genlog
secure-file-priv=/tmp 
user=mysql 
gtid-mode=off
enforce-gtid-consistency=off
[mysql]                  
socket=/tmp/mysql3306.sock
prompt=db01 

进程2

[mysqld] 
basedir=/usr/local/mysql 
datadir=/data/3307/data 
socket=/tmp/mysql3307.sock
server_id=52 
port=3307 
log_error=/data/3307/log/mysql-err.log 
log_bin=/data/3307/log/mysql-bin 
slow_query_log=1 
slow_query_log_file=/data/3307/log/slow.log
general_log=on                                 
general_log_file=/data/3307/log/genlog
secure-file-priv=/tmp 
user=mysql 
gtid-mode=off
enforce-gtid-consistency=off
[mysql]                  
socket=/tmp/mysql3307.sock
prompt=db02 

进程3

[mysqld] 
basedir=/usr/local/mysql 
datadir=/data/3308/data 
socket=/tmp/mysql3308.sock
server_id=53 
port=3308 
log_error=/data/3308/log/mysql-err.log 
log_bin=/data/3308/log/mysql-bin 
slow_query_log=1 
slow_query_log_file=/data/3308/log/slow.log
general_log=on                                 
general_log_file=/data/3308/log/genlog
secure-file-priv=/tmp 
user=mysql 
gtid-mode=off
enforce-gtid-consistency=off
[mysql]                  
socket=/tmp/mysql3308.sock
prompt=db03

6.初始化

# 初始化 MySQL 实例 
# --defaults-file:指定配置文件路径
# --initialize-insecure:初始化数据库,不生成临时 root 密码
# 1.创建数据目录结构 2.初始化系统表 3.创建默认用户(root 用户无密码)
​
mysqld --defaults-file=/etc/mysql/3306/my.cnf --initialize-insecure
mysqld --defaults-file=/etc/mysql/3307/my.cnf --initialize-insecure
mysqld --defaults-file=/etc/mysql/3308/my.cnf --initialize-insecure

7.启动

# 启动方式一
# 安全启动 MySQL 服务
# --defaults-file:指定配置文件路径
# &:后台运行
mysqld_safe --defaults-file=/etc/mysql/3306/my.cnf &
mysqld_safe --defaults-file=/etc/mysql/3306/my.cnf &
mysqld_safe --defaults-file=/etc/mysql/3306/my.cnf &
​
# 验证
netstat -tulnp|grep mysqld
​
# 启动方式二
# 通过系统服务脚本管理 传统的 init.d 方式
/etc/init.d/mysqld restart
​
# 启动方式三 : systemd方式
# 使用系统服务管理(稳定)
systemctl enable mysqld
systemctl start mysqld
​
# 启动方式四 : SYS-V启动方式
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
service mysqld restart
​
# 启动方式四
./usr/local/mysql.server start

8.本地连接

# 通过 socket 连接 MySQL
# -S:指定 socket 文件路径
# mysql.sock:特定实例的 socket 文件
mysql -S /tmp/mysql3306.sock
mysql -S /tmp/mysql3307.sock
mysql -S /tmp/mysql3308.sock

  

日志

错误日志(error log):  记录 启动故障 主从故障 死锁数据库hang,堆栈信息
二进制日志(binlog):     记录了MySQL 发生过的修改的操作的日志。除了show select。
慢日志(slow log):      记录MySQL工作中,运行较慢的语句。
普通日志(general_log):  记录MySQL运行期间,所有的所作语句
​
# 错误日志设置
#查询错误日志记录级别 
show variables like '%log_error%';
#设置日志记录级别
set global log_error_verbosity=3;
​
# 慢日志设置
-- 查看慢查询日志状态
SHOW VARIABLES LIKE 'slow_query_log%';
-- 查看慢查询相关参数
SHOW VARIABLES LIKE '%slow%';
-- 查看慢查询统计
SHOW GLOBAL STATUS LIKE '%slow%';
#开关: 
[mysqld]
slow_query_log=1                               # 开关:1启用
slow_query_log_file=/data/3306/log/slow.log    # 指定慢查询日志文件的存储位置
#维度: 
[mysqld]
set global slow_query_log=1                    # 开启慢查询日志
set global long_query_time=1.0                 # 设置慢查询阈值 1秒 
set global log_queries_not_using_indexes=1     # 即使查询执行很快,但没有使用索引也会被记录
set global log_throttle_queries_not_using_indexes=1000;  #每分钟最多记录 1000 条未使用索引的查询,防止日志文件过大
 

高可用架构(Complete HA Architectures)

1.MHA+ProxySQL

综合成本与稳定性

MHA(Master High Availability)基于传统主从复制的外置高可用工具(Perl开发),核心解决主库故障时的自动切换问题,需配合半同步/异步复制使用。

ProxySQL 是一个高性能的 MySQL 代理,支持动态查询路由、负载均衡、连接池等功能,非常适用于读写分离。

应用程序连接 ProxySQL,ProxySQL 根据 SQL 语句的类型,自动将写操作路由到主库,将读操作分配给从库。

 

2.InnoDB Cluster + MySQL Router

金融级强一致

InnoDB Cluster确实是基于MySQL Group Replication(MGR)`构建的。

对于三甲医院这类对数据一致性和系统稳定性要求极高的场景,Single-Primary 模式提供了更可靠和可维护的解决方案。

MGR(MySQL Group Replication):MySQL内核集成的分布式强一致方案(C/C++开发),通过组复制协议实现多节点数据实时同步与自愈,是官方新一代高可用架构基础。

MySQL Router : MySQL 官方提供的轻量级代理,专为 MySQL InnoDB Cluster读写分离 设计,能够实现自动路由和高可用性支持。

应用层
   ↓
MySQL Server 层
   ↓
Group Communication System (GCS) 层
   ↓
XCom 层 (Paxos算法)

2.1主机规划

IP HOSTNAME ROLE soft
127.0.0.1 master mic-master mysql、mysqlsh
127.0.0.1 slave1 mic-slave1 mysql、mysqlsh
127.0.0.1 slave2 mic-slave2 mysql、mysqlsh
127.0.0.1 manager mic-manager mysqlsh、mysql-router

 

2.2安装包

mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz
mysql-router-8.4.6-linux-glibc2.17-x86_64.tar.xz
mysql-shell-8.4.6-linux-glibc2.17-x86-64bit.tar.gz

  

image

 

2.3解压缩

#解压缩
# 第一步:解压 xz 压缩
xz  -d /usr/local/src/mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz
# 第二步:解压 tar 归档
tar xf /usr/local/src/mysql-8.4.6-linux-glibc2.17-x86_64.tar  -C  /usr/local/

xz  -d /usr/local/src/mysql-router-8.4.6-linux-glibc2.17-x86_64.tar.xz
tar xf /usr/local/src/mysql-router-8.4.6-linux-glibc2.17-x86_64.tar    -C  /usr/local/

tar xf /usr/local/src/mysql-shell-8.4.6-linux-glibc2.17-x86-64bit.tar.gz  -C  /usr/local/

#软链接
ln -s  /usr/local/mysql-8.4.6-linux-glibc2.17-x86_64/  /usr/local/mysql
ln -s  /usr/local/mysql-shell-8.4.6-linux-glibc2.17-x86-64bit/  /usr/local/mysqlsh 
ln -s  /usr/local/mysql-router-8.4.6-linux-glibc2.17-x86_64/  /usr/local/mysql-router

2.4域名

# 添加域名
vim /etc/hosts 

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 master slave1 slave2 manage
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# 测试主机名解析
ping master
nslookup master
getent hosts master

# 如果未生效
# 重启网络服务(某些发行版)
sudo systemctl restart network

2.5 主节点 my.cnf

vim /etc/mysql/3306/my.cnf

 

[mysqld]                                  # MySQL 服务端配置
# 基本路径配置
basedir=/usr/local/mysql                       # MySQL 安装目录
datadir=/data/3306/data                        # 数据文件存储目录
socket=/tmp/mysql3306.sock                     # Unix socket 文件路径(本地连接可使用)

# 网络配置
server_id=51                                   # 服务器唯一标识
port=3306                                      # TCP/IP 连接使用的端口号

# 日志配置
log_error=/data/3306/log/mysql-err.log         # 错误日志的存储位置
log_bin=/data/3306/log/mysql-bin               # 二进制日志文件目录的存储位置
binlog_format=row                              # 设置二进制日志格式 ROW 模式记录每行数据的变化
slow_query_log=1                               # 慢查询日志开关:1启用
slow_query_log_file=/data/3306/log/slow.log    # 慢查询日志文件的存储位置
general_log=on                                 # 普通日志开关:on启用
general_log_file=/data/3306/log/genlog         # 普通日志文件的存储位置

# 安全配置
secure-file-priv=/tmp                          # 限制文件操作的目录LOAD DATA INFILE 和 SELECT ... INTO OUTFILE

# 用户配置(重要)
user=mysql                                     # 指定 MySQL 服务运行的系统用户(限制mysql进程对系统的访问权限)

# GTID 配置
gtid-mode=ON                                  # 启用 GTID(全局事务标识)复制模式 
enforce-gtid-consistency=ON                   # 强制 GTID 一致性

# 复制
#master_info_repository=TABLE                  # 将主库信息存储在表中而非文件。 8.3已移除
#relay_log_info_repository=TABLE               # 将中继日志信息存储在表中。8.3已移除
log_slave_updates=ON                          # 从服务器会记录它执行的更新到自己的二进制日志中。

# Group Replication 配置
loose-group_replication_group_name="707df9a6-e6af-4140-bbbd-ccae9f7138f6"      # UUID 组复制群组名称。
loose-group_replication_start_on_boot=OFF                                      # 启动时不自动启动组复制。
loose-group_replication_local_address="master:3306"                            # 本地用于组复制通信的地址和端口。
loose-group_replication_group_seeds="master:3306,slave1:3307,slave2:3308"      # 种子成员列表。
loose-group_replication_bootstrap_group=OFF                                    # 不引导新组。
loose-group_replication_ip_whitelist="master,slave1,slave2,manager"            # 白名单 IP 或主机名。

# X Plugin 保持启用但指定端口
mysqlx_port=33060
mysqlx_bind_address=0.0.0.0

[mysql]                                   # MySQL 客户端配置
socket=/tmp/mysql3306.sock
prompt=db01                               # 设置 MySQL 客户端命令行提示符为 "db01"

2.6 从节点 my.cnf

[mysqld]                                  
basedir=/usr/local/mysql                       
datadir=/data/3307/data                       
socket=/tmp/mysql3307.sock                     

server_id=52                                 # 差异                     
port=3307                                      

log_error=/data/3307/log/mysql-err.log         
log_bin=/data/3307/log/mysql-bin               
binlog_format=row                              
slow_query_log=1                               
slow_query_log_file=/data/3307/log/slow.log    
general_log=on                                 
general_log_file=/data/3307/log/genlog        

secure-file-priv=/tmp                          

user=mysql                                     

gtid-mode=ON                                 
enforce-gtid-consistency=ON                   
             
log_slave_updates=ON                         

loose-group_replication_group_name="397752c1-be40-42bb-ba45-216f1407d950"   # 差异 
loose-group_replication_start_on_boot=OFF                                      
loose-group_replication_local_address="slave1:3307"                        # 差异                 
loose-group_replication_group_seeds="master:3306,slave1:3307,slave2:3308"  
loose-group_replication_bootstrap_group=OFF                                    
loose-group_replication_ip_whitelist="master,slave1,slave2,manager"            
loose-group_replication_allow_local_disjoint_gtids_join=ON     # 从节点特有配置,允许GTID不连续的节点加入复制组

mysqlx_port=33070
mysqlx_bind_address=0.0.0.0

[mysql]                                   
socket=/tmp/mysql3307.sock
prompt=db02                               

  

[mysqld]                                  
basedir=/usr/local/mysql                       
datadir=/data/3308/data                       
socket=/tmp/mysql3308.sock                     

server_id=53                                                 
port=3308                                      

log_error=/data/3308/log/mysql-err.log         
log_bin=/data/3308/log/mysql-bin               
binlog_format=row                              
slow_query_log=1                               
slow_query_log_file=/data/3308/log/slow.log    
general_log=on                                 
general_log_file=/data/3308/log/genlog        

secure-file-priv=/tmp                          

user=mysql                                     

gtid-mode=ON                                 
enforce-gtid-consistency=ON                   
log_slave_updates=ON                         

loose-group_replication_group_name="10b74154-09a3-46d2-8060-6a1c659ac5d2"   
loose-group_replication_start_on_boot=OFF                                      
loose-group_replication_local_address="slave2:3308"                                     
loose-group_replication_group_seeds="master:3306,slave1:3307,slave2:3308"  
loose-group_replication_bootstrap_group=OFF                                    
loose-group_replication_ip_whitelist="master,slave1,slave2,manager"            
loose-group_replication_allow_local_disjoint_gtids_join=ON     

mysqlx_port=33080
mysqlx_bind_address=0.0.0.0

[mysql]                                   
socket=/tmp/mysql3308.sock
prompt=db03    

  

2.7初始化

pkill mysqld 
pkill mysqlsh
rm -rf /data/330{6~8}/data/*
rm -rf /data/330{6~8}/log/*

# 设置正确的所有者和权限
chown -R mysql:mysql /data/*
chmod -R 755 /data/*

# 使用mysql用户初始化数据库
sudo -u mysql /usr/local/mysql/bin/mysqld --defaults-file=/etc/mysql/3306/my.cnf --initialize-insecure
sudo -u mysql /usr/local/mysql/bin/mysqld --defaults-file=/etc/mysql/3307/my.cnf --initialize-insecure
sudo -u mysql /usr/local/mysql/bin/mysqld --defaults-file=/etc/mysql/3308/my.cnf --initialize-insecure

2.8启动

sudo -u mysql /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/mysql/3306/my.cnf &
sudo -u mysql /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/mysql/3307/my.cnf &
sudo -u mysql /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/mysql/3308/my.cnf &

 

# 验证
netstat -tulnp | grep mysqld
tail -f /data/3306/log/mysql-err.log

2.9本地连接

# 通过 socket 连接 MySQL 
# 首次无密码连接
 sudo -u mysql /usr/local/mysql/bin/mysql -S /tmp/mysql3306.sock
 sudo -u mysql /usr/local/mysql/bin/mysql -S /tmp/mysql3307.sock
 sudo -u mysql /usr/local/mysql/bin/mysql -S /tmp/mysql3308.sock

# 设置root@'localhost'密码
 ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
 
# 再次连接
 sudo -u mysql /usr/local/mysql/bin/mysql -S /tmp/mysql3306.sock -p123456
 sudo -u mysql /usr/local/mysql/bin/mysql -S /tmp/mysql3307.sock -p123456
 sudo -u mysql /usr/local/mysql/bin/mysql -S /tmp/mysql3308.sock -p123456

  

2.10创建集群账户

# 以 root 用户 通过 socket 连接 MySQL
/usr/local/mysql/bin/mysql -S /tmp/mysql3306.sock -p123456
/usr/local/mysql/bin/mysql -S /tmp/mysql3307.sock -p123456
/usr/local/mysql/bin/mysql -S /tmp/mysql3308.sock -p123456


/**
 为每一个mysql实例创建一个专门用于集群管理的新用户 clusteradmin
 更安全的做法 只授予必要的最小权限 测试可以不设置
 
*/
CREATE USER 'clusteradmin'@'%' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'clusteradmin'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

  

2.11 MySQL Shell 组建管理集群

什么是 MySQL Shell? MySQL 官方提供的新一代命令行客户端工具 支持多种编程语言模式:JavaScript、Python、SQL 专为 MySQL 8.0+ 设计,支持现代 MySQL 功能 提供 DBA 管理和开发功能

doc: https://dev.mysql.com/doc/mysql-shell/8.4/en/mysqlsh.html

 

2.12 初始化配置集群(了解)

# 1.mysql shell 工具分别连接3个MySQL实例
# 以 root 用户身份运行 MySQL Shell 并连接到 MySQL 实例 (3306)  【TCP/IP 协议】
/usr/local/mysqlsh/bin/mysqlsh --uri=root@localhost:3306
# 以 clusteradmin 用户身份运行
/usr/local/mysqlsh/bin/mysqlsh --uri=clusteradmin@localhost:3306

# 以 root 用户身份运行 MySQL Shell 并连接到 MySQL 实例 (3306)  【指定 socket 连接】
# 使用 Unix Socket 文件直接连接,绕过网络协议栈
/usr/local/mysqlsh/bin/mysqlsh -S /tmp/mysql3306.sock -p123456
/usr/local/mysqlsh/bin/mysqlsh -u root -h localhost -P 3306 -S /tmp/mysql3306.sock -p123456

# 在 MySQL Shell 中切换到 JavaScript 模式
\js     
# 查看当前状态
\status
# 查看 DBA 模块帮助
dba.help()
# 退出
\exit

# 2. 初始化配置集群实例
dba.configureInstance('clusteradmin@localhost:3306')
    这个命令会检查并自动配置实例以满足 InnoDB Cluster 的要求
    包括:
    创建必要的用户和权限
    配置 GTID
    设置二进制日志
    配置其他集群所需的参数
    
# 3. 创建 InnoDB Cluster
var cluster = dba.createCluster('myCluster')

# 4. 检查实例状态
dba.checkInstanceConfiguration("clusteradmin@localhost:3306");
	
# 5. 查看集群状态(创建集群后)
cluster.status()

# 6. 集群结构信息描述 
cluster.describe()

# 7. 集群状态总览 
cluster.status() 

# 8. 查看集群名字 
dba.getCluster(); 

# 9. 查看router信息 
cluster.listRouters()

# 10.将实例重新加入到集群 如果实例离开集群,比如丢失连接,并且没有自动重新加入集群。
Cluster.rejoinInstance() 

# 11.在线切换primary 实例
cluster.setPrimaryInstance('clusteradmin@slave1:3306')

  

2.13 初始化配置集群(实战)

3306实例-主节点
[root@localhost ~]# /usr/local/mysqlsh/bin/mysqlsh --uri=clusteradmin@master:3306
 MySQL  localhost:3308 ssl  SQL > \js
 MySQL  localhost:3308 ssl  JS > dba.configureInstance('clusteradmin@master:3306')          # 初始化配置
 MySQL  localhost:3308 ssl  JS > dba.checkInstanceConfiguration("clusteradmin@master:3306");
 MySQL  localhost:3308 ssl  JS > \q
3307实例-从节点
[root@localhost ~]# /usr/local/mysqlsh/bin/mysqlsh --uri=clusteradmin@slave1:3307
 MySQL  localhost:3308 ssl  SQL > \js
 MySQL  localhost:3308 ssl  JS > dba.configureInstance('clusteradmin@slave1:3307')           # 初始化配置
 MySQL  localhost:3308 ssl  JS > dba.checkInstanceConfiguration("clusteradmin@slave1:3307");
 MySQL  localhost:3308 ssl  JS > \q
3308实例-从节点
[root@localhost ~]# /usr/local/mysqlsh/bin/mysqlsh --uri=clusteradmin@slave2:3308
 MySQL  localhost:3308 ssl  SQL > \js
 MySQL  localhost:3308 ssl  JS > dba.configureInstance('clusteradmin@slave2:3308')          # 初始化配置
 MySQL  localhost:3308 ssl  JS > dba.checkInstanceConfiguration("clusteradmin@slave2:3308");
 MySQL  localhost:3308 ssl  JS > \q

2.14 创建集群并添加节点

添加主节点
#3306实例
[root@localhost ~]# /usr/local/mysqlsh/bin/mysqlsh --uri=clusteradmin@master:3306
 MySQL  localhost:3308 ssl  SQL > \js
 MySQL  localhost:3308 ssl  JS > var cluster = dba.createCluster('myCluster')                # 创建集群
 MySQL  localhost:3308 ssl  JS > cluster.status()
 MySQL  localhost:3308 ssl  JS > \q
添加slave1\slave2节点
#3307实例
[root@localhost ~]# /usr/local/mysqlsh/bin/mysqlsh --uri=clusteradmin@localhost:3307
 MySQL  localhost:3308 ssl  SQL > \js
 MySQL  localhost:3308 ssl  JS > shell.connect('clusteradmin@master:3306');            # 连接主节点
 MySQL  localhost:3308 ssl  JS > var cluster = dba.getCluster('myCluster')             # 获取集群实例
 MySQL  localhost:3308 ssl  JS > cluster.addInstance('clusteradmin@slave1:3307');      # 添加从节点
 MySQL  localhost:3308 ssl  JS > cluster.addInstance('clusteradmin@slave2:3308');      # 添加从节点
 MySQL  localhost:3308 ssl  JS > cluster.status()

image

 

2.15 MySQL Router 集群路由

doc: https://dev.mysql.com/doc/mysql-router/8.4/en/

初始化配置
# 注册router到集群,生成myrouter目录, 并生成启动程序和配置文件.
/usr/local/mysql-router/bin/mysqlrouter --bootstrap clusteradmin@master:3306 -d /etc/mysqlrouter --user=root

各参数含义:
/usr/local/mysql-router/bin/mysqlrouter:MySQL Router可执行程序
    --bootstrap clusteradmin@master:3306:
    --bootstrap:引导模式,自动配置Router
clusteradmin@master:3306:连接到MySQL集群的账户和地址
	clusteradmin:用户名
	master:主机名
	3306:端口号
-d /etc/mysqlrouter:
	-d:指定工作目录
myrouter:创建的目录名,包含配置文件和运行时数据
	--user=root:指定MySQL Router运行时使用的系统用户
	
/**

After this MySQL Router has been started with the generated configuration

    $ /usr/local/mysql-router/bin/mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf

InnoDB Cluster 'myCluster' can be reached by connecting to:

## MySQL Classic protocol                            # 传统MySQL协议

- Read/Write Connections: localhost:6446             # 读写端口
- Read/Only Connections:  localhost:6447             # 只读端口
- Read/Write Split Connections: localhost:6450       # 读写分离端口 自动路由,写操作到Primary,读操作到Secondary

## MySQL X protocol                                  # X协议

- Read/Write Connections: localhost:6448             
- Read/Only Connections:  localhost:6449        

*/
启动
# 启动 router
/etc/mysqlrouter/start.sh
验证
# 验证连接 router

# 1.本机mysql-shell连接
 /usr/local/mysqlsh/bin/mysqlsh --uri root@localhost:6446
 
# 2.本机mysql连接
 /usr/local/mysql/bin/mysql -h 127.0.0.1 -u root -P 6446 -p
高可用
MySQL Router进程确实可能会挂掉,而且在生产环境中确实需要考虑高可用性。

MySQL Router高可用方案:

# 方案一:负载均衡器 + 多个Router实例

# 部署架构
Load Balancer (HAProxy/Nginx/F5)
    ├── Router Node 1 (port 6446/6447)
    ├── Router Node 2 (port 6446/6447)
    └── Router Node 3 (port 6446/6447)

# 方案二:Keepalived + 多个Router实例

# 主Router节点
VIP: 192.168.1.100
Router1: 192.168.1.101
Router2: 192.168.1.102

应用服务器
    ↓
负载均衡器 (HAProxy/Nginx)
    ↓
多个MySQL Router实例
    ↓
MySQL InnoDB Cluster

  

image

 

image

2.16 验证cluster集群

1.登陆后,新建一个表,往里面写进数据,查看从节点数据会不会同步;

2.关闭master的mysql服务,route将主节点自动切换到slave1,slave1从只读变为可读写,再重新启动 master mysql后,master变为只读模式。 (验证MySQL InnoDB Cluster的自动故障转移和恢复机制。)

3. 验证读写分离功能
验证同步
# 通过MySQL Router的读写端口连接
[root@localhost ~]# /usr/local/mysql/bin/mysql -h master -u root -P 6446  -p
-- 选择或创建测试数据库
CREATE DATABASE IF NOT EXISTS test_db;
USE test_db;

-- 创建测试表
CREATE TABLE test_table (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入测试数据
INSERT INTO test_table (name) VALUES 
('Test Record 1'),
('Test Record 2'),
('Test Record 3');

-- 提交事务(如果需要)
COMMIT;

-- 查看插入的数据
SELECT * FROM test_table;
# 连接到从节点验证同步

# 通过MySQL Router的只读端口连接
[root@localhost ~]# mysql -h localhost -P 6447 -u clusteradmin -p

-- 使用相同数据库
USE test_db;

-- 查看数据是否同步
SELECT * FROM test_table;

-- 查看当前节点状态
SELECT @@server_id, @@hostname, @@port;
SELECT * FROM performance_schema.replication_group_members;
监控主
# 实时监控同步状态(主节点)

-- 确认当前连接的是主节点
SELECT @@server_id, @@hostname, @@port;

-- 查看集群状态 Group Replication
SELECT * FROM performance_schema.replication_group_members;

-- 查看复制延迟(如果有的话)
SELECT * FROM performance_schema.replication_applier_status;


-- 查看事务应用情况
SELECT 
    CHANNEL_NAME,
    VIEW_ID,
    MEMBER_ID,
    COUNT_TRANSACTIONS_IN_QUEUE,
    COUNT_TRANSACTIONS_CHECKED,
    COUNT_CONFLICTS_DETECTED,
    COUNT_TRANSACTIONS_ROWS_VALIDATING
FROM performance_schema.replication_group_member_stats;

-- 检查是否有错误
SHOW REPLICA STATUS\G

-- 检查错误日志
SHOW ENGINE INNODB STATUS\G

-- 查看read_only状态 (0:可读写模式 1:只读模式)
SELECT @@super_read_only as super_read_only;

-- 查看所有只读相关变量
SHOW VARIABLES LIKE '%read_only%';

-- 查看当前用户权限
SHOW GRANTS;
验证故障转移
1. 初始状态
Master (可读写): master:3306
Slave1 (只读): slave1:3307
Slave2 (只读): slave2:3308
MySQL Router: 读写端口6446 -> master, 只读端口6447 -> slaves

2. 关闭Master MySQL服务
[root@localhost ~]# /usr/local/mysql/bin/mysqladmin -u root -p -P 3306 -h master shutdown

Group Replication检测到故障:
其他节点检测到Master节点失联
触发选举机制选择新的Primary节点
Slave1被选举为新的Primary节点

3. 新状态
Master (原Slave1, 现在可读写): slave1:3307
Slave1 (原Master, 已关闭): master:3306
Slave2 (只读): slave2:3308
MySQL Router: 读写端口6446 -> slave1, 只读端口6447 -> slave2

4. 重新启动原Master节点
[root@localhost ~]# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/mysql/3306/my.cnf &

原Master节点启动后自动重新加入Group Replication
但是角色变为Secondary(只读)
数据会自动同步到最新状态

5. 自动恢复过程
Master (新Primary): slave1:3307 (可读写)
Slave1 (原Master): master:3306 (只读)
Slave2: slave2:3308 (只读)
MySQL Router: 读写端口6446 -> slave1, 只读端口6447 -> master,slave2

2.17 遇到问题

 # 清空集群
 [root@localhost ~]# /usr/local/mysqlsh/bin/mysqlsh --uri=clusteradmin@master:3306
 MySQL  localhost:3308 ssl  SQL > \js
 MySQL  localhost:3308 ssl  SQL > shell.connect('clusteradmin@master:3306');      # 连接到集群        
 MySQL  localhost:3308 ssl  SQL > var cluster = dba.getCluster('myCluster')       # 获取集群对象
 MySQL  localhost:3308 ssl  SQL > cluster.removeInstance('slave1:3307')           # 移除 slave1 实例
 
 MySQL  localhost:3308 ssl  SQL > dba.dropMetadataSchema()                        # 清理损坏或不一致的集群配置
 
 
cluster.removeInstance() 的作用是:
1.从集群中移除指定节点:
	停止该节点的 Group Replication
	将该节点从集群成员列表中删除
	该节点不再参与集群的数据同步
2.不影响被移除节点的数据:
	节点上的数据不会被自动删除
	节点仍然可以独立运行(作为单机MySQL)
3.集群继续运行:
	剩余节点继续组成集群
	如果移除的是主节点,集群会自动选举新的主节点
注意事项:
	不能移除当前连接的实例(即不能移除自己)
	需要确保集群有足够多的节点保持法定人数
	建议在维护窗口期间执行此操作
特注:
    已移除的InnoDB集群无法重新添加到InnoDB ClusterSet部署中。
    如果想再次在该部署中使用服务器实例,需要使用它们重新设置一个新的集群。
    
dba.dropMetadataSchema() 命令的作用是删除 MySQL Shell 的元数据模式(metadata schema)。
具体作用:
1.删除元数据Schema
	删除名为 mysql_innodb_cluster_metadata 的数据库
	这个schema存储了InnoDB集群的配置和元数据信息
2.清除集群配置信息
	删除集群的拓扑结构信息
	清除实例角色(主节点/从节点)信息
	移除集群成员列表
	删除集群配置参数
警告:
	此操作不可逆
	会完全删除集群的配置信息
	不影响用户数据,但会影响集群功能
	执行前需要确保已经备份重要配置

 网络拓扑

三台mysql连接交换机,交换机连接路由器

MySQL Server 1  MySQL Server 2  MySQL Server 3
       |               |               |
       --------交换机(Switch)----------
                       |
                  路由器(Router)
                       |
                    外部网络

延迟差异 局域网内交换机转发:微秒级延迟 路由器转发:毫秒级延迟

MySQL1 → 交换机 → MySQL2
   (局域网内部通信)

 

 
posted @ 2025-08-20 17:54  Peter.Jones  阅读(3)  评论(0)    收藏  举报