MySQL集群搭建

本文为个人学习笔记整理,仅供交流参考,非专业教学资料,内容请自行甄别。

文章目录


概述

无论是Redis,Rabbit MQ还是Kafka等中间件,在生产环境下,都不太可能单机部署,而是以集群的形式部署。这也是面试中经常会问到的问题,为什么MySQL需要集群部署?(或者说常见中间件为什么需要集群部署)大概有以下几点:

  • 防止单机模式下的故障,这是最主要的,如果只部署一台服务器,那么出现问题就是100%不可用。而集群的数据是在多实例之间进行同步,并且集群的服务器可以跨地区部署。
  • 突破性能瓶颈,单机模式下,无论是读还是写,都会在同一台服务器上。无法践行读写分离 + 负载均衡的设计思想。
  • 突破存储瓶颈,单台服务器能存储的数据量也是有限的,并且随着数据量的增长,查询效率也会大大降低。而集群可以通过分片,将数据存储在不同的服务器上。

本篇将记录MySQL集群的搭建。


一、搭建MySQL集群

首先需要两台服务器,作为一主一从的架构。并且各自要安装好MySQL,这里安装8.0的版本,并且我的centos是9版本,版本不同会有差异!如果版本不一样,请自行查阅其他资料

MySQL 官方提供了适配 RHEL 9/CentOS 9 的仓库包,执行以下命令下载:

bash 复制代码
wget https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm

安装仓库配置包:

bash 复制代码
dnf install -y mysql80-community-release-el9-1.noarch.rpm

执行完上述的命令,在/etc/yum.repos.d/下会产生下图的三个.repo文件:

然后导入 MySQL GPG 密钥,解决 EL9 的密钥验证问题:

bash 复制代码
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023

安装MySQL服务器:

bash 复制代码
dnf install -y mysql-community-server

启动并初始化 MySQL 服务,CentOS 9 使用systemd管理服务:

bash 复制代码
systemctl start mysqld

设置开机自启:

bash 复制代码
systemctl enable mysqld

查看MySQL服务器状态,active (running)为成功:

bash 复制代码
systemctl status mysqld

MySQL 8.0 安装后会在/var/log/mysqld.log生成临时密码,查看临时密码:

bash 复制代码
grep 'temporary password' /var/log/mysqld.log

登录MySQL并修改临时密码:

bash 复制代码
mysql -uroot -p

修改 root 用户密码,MySQL 8.0 默认启用密码强度策略(至少 8 位,包含大小写字母、数字、特殊字符):

sql 复制代码
ALTER USER 'root'@'localhost' IDENTIFIED BY '你自己的密码';
FLUSH PRIVILEGES;

配置 MySQL 远程访问:

sql 复制代码
CREATE USER 'root'@'%' IDENTIFIED BY '你自己的密码';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

开放端口,或者直接禁用掉防火墙:

bash 复制代码
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload

关闭 SELinux,如果是临时关闭,直接执行以下命令:

bash 复制代码
setenforce 0

如果永久关闭,则编辑/etc/selinux/config,将SELINUX=enforcing改为SELINUX=disabled,然后保存退出,并且重启服务器,这里的服务器指的是Linux服务器,不是MySQL服务器:

bash 复制代码
reboot

服务器重启完成后,可执行以下命令确认 SELinux 已永久关闭,输出 Disabled 即表示配置生效。

bash 复制代码
getenforce

验证安装成果:

bash 复制代码
mysql -V

这样就可以用远程连接工具连接了,但是MySQL 8.0 默认使用的caching_sha2_password认证插件,我这里的navicat版本比较低,还需要进行额外的设置:

sql 复制代码
-- 针对远程访问的root用户(@'%'对应任意IP)
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '你的密码';

-- 若本地也需要适配,补充修改localhost的root用户
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';

-- 刷新权限使配置生效
FLUSH PRIVILEGES;

连接成功:

二、搭建主从集群

通过以上的步骤,成功在两台服务器上搭建了MySQL服务,接下来需要组成集群

2.1、主节点配置

/etc/my.cnf.d/mysql-server.cnf中加入以下的设置:

bash 复制代码
# 开启二进制日志(主从复制核心依赖)
log_bin = /var/lib/mysql/mysql-bin
# 主节点唯一ID(不能与从节点重复)
server-id = 1
# 二进制日志格式(推荐ROW,支持更复杂的复制场景)
binlog_format = ROW
# 自动清理7天前的二进制日志(避免磁盘占满)
expire_logs_days = 7
# 允许从节点复制时记录自身的二进制日志(级联复制需开启,主从场景可选)
log_slave_updates = 1

重启MySQL服务器:

bash 复制代码
systemctl restart mysqld

在主节点终端登录 MySQL,执行 SQL 创建用于从节点复制的用户(仅允许从节点访问),并授权复制权限:

sql 复制代码
-- 创建复制用户(用户名:repl,密码:ReplPass@123,允许131访问)
CREATE USER 'repl'@'从节点' IDENTIFIED WITH mysql_native_password BY 'ReplPass@123';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'从节点';
-- 刷新权限
FLUSH PRIVILEGES;

查看主节点的binlog,其中的Binlog_Do_DBBinlog_Ignore_DB代表了需要记录binlog的库以及不需要记录binlog的库。

bash 复制代码
SHOW MASTER STATUS;

2.2、从节点配置

/etc/my.cnf中加入以下的设置:

重启 MySQL 服务使配置生效

bash 复制代码
systemctl restart mysqld

在从节点终端登录 MySQL,执行以下 SQL,替换MASTER_LOG_FILE和MASTER_LOG_POS为你在主节点记录的值

sql 复制代码
CHANGE MASTER TO
MASTER_HOST='主节点',
MASTER_USER='repl',
MASTER_PASSWORD='ReplPass@123',
MASTER_LOG_FILE='binlog.000004',  -- 主节点SHOW MASTER STATUS的File值
MASTER_LOG_POS=157;                  -- 主节点SHOW MASTER STATUS的Position值

启动主从复制

sql 复制代码
-- 启动主从复制
START SLAVE;

在从节点的 MySQL 中执行以下命令,查看复制状态:

sql 复制代码
SHOW SLAVE STATUS\G;

重点检查以下两个参数,均为Yes则表示主从配置成功:

三、测试主从同步

在主节点创建数据库:

sql 复制代码
CREATE DATABASE test_repl;

从节点执行:

sql 复制代码
SHOW DATABASES;

然后我创建了一张user表,在主库插入一条数据

从库数据同步

如果向从库插入数据,则不会同步到主库,同步的过程是单向的。所以一般都是主库负责写,从库负责同步和读。

主库写入数据后,对应的binlog也会更新

四、部分同步

在上面提到过,主节点的binlog,其中的Binlog_Do_DBBinlog_Ignore_DB代表了需要记录binlog的库以及不需要记录binlog的库,可以在my.cnf文件中进行设置,指定需要同步的库或排除不需要同步的,需要在从库配置部分同步,配置前首先STOP SLAVE;停止同步,然后systemctl stop mysqld停止服务。

编辑从库的/etc/my.cnf文件,可以进行以下的设置:

bash 复制代码
# 仅同步test_repl库的所有表(推荐用wild参数)
replicate-wild-do-table=test_repl.%
# 忽略tmp_db库的所有表
#replicate-wild-ignore-table=tmp_db.%
# 忽略所有库下以tmp_开头的表
#replicate-wild-ignore-table=%.tmp_%

然后启动服务,开启从节点同步,验证效果,首先在主节点创建一个数据库test_repl_exclude,从节点没有同步:

在主节点创建一张表address,从节点同步到了:

但是进行如下的配置:

bash 复制代码
# 忽略所有库下以address__开头的表
replicate-wild-ignore-table=%.address%

在主库的address中插入一条数据:

从节点没有同步到:

五、集群扩容同步

如果集群运行了一段时间,需要加入新的从节点,那么新的从节点在加入之后,是不会自动同步已有的数据的,新从节点需先获取主节点的全量数据备份,并记录备份时刻的 Binlog 位置(传统复制)如果数据量较小,可以通过MySQL自带的mysqldump 工具备份,在主节点执行:

sql 复制代码
mysqldump -u root -p --all-databases > backup.sql

生成的文件:

然后将其复制到从节点上,并且执行:

sql 复制代码
mysql ­u root ­p < backup.sql
相关推荐
小冷coding7 小时前
【MySQL】MySQL 插入一条数据的完整流程(InnoDB 引擎)
数据库·mysql
Elias不吃糖7 小时前
Java Lambda 表达式
java·开发语言·学习
情缘晓梦.7 小时前
C语言指针进阶
java·开发语言·算法
鲨莎分不晴8 小时前
Redis 基本指令与命令详解
数据库·redis·缓存
专注echarts研发20年8 小时前
工业级 Qt 业务窗体标杆实现・ResearchForm 类深度解析
数据库·qt·系统架构
南知意-9 小时前
IDEA 2025.3 版本安装指南(完整图文教程)
java·intellij-idea·开发工具·idea安装
码农水水10 小时前
蚂蚁Java面试被问:混沌工程在分布式系统中的应用
java·linux·开发语言·面试·职场和发展·php
海边的Kurisu10 小时前
苍穹外卖日记 | Day4 套餐模块
java·苍穹外卖
毕设源码-邱学长10 小时前
【开题答辩全过程】以 走失儿童寻找平台为例,包含答辩的问题和答案
java
周杰伦的稻香10 小时前
MySQL中常见的慢查询与优化
android·数据库·mysql