目录
一、MySQL 主从复制
(0)概述
MySQL 主从复制是一种数据同步机制,允许数据从一个主数据库(Master)复制到一个或多个从数据库(Slave)。其主要用途包括:
-
数据冗余与灾备:通过从库提供数据备份,增强容灾能力。
-
负载均衡:将读操作分散到多个从库,减轻主库压力。
-
高可用性:主库故障时,从库可快速切换为主库,减少停机时间。
(1)MySQL 支持的复制类型
-
基于语句的复制(Statement-Based Replication, SBR)
-
主库记录执行的 SQL 语句到二进制日志(binlog),从库重放这些语句。
-
优点:日志量小,节省存储和传输时间。
-
缺点:非确定性语句(如
NOW()
)可能导致数据不一致。
-
-
基于行的复制(Row-Based Replication, RBR)
-
主库记录每行数据的变更细节到 binlog。
-
优点:数据一致性高,适合复杂操作(如含变量的语句)。
-
缺点:日志量大,可能影响性能。
-
-
混合模式复制(Mixed-Based Replication, MBR)
-
根据操作类型自动选择 SBR 或 RBR,平衡安全性与效率。
-
(2)复制的工作原理过程
-
主库写入数据:主库将数据变更记录到 binlog。
-
从库 IO 线程拉取日志:从库的 IO 线程连接主库,读取 binlog 并写入本地中继日志(relay log)。
-
从库 SQL 线程重放日志:从库的 SQL 线程解析 relay log,重放 SQL 或行变更操作。
-
复制模式:
-
异步复制(默认):主库不等待从库确认,性能高但可能丢数据。
-
半同步复制:主库至少等待一个从库接收数据后才提交事务,平衡性能与安全性。
-
全同步复制(需第三方插件):主库等待所有从库提交事务,保证强一致性但延迟高。
-
二、MySQL 读写分离
(0)概述
MySQL 读写分离是一种通过分离读操作(SELECT)与写操作(INSERT/UPDATE/DELETE)的数据库架构设计,将写操作集中在主库(Master),读操作分散到从库(Slave),以提升系统性能和并发处理能力。
核心作用:
-
降低主库压力:读操作占数据库负载的 70%~90%,读写分离可将读请求分流到从库。
-
提高扩展性:通过增加从库水平扩展读能力。
-
提升可用性:从库故障时,读请求可路由到其他从库或主库
(1)MySQL 读写分离类型
1. 基于程序代码内部实现
原理:在应用程序代码中显式指定读/写操作的数据源,例如:
-
使用 多数据源配置(如 Spring Boot 中配置
masterDataSource
和slaveDataSource
)。 -
通过 AOP(面向切面编程) 或 注解 动态切换数据源(如
@ReadOnly
注解标记读操作)。
优点:
-
灵活控制:可根据业务逻辑定制路由规则(如特定查询强制走主库)。
-
低依赖:无需额外中间件,减少运维复杂度。
缺点:
-
代码侵入性:需修改业务代码,增加维护成本。
-
扩展性受限:新增从库需修改配置并重启应用。
2. 基于中间代理实现
原理:通过独立的中间件代理层(Proxy)自动路由请求,对应用透明。
常见工具:
-
ProxySQL:高性能开源代理,支持动态路由、连接池管理、故障转移。
-
MyCAT:基于阿里开源的分布式数据库中间件,支持读写分离、分库分表。
-
MySQL Router:官方轻量级中间件,集成于 MySQL InnoDB Cluster。
工作流程:
-
应用连接代理:应用将 SQL 请求发送到代理服务器。
-
代理解析 SQL:代理解析 SQL 类型(读/写)。
-
路由决策:
-
写操作(INSERT/UPDATE/DELETE) → 转发到主库。
-
读操作(SELECT) → 按负载均衡策略(轮询、权重、最小连接数)分发到从库。
-
-
结果返回:代理将数据库响应返回给应用。
优点:
-
对应用透明:无需修改业务代码,降低侵入性。
-
动态管理:支持在线添加/移除从库,代理自动感知。
-
高可用:内置健康检查,自动剔除故障节点。
缺点:
-
性能开销:代理层可能成为性能瓶颈(需选择高性能代理如 ProxySQL)。
-
运维复杂度:需额外维护代理服务器,增加架构复杂度。
(2)工作原理过程
-
请求识别:
-
中间件或应用层解析 SQL,区分读(SELECT)和写(INSERT/UPDATE/DELETE)。
-
-
路由策略:
-
写操作:直接转发至主库。
-
读操作:按负载均衡策略(轮询、权重、随机)分发到从库。
-
-
负载均衡与故障转移:
-
中间件监控从库状态,自动剔除故障节点。
-
-
数据一致性处理:
-
强制特定读请求走主库(如通过
/* FORCE_MASTER */
注释)。
-
三、主从复制与读写分离的关系
-
基础与扩展:
-
主从复制是读写分离的基础,为读写分离提供数据同步支持。
-
读写分离是主从复制的扩展应用,进一步提升系统性能。
-
-
一致性权衡:
-
主从同步存在延迟(异步复制),读写分离可能导致“读旧数据”。
-
解决方案:强制特定读请求走主库(如通过 ProxySQL 的
/* FORCE_MASTER */
注解)。
-
四、主从复制配置
(1)主从复制搭建
主服务器配置:
1.关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
2.修改/etc/my.cnf文件
log-bin=/usr/local/mysql/data/mysql-bin
binlog_format=MIXED
server-id=1 #id号不能相同
3.重启服务
systemctl restart mysqld
4.创建用户给从服务器授权
create user 'myslave'@'%' identified by '123456';
grant replication slave on *.* to 'myslave'@'%';
alter user 'myslave'@'%' identified with mysql_native_password by '123456';
5.刷新权限并查看主数据库状态信息
flush privileges;
show master status;
从服务器配置:
1.修改/etc/my.cnf文件
server-id=2 //添加 唯一服务器标识符。不可以冲突
2.连接主(记得关主防火墙)
change master to master_host='主IP',master_user='主账号名',master_password='',master_log_file='log名',master_log_pos='position号';
例如:
change master to master_host='192.168.10.101',master_user='myslave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=324;
3.开启从服务,启动同步
start slave;
4.查看状态 (IO ,SQL 为Yes)
show slave status\G
或
mysql -uroot -ppwd123 "show slave status\G" | grep "YES"
验证:
1. 主从 登录MySQL
2. 再主上创建新数据库,在从上查看是否同步
(2)主主复制搭建
#双机互为主从
在主从复制的基础上做(改从的配置)
1.添加配置文件 /etc/my.cof
log-bin=/usr/local/mysql/data/mysql-bin
binlog-format=MIXED
2.创建用户开启权限
create user 'myslave'@'%' identified by 'pwd123';
grant replication slave on *.* to 'myslave'@'%';
alter user 'myslave'@'%' identified with mysql_native_password by 'pwd123';
3.刷新
flush privileges;
show master status; #看主状态信息
4.先关闭从同步
stop slave;
5.在主上设置从为它的主
change master to master_host='主IP',master_user='主账号名',master_password='',master_log_file='log名',master_log_pos=position号;
6.双机开启从同步,查看从状态
start slave;
show master status;
五、读写分离搭建
#MySQL读写分离是建立于MySQL主从的基础上的
搭建一台mycat服务器
1.准备软件包
jdk-8u171-linux-x64.rpm
mycat2-1.21-release-jar-with-dependencies.jar
mycat2-install-template-1.20.zip
mysql-connector-java-8.0.18.jar
2.准备环境并安装mycat
rpm -ivh jdk-8u171-linux-x64.rpm(解决不了依赖关系)
dnf -y install jdk-8u171-linux-x64.rpm(解决依赖关系)
unzip mycat2-install-template-1.20.zip -d /usr/local (解压到local下)
ln -s /usr/local/mycat/bin/* /usr/local/bin/ (做系统环境)
cp mysql-connector-java-8.0.18.jar mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/ (把架包复制进来)
cd /usr/local/mycat/bin/
chmod +x *
mycat -h #测试安装的正确性
3.在主服务器上为mycat创建用户并授权(从会自动同步),使mycat可以连接主服务器
create user 'mycat'@'%' identified by 'pwd123';
grant all on *.* to 'mycat'@'%';
alter user 'mycat'@'%' identified with mysql_native_password by 'pwd123';
flush privileges;
4.mycat配置
vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
"password":"pwd123", (更改密码)
"url":"jdbc:mysql://192.168.10.101:3306/mysql? (更改成主的IP)
"user":"mycat", (更改用户名)
mycat start (启动mycat)
netstat -anpt |grep mycat
netstat -anpt |grep 8066 (查看启动了没有)
systemctl stop firewalld (关掉防火墙)
5.客户机验证
dnf -y install mysql (没有mysql命令装)
mysql -uroot -p123456 -P8066 -h192.168.10.104 (这个密码是mycat提供给客户端使用的)
create database aaa;
注意:mycat 连接的是主,通过mycat创建的库 主从是可以看到的 通过主创建的库 mycat是看不到的。
读写分离配置,有两种方式,一是直接在Mycat的配置目录“/usr/local/mycat/conf”的子目录编辑相关的文本文件;二是登录到mycat交互界面。用特殊的SQL命令配置。
##演示第二种方式
第一步 mycat 添加数据源
#以管理员的身份登录到mycat (别登录到其他节点了)
# 增加主库master
/*+ 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"} */;
#添加从节点的库
/*+ 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"} */;
/*+ 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
注意:如果数据源配置有误可使用“/*+ mycat:resetConfig{} */;” 进行重置
执行前面的SQL语句后,在目录"/usr/local/mycat/conf/data/sources"下会自动生成文本文件。
第二步 创建mycat集群
/*! mycat:createCluster{"name":"cls01","masters":["master"],"replicas":["slave1","slave2"]} */;
可以通过查看mycat集群
ls /usr/local/mycat/conf/datasources
还可以查看负载均衡的算法:看是否为轮询“BalanceRoundRobin”
cat /usr/local/mycat/conf/server.json
重启mycat
mycat retart
第三步 验证Mycat读写分离效果
1.登录集群
mysql -uroot -p123456 -P8066 -h192.168.10.101 (登录,IP为主服务器)
create database test; (创建库测试一下)
注意:在mycat 的schemas目录下会有一个该库明明的文件,要修改文件标注的mycat的集群,然后重新启动mycat(pwd--ll--cat test.schema.json)
mycat restart #重启
create table test.zang(id int(10),name varchar(10),address varchar(20)); #创建表的操作会路由到master主服务器执行,并同步到slave
2.停止主从同步
stop slave;
3.在主和从创建测试数据
在主从分别在zang表里添加数据
如:
主
insert into test.zang values('1','zhangsan','this_is_master');
从
insert into test.zang values('2','zhangsan','this_is_slave1');
#测试读操作
登录mycat集群,查询test.zang的数据
select * from test.zang #多查几次,结果为从服务器解析
#测试写操作
登录集群 mysql -uroot -p123456 -P8066 -h192.168.10.101
insert into zang values('4','zhang','write_test');
在主上查看(只有主上可以查到)
show databases;
show tables;
select * from zang;