MySQL读写分离的核心逻辑是将写请求发送到主库,读请求分发到从库,从而分散单节点的访问压力,而主从复制与binlog日志同步是实现这一架构的基础。binlog即二进制日志,记录了主库所有数据变更操作,从库通过读取主库的binlog日志来同步数据,保证主从数据一致性。

一、binlog日志基础配置
binlog是MySQL主从复制的核心载体,首先需要开启主库的binlog功能,修改主库MySQL配置文件my.cnf(Windows系统为my.ini):
[mysqld] # 开启binlog日志,日志文件前缀为mysql-bin log-bin=mysql-bin # 设置服务器唯一ID,主从库ID不能重复 server-id=1 # binlog日志格式,推荐使用ROW格式,记录每行数据变更,同步更准确 binlog_format=ROW # 可选:设置binlog过期时间,避免日志文件占用过多磁盘空间 expire_logs_days=7
修改完成后重启主库MySQL服务,登录主库执行以下命令查看binlog状态:
-- 查看binlog是否开启 SHOW VARIABLES LIKE 'log_bin'; -- 查看当前binlog文件信息 SHOW MASTER STATUS;
执行SHOW MASTER STATUS后会得到类似如下结果,记录下File和Position的值,后续从库配置需要用到:
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
|---|---|---|---|
| mysql-bin.000001 | 154 |
二、主从复制配置步骤
1. 主库创建同步账号
主库需要创建一个用于从库同步数据的专用账号,并授予复制权限:
-- 创建同步账号,允许从库IP访问,替换为实际从库IP,%表示所有IP CREATE USER 'repl'@'192.168.0.%' IDENTIFIED BY 'repl_password'; -- 授予复制权限 GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.0.%'; -- 刷新权限 FLUSH PRIVILEGES;
2. 从库配置同步参数
修改从库MySQL配置文件,设置唯一的server-id,注意不能和主库重复:
[mysqld] # 从库服务器唯一ID server-id=2 # 可选:开启从库binlog,用于级联复制场景 # log-bin=mysql-slave-bin # 可选:设置从库只读,避免误写 read_only=1
重启从库MySQL服务后,登录从库执行同步配置命令,替换对应的主库IP、同步账号信息、binlog文件名和位置:
CHANGE MASTER TO MASTER_HOST='192.168.0.10', -- 主库IP MASTER_USER='repl', -- 同步账号 MASTER_PASSWORD='repl_password', -- 同步账号密码 MASTER_LOG_FILE='mysql-bin.000001', -- 主库binlog文件名 MASTER_LOG_POS=154; -- 主库binlog位置
3. 启动从库同步并验证
执行以下命令启动从库同步线程:
START SLAVE;
执行SHOW SLAVE STATUSG查看同步状态,重点关注两个字段:
Slave_IO_Running:值为Yes表示IO线程正常运行,负责从主库拉取binlogSlave_SQL_Running:值为Yes表示SQL线程正常运行,负责执行同步过来的binlog日志
两个字段都为Yes说明主从复制配置成功,此时主库的数据变更会自动同步到从库。
三、基于主从复制实现读写分离
主从复制配置完成后,就可以实现读写分离,常见的实现方式有两种:
1. 应用层代码实现
在业务代码中根据SQL类型选择数据源,写操作走主库,读操作走从库,以下是Java示例:
public class DataSourceRouter {
// 主库数据源
private DataSource masterDataSource;
// 从库数据源
private DataSource slaveDataSource;
public DataSource getDataSource(String sql) {
// 简单判断SQL是否为写操作,实际场景可优化判断逻辑
if (sql.trim().toUpperCase().startsWith("INSERT")
|| sql.trim().toUpperCase().startsWith("UPDATE")
|| sql.trim().toUpperCase().startsWith("DELETE")) {
return masterDataSource;
} else {
return slaveDataSource;
}
}
}
2. 中间件层实现
使用MyCat、ShardingSphere等中间件,不需要修改业务代码,中间件会自动解析SQL并路由到对应的主从库,以下是ShardingSphere-JDBC的简易配置示例:
spring:
shardingsphere:
datasource:
names: master, slave
master:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://192.168.0.10:3306/test_db
username: root
password: master_password
slave:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://192.168.0.11:3306/test_db
username: root
password: slave_password
rules:
readwrite-splitting:
data-sources:
readwrite_ds:
type: Static
props:
write-data-source-name: master
read-data-source-names: slave
四、常见问题与注意事项
- 主从复制存在延迟,对实时性要求高的读操作建议走主库,避免读取到旧数据
- 从库建议设置为只读,避免误写导致主从数据不一致
- 定期检查主从同步状态,若出现同步中断,先排查错误日志,再重新配置同步位点
- binlog日志要定期清理,避免占用过多磁盘空间,同时要保证从库同步完成前不清理对应的binlog文件
注意:读写分离仅适用于读多写少的场景,若业务写操作占比很高,读写分离的提升效果有限,需要结合分库分表等其他方案优化。
MySQL读写分离主从复制binlog日志同步修改时间:2026-07-03 03:18:29