本文基于 MySQL 8.0 + openEuler 24.03,用最简步骤实现主从复制 + MyCat2 读写分离,包含全套可复制代码与关键知识点。
一、核心原理(必懂)
1. 主从复制
- 作用:主库写、从库读,数据实时同步,分担压力、容灾备份。
- 流程:
- 主库写入 binlog 二进制日志
- 从库 IO 线程拉取 binlog 到 relay log
- 从库 SQL 线程重放日志,保持数据一致
- 复制类型:
- STATEMENT:基于 SQL 语句(默认,高效)
- ROW:基于行数据变更(精准)
- MIXED:混合模式(自动切换)
2. 读写分离
- 规则:写 → 主库,读 → 从库
- 实现方式:
- 代码层:业务代码判断 SQL 路由
- 中间件:MyCat、Amoeba、MySQL-Proxy(本文用 MyCat2)
二、环境准备(5 台服务器)
表格
| 角色 | IP | 应用 |
|---|---|---|
| Master | 192.168.10.101 | MySQL 8.0 |
| Slave1 | 192.168.10.102 | MySQL 8.0 |
| Slave2 | 192.168.10.103 | MySQL 8.0 |
| MyCat2 | 192.168.10.104 | MyCat2 + JDK8 |
| Client | 192.168.10.105 | MySQL 客户端 |
2. 环境准备(所有节点执行)
bash
运行
# 时间同步
yum -y install ntpdate
ntpdate ntp1.aliyun.com
# 关闭防火墙与SELinux
systemctl stop firewalld
systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
3. MySQL 二进制安装(主 / 从都执行)
bash
运行
# 安装依赖
dnf -y install gcc vim wget net-tools lrzsz tar libaio numactl openssl ncurses-compat-libs
# 创建mysql用户
useradd -M -s /sbin/nologin mysql
# 解压安装
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 /usr/local/mysql/data
chown -R mysql:mysql /usr/local/mysql/data
# 初始化(记录临时密码)
cd /usr/local/mysql/bin
./mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
4. MySQL 配置文件(/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
max_connections=2048
default-storage-engine=INNODB
skip-name-resolve
character-set-server=utf8
max_allowed_packet=16M
5. 配置系统服务与环境变量
bash
运行
# 环境变量
echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile
# 配置systemd
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
bash
运行
systemctl daemon-reload
systemctl enable mysqld
systemctl start mysqld
# 修改root密码
mysqladmin -u root password 'pwd123'
6. 主库(Master)配置(192.168.10.101)
bash
运行
# 修改my.cnf
vim /etc/my.cnf
添加:
ini
server-id=1
log-bin=/usr/local/mysql/data/mysql-bin
binlog_format = MIXED
bash
运行
systemctl restart mysqld
# 登录MySQL授权从库
mysql -u root -p
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;
# 查看主库状态(记录File和Position)
show master status;
7. 从库(Slave1/Slave2)配置
Slave1(192.168.10.102)
bash
运行
vim /etc/my.cnf
ini
server-id=2
bash
运行
systemctl restart mysqld
Slave2(192.168.10.103)
bash
运行
vim /etc/my.cnf
ini
server-id=3
bash
运行
systemctl restart mysqld
两台从库执行同步命令
sql
mysql -uroot -p
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;
# 检查状态(两个必须为YES)
show slave status\G
关键项:
Slave_IO_Running: Yes、Slave_SQL_Running: Yes
8. 主从复制验证
sql
# 主库创建库
create database db_test;
# 从库查看
show databases;
三、MySQL 读写分离(Mycat2)
1. 核心原理(补充知识点)
- 读写分离两种实现
- 代码层:代码判断 SQL 路由,性能好,改造成本高
- 代理层:Mycat、Amoeba、MySQL-Proxy,对应用透明
- Mycat2 优势
- 兼容 MySQL 协议
- 支持读写分离、分库分表
- 配置简单,支持 SQL 命令配置
2. Mycat2 安装(192.168.10.104)
bash
运行
# 安装JDK
dnf install jdk-8u171-linux-x64.rpm -y
# 解压Mycat2
unzip mycat2-install-template-1.20.zip -d /usr/local/
mv /usr/local/mycat2-install-template-1.20 /usr/local/mycat
# 环境变量
echo 'export PATH=$PATH:/usr/local/mycat/bin' >> /etc/profile
source /etc/profile
# 复制依赖包
cp mysql-connector-java-8.0.18.jar /usr/local/mycat/lib
cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib
# 赋权
chmod -R +x /usr/local/mycat/bin
# 验证安装
mycat -h
3. 主库创建 Mycat 账号
sql
mysql -uroot -p
create user 'mycat'@'%' identified by 'pwd123';
grant all on *.* to 'mycat'@'%';
ALTER USER 'mycat'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd123';
flush privileges;
4. Mycat2 配置读写分离
bash
运行
# 启动Mycat
mycat start
# 连接Mycat(端口8066)
mysql -uroot -p123456 -P8066 -h192.168.10.104
(1)添加数据源
sql
-- 主库(写)
/*+ mycat:createDataSource{
"name":"master",
"url":"jdbc:mysql://192.168.10.101:3306/?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true",
"instanceType":"WRITE",
"user":"mycat",
"password":"pwd123"
} */;
-- 从库1(读)
/*+ mycat:createDataSource{
"name":"slave1",
"url":"jdbc:mysql://192.168.10.102:3306/?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true",
"instanceType":"READ",
"user":"mycat",
"password":"pwd123"
} */;
-- 从库2(读)
/*+ mycat:createDataSource{
"name":"slave2",
"url":"jdbc:mysql://192.168.10.103:3306/?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true",
"instanceType":"READ",
"user":"mycat",
"password":"pwd123"
} */;
-- 查看数据源
/*+ mycat:showDataSources{} */\G
(2)创建集群
sql
/*! mycat:createCluster{
"name":"cls01",
"masters":["master"],
"replicas":["slave1","slave2"]
} */;
(3)修改集群负载均衡(轮询)
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
"loadBalance":{
"defaultLoadBalance":"BalanceRoundRobin"
}
bash
运行
mycat restart
5. 读写分离验证
sql
# Mycat创建库表
create database test;
use test;
create table zang(id int(10),name varchar(10),address varchar(20));
bash
运行
# 从库停止同步
mysql -uroot -p -h192.168.10.102
stop slave;
mysql -uroot -p -h192.168.10.103
stop slave;
sql
# 主库插入
insert into test.zang values('1','zang','this_is_master');
# 从库1插入
insert into test.zang values('2','zang','this_is_slave1');
# 从库2插入
insert into test.zang values('3','zang','this_is_slave2');
sql
# Mycat查询(轮询读从库)
select * from test.zang;
# Mycat写入(只写主库)
insert into zang values('4','zhang','write_test');
六、补充知识点(面试 / 运维常用)
- server-id 必须唯一,同一集群内不能重复。
- MySQL 8.0 默认认证插件为
caching_sha2_password,需改为mysql_native_password兼容中间件。 - 主从延迟:从库单线程重放,高并发下会延迟,可用并行复制优化。
- MyCat 端口:
- 8066:数据端口(业务访问)
- 9066:管理端口
- 读写分离策略:
BALANCE_ALL_READ:所有读走从库BalanceRoundRobin:从库轮询负载
- 常见异常:
- Slave_IO 异常:网络 / 账号 / 防火墙问题
- Slave_SQL 异常:从库数据冲突、主键重复
七、整体总结
- 先主从复制,再读写分离,顺序不可颠倒。
- 主库负责写,从库负责读,大幅降低主库压力。
- MyCat 作为中间件,对应用透明,无需修改业务代码。
- 生产环境需开启主从监控、心跳检测、故障自动切换。