MySQL 主从复制与读写分离
·
本文基于MySQL 8.0.36 + MyCat2,从原理讲解、环境准备、主从复制搭建、读写分离配置、验证测试全流程讲解,补充关键知识点,适合零基础快速上手。
一、核心原理(必懂)
1.1 主从复制原理
主从复制是Master(主库) 实时将数据变更同步到Slave(从库) 的机制,是读写分离的基础。
- 核心组件
- Binary Log(binlog):主库记录所有数据修改的二进制日志。
- I/O Thread:从库拉取主库 binlog,写入中继日志(Relay Log)。
- SQL Thread:从库重放中继日志,保持数据与主库一致。
- 复制类型
- 基于语句:执行相同 SQL,默认、效率高。
- 基于行:同步数据行变更,精准。
- 混合模式:自动切换,生产推荐。
1.2 读写分离原理
读写分离是写操作只走主库,读操作负载到从库,降低主库压力。
- 实现方式
- 代码层:业务代码判断 SQL 路由,性能好、改造成本高。
- 中间件层:MyCat、MySQL Proxy、Amoeba,透明无代码侵入,生产主流。
- 核心价值
- 高并发:读请求分摊到多从库。
- 高可用:主库故障,从库可切换。
- 灾备:从库实时备份数据。
二、实验环境规划
表格
| 角色 | IP 地址 | 操作系统 | 服务 | 端口 |
|---|---|---|---|---|
| Master(主库) | 192.168.10.101 | openEuler 24.03 | MySQL 8.0.36 | 3306 |
| Slave1(从库 1) | 192.168.10.102 | openEuler 24.03 | MySQL 8.0.36 | 3306 |
| Slave2(从库 2) | 192.168.10.103 | openEuler 24.03 | MySQL 8.0.36 | 3306 |
| MyCat(中间件) | 192.168.10.104 | openEuler 24.03 | MyCat2 + JDK8 | 8066 |
| 测试客户端 | 192.168.10.105 | openEuler 24.03 | MySQL 客户端 | - |
前置统一操作(所有节点执行)
- 关闭防火墙与 SELinux
bash
运行
systemctl stop firewalld
systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0
- 时间同步(主从必须时间一致)
bash
运行
yum -y install ntpdate
ntpdate ntp1.aliyun.com
- 安装基础依赖
bash
运行
dnf -y install gcc vim wget net-tools lrzsz tar libaio numactl openssl ncurses-compat-libs
三、MySQL 主从复制搭建(详细步骤)
3.1 所有数据库节点安装 MySQL 8.0.36
- 创建 mysql 用户
bash
运行
useradd -M -s /sbin/nologin mysql
- 解压并配置 MySQL
bash
运行
tar xJf mysql-8.0.36-linux-glibc2.28-x86_64.tar.xz
mv mysql-8.0.36-linux-glibc2.28-x86_64 /usr/local/mysql
mkdir -p /usr/local/mysql/data
chown -R mysql:mysql /usr/local/mysql/data
- 初始化 MySQL(记录临时密码)
bash
运行
cd /usr/local/mysql/bin
./mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
- 配置 my.cnf
bash
运行
vim /etc/my.cnf
ini
[client]
socket=/usr/local/mysql/data/mysql.sock
[mysqld]
socket=/usr/local/mysql/data/mysql.sock
bind-address = 0.0.0.0
port = 3306
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
default-storage-engine=INNODB
character-set-server=utf8
max_connections=2048
skip-name-resolve
max_allowed_packet=16M
- 配置环境变量
bash
运行
echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile
- 配置 systemd 服务
bash
运行
cp /usr/local/mysql/support-files/mysql.server /etc/rc.d/init.d/mysqld
chmod +x /etc/rc.d/init.d/mysqld
vim /lib/systemd/system/mysqld.service
ini
[Unit]
Description=mysqld
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.d/init.d/mysqld start
ExecReload=/etc/rc.d/init.d/mysqld restart
ExecStop=/etc/rc.d/init.d/mysqld stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
- 启动并设置 root 密码
bash
运行
systemctl daemon-reload
systemctl enable mysqld
systemctl start mysqld
# 登录后修改密码
mysql -uroot -p"临时密码"
ALTER USER 'root'@'localhost' IDENTIFIED BY 'pwd123';
FLUSH PRIVILEGES;
3.2 配置 Master 主库(192.168.10.101)
- 修改 my.cnf 开启 binlog
bash
运行
vim /etc/my.cnf
在 [mysqld] 下添加:
ini
server-id=1 # 唯一ID,集群内不重复
log-bin=/usr/local/mysql/data/mysql-bin # 开启binlog
binlog_format = MIXED # 混合复制模式
- 重启 MySQL
bash
运行
systemctl restart mysqld
- 创建从库复制授权账号
bash
运行
mysql -uroot -ppwd123
sql
-- 创建复制用户
CREATE USER 'myslave'@'%' IDENTIFIED BY '123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'%';
-- 兼容旧认证插件
ALTER USER 'myslave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;
-- 查看主库binlog状态(记录File和Position)
SHOW MASTER STATUS;
关键记录:mysql-bin.000001、Position=157
3.3 配置 Slave1 从库(192.168.10.102)
- 修改 my.cnf
bash
运行
vim /etc/my.cnf
ini
server-id=2 # 唯一,不能和主/其他从重复
- 重启 MySQL
bash
运行
systemctl restart mysqld
- 关联主库并启动同步
bash
运行
mysql -uroot -ppwd123
sql
CHANGE MASTER TO
master_host='192.168.10.101',
master_user='myslave',
master_password='123456',
master_log_file='mysql-bin.000001',
master_log_pos=157;
-- 启动从库同步
START SLAVE;
3.4 配置 Slave2 从库(192.168.10.103)
步骤同 Slave1,仅修改server-id=3,其余命令完全一致。
3.5 验证主从同步
- 从库检查状态
sql
SHOW SLAVE STATUS\G
必须满足:Slave_IO_Running: YesSlave_SQL_Running: Yes2. 主库创建数据库测试
sql
CREATE DATABASE db_test;
- 从库查看
sql
SHOW DATABASES;
能看到db_test即主从复制成功。
四、MyCat2 读写分离搭建(详细步骤)
MyCat 是数据库中间件,负责 SQL 路由:写→主库,读→从库。
4.1 MyCat 节点(104)安装 JDK8
bash
运行
dnf install jdk-8u171-linux-x64.rpm -y
java -version # 验证安装
4.2 安装 MyCat2
- 解压 MyCat
bash
运行
unzip mycat2-install-template-1.20.zip -d /usr/local/
ll /usr/local/mycat (里面包含bin,conf,lib(存放函数)和logs)
- 配置环境变量
bash
运行
echo 'export PATH=$PATH:/usr/local/mycat/bin' >> /etc/profile
source /etc/profile
- 添加依赖包
bash
运行
cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib
cp mysql-connector-java-8.0.18.jar /usr/local/mycat/lib
- 添加执行权限
bash
运行
chmod -R +x /usr/local/mycat/bin
mycat -h # 验证安装
4.3 主库创建 MyCat 连接账号(101 执行)
sql
CREATE USER 'mycat'@'%' IDENTIFIED BY 'pwd123';
GRANT ALL ON *.* TO 'mycat'@'%';
ALTER USER 'mycat'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd123';
FLUSH PRIVILEGES;
4.4 配置 MyCat 默认数据源(104)
bash
运行
vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
修改关键配置:
json
"url":"jdbc:mysql://192.168.10.101:3306/mysql?useSSL=false",
"user":"mycat",
"password":"pwd123"
4.5 启动 MyCat 并添加主从数据源
- 启动 MyCat
bash
运行
mycat start
ss -tnl | grep 8066 # 验证8066端口监听
cat /usr/local/mycat/conf/users/root.user.json (可以进行查看一下,这里放的是客户端的相关内容,存放登录用户和密码,客户端使用这个用户和密码才可以跟mycat连接并可以访问mysql。因为客户端需要跟mycat连接才可以访问mysql)
- 登录 MyCat(客户端 / MyCat 节点均可)
bash
运行
在105(客户端)上安装mysql 客户端版 命令:dnf -y install mysql
然后在105做测试(这个·root和密码是mycat提供的,就是上面第15步相关文件提供的内容)
mysql -uroot -p123456 -P8066 -h 192.168.10.104
show databases;(看的只有3个库,此时读写分离并为实现,只搭建了框架)
然后把该老师给的资料中的文档中的内容一个个复制进去(先复制前3条),记得查看ip密码什么之类的是否正确 (这一步告诉mycat谁是主,谁是从,如何在哪里读,在哪里写,这里的用户是在101上创建授权的用户,因为mycat连接mysql的,然后客户端通过mycat连接客户端)
- 添加主库数据源
sql
/*+ mycat:createDataSource{
"name":"master",
"url":"jdbc:mysql://192.168.10.101:3306/?useSSL=false",
"instanceType":"WRITE",
"user":"mycat",
"password":"pwd123"
} */;
- 添加从库 1 数据源
sql
/*+ mycat:createDataSource{
"name":"slave1",
"url":"jdbc:mysql://192.168.10.102:3306/?useSSL=false",
"instanceType":"READ",
"user":"mycat",
"password":"pwd123"
} */;
- 添加从库 2 数据源
sql
/*+ mycat:createDataSource{
"name":"slave2",
"url":"jdbc:mysql://192.168.10.103:3306/?useSSL=false",
"instanceType":"READ",
"user":"mycat",
"password":"pwd123"
} */;
- 查看数据源
sql
/*+ mycat:showDataSources{} */\G
4.6 创建 MyCat 集群
sql
/*! mycat:createCluster{
"name":"cls01",
"masters":["master"],
"replicas":["slave1","slave2"]
} */;
4.7 配置读写分离与轮询策略(104)
- 修改集群配置
bash
运行
vim /usr/local/mycat/conf/clusters/cls01.cluster.json
json
"readBalanceType":"BALANCE_ALL_READ",
"balance":1
- 修改负载均衡为轮询
bash
运行
vim /usr/local/mycat/conf/server.json
json
"defaultLoadBalance":"BalanceRoundRobin"
- 重启 MyCat
bash
运行
mycat restart
netstat -anpt | grep 8066 (两个,其中一个是远程的ip
4.8 绑定数据库到集群
- 客户端创建测试库
bash
运行
mysql -uroot -p123456 -P8066 -h192.168.10.104
CREATE DATABASE test;
- MyCat 节点修改 schema 配置
bash
运行
vim /usr/local/mycat/conf/schemas/test.schema.json
添加:
json
"targetName":"cls01",
- 重启 MyCat
bash
运行
mycat restart
五、读写分离验证(最直观测试)
5.1 停止从库同步(制造数据差异)
bash
运行
# Slave1执行
mysql -uroot -ppwd123
STOP SLAVE;
# Slave2执行
mysql -uroot -ppwd123
STOP SLAVE;
5.2 分别插入不同数据
- 主库(101)
sql
USE test;
CREATE TABLE zang(id INT,name VARCHAR(10));
INSERT INTO zang VALUES(1,'master');
- Slave1(102)
sql
USE test;
INSERT INTO zang VALUES(2,'slave1');
- Slave2(103)
sql
USE test;
INSERT INTO zang VALUES(3,'slave2');
5.3 客户端测试读轮询
bash
运行
mysql -uroot -p123456 -P8066 -h192.168.10.104
USE test;
SELECT * FROM zang;
- 第一次查询:
slave1数据 - 第二次查询:
slave2数据 - 第三次查询:
slave1数据→ 读请求轮询分发到从库
5.4 测试写路由到主库
sql
INSERT INTO zang VALUES(4,'write_test');
- 仅主库 101能查到该数据
- 从库 102/103 无此数据→ 写请求只路由到主库
六、关键补充知识点
6.1 主从复制常见问题
- server-id 重复:从库无法连接,必须唯一。
- 防火墙 / 端口未开:3306 端口不通,I/O 线程失败。
- 密码认证插件:MySQL8 默认
caching_sha2_password,需改为mysql_native_password。 - 主从数据不一致:从库手动修改数据,导致 SQL 线程中断。
6.2 MyCat 核心概念
- 8066 端口:MyCat 数据端口,客户端连接用。
- 数据源:定义主 / 从库连接信息。
- 集群:绑定主从,指定读写路由。
- 轮询策略:
BalanceRoundRobin,读请求均匀分发。
6.3 生产环境优化
- 主库:只写,配置高 CPU / 内存,开启 binlog。
- 从库:只读,配置多实例,分担读压力。
- MyCat:集群部署,避免单点故障。
- 监控:用 Prometheus+Grafana 监控主从延迟、MyCat 状态。
6.4 读写分离适用场景
- 读多写少:电商、博客、后台管理系统。
- 高并发:需要水平扩展读能力。
- 数据灾备:主从同步保障数据安全。
七、总结
- 主从复制是基础,依赖 binlog+I/O+SQL 线程实现数据同步。
- 读写分离是优化,MyCat 中间件实现透明路由,无代码侵入。
- 完整流程:环境准备→MySQL 安装→主从配置→MyCat 安装→数据源 / 集群配置→验证。
- 生产中需关注主从延迟、高可用、监控告警,保障数据库稳定运行。
八,
- 先主从复制,再读写分离,顺序不可颠倒。
- 主库负责写,从库负责读,大幅降低主库压力。
- MyCat 作为中间件,对应用透明,无需修改业务代码。
- 生产环境需开启主从监控、心跳检测、故障自动切换。
更多推荐
所有评论(0)