MySQL 主从复制与读写分离:高可用架构实战

MySQL 主从复制是企业级应用的高可用基础——主库写、从库读,既分担了读压力,又提供了数据冗余备份。但很多人只会在配置文件里加几行 server-id 就以为完成了复制,实际上主从复制涉及binlog 格式、同步模式、故障切换等多个关键环节。本文系统讲解 MySQL 主从复制的完整部署与运维。

主从复制的核心原理

MySQL 复制基于 binlog(二进制日志) 机制:主库将所有写操作记录到 binlog,从库通过 I/O 线程拉取 binlog 并写入本地 relay log,再由 SQL 线程重放这些操作,从而实现数据同步。

组件位置职责
Master主库服务器记录 binlog,提供 dump 线程推送
Slave I/O从库服务器连接主库,拉取 binlog 写入 relay log
Slave SQL从库服务器读取 relay log 并重放 SQL 语句
Binlog主库文件记录所有变更操作的二进制日志
Relay Log从库文件暂存从主库拉取的 binlog 副本

第一步:主库配置

# 编辑主库配置文件 /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# 必须唯一,不能与其他实例重复
server-id = 1
# 启用 binlog
log-bin = mysql-bin
# binlog 格式:推荐 ROW(行级复制,数据一致性最高)
binlog_format = ROW
# 需要复制的数据库(可选,多个用逗号分隔)
binlog_do_db = myapp
# 忽略的数据库(如 mysql、performance_schema)
binlog_ignore_db = mysql
binlog_ignore_db = performance_schema
binlog_ignore_db = information_schema
# 重启主库使配置生效
sudo systemctl restart mysql

# 创建复制账户
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_password_123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

# 查看主库状态和 binlog 位置
SHOW MASTER STATUS;

第二步:从库配置

# 编辑从库配置文件 /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
server-id = 2          # 必须与主库不同
log-bin = mysql-bin
binlog_format = ROW
relay-log = relay-bin

# 重启从库
sudo systemctl restart mysql
# 配置复制关系
CHANGE MASTER TO
  MASTER_HOST = '主库IP',
  MASTER_USER = 'repl',
  MASTER_PASSWORD = 'repl_password_123',
  MASTER_LOG_FILE = 'mysql-bin.000001',    # 主库 SHOW MASTER STATUS 的输出
  MASTER_LOG_POS = 154;                    # 主库 SHOW MASTER STATUS 的输出

# 启动复制
START SLAVE;

# 查看复制状态
SHOW SLAVE STATUS\G

同步模式选择:异步 vs 半同步

MySQL 支持多种复制模式,核心区别在于数据一致性与性能的权衡:

模式一致性保证性能影响适用场景
异步复制(默认)无保证,从库可能延迟⭐⭐⭐ 无额外开销读多写少,容忍短暂不一致
半同步复制至少一个从库确认收到⭐⭐ 有轻微延迟金融、订单等要求强一致的场景
组复制(MGR)多数派确认⭐ 延迟较高高可用集群,自动故障切换

开启半同步复制

# 在主库和从库安装半同步插件
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

# 主库启用
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000;  # 1秒超时

# 从库启用
SET GLOBAL rpl_semi_sync_slave_enabled = 1;

# 重启 IO 线程使配置生效
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

主从延迟排查与优化

主从延迟是复制故障中最常见的问题。延迟原因通常有三类:

  1. 网络延迟:主从之间网络不稳定或带宽不足。
  2. 从库硬件性能不足:SQL 线程重放速度跟不上主库写入速度。
  3. 大事务或慢查询:主库执行大事务时,从库需要重放更长时间。
-- 检查主从延迟
SHOW SLAVE STATUS\G
# 关注 Slave_SQL_Running_State 和 Seconds_Behind_Master

-- 查看当前复制线程状态
SELECT * FROM information_schema.processlist WHERE COMMAND IN ('Binlog Dump','Slave_IO','Slave_SQL');

-- 优化:从库只读查询,避免写操作冲突
SET GLOBAL read_only = ON;

故障切换:手动主从切换

当主库发生故障需要切换时,选择延迟最小的从库作为新主库。以下是手动切换步骤:

# 1. 在所有从库上停止复制
STOP SLAVE;

# 2. 选择延迟最小的从库提升为主库
RESET MASTER;
SET GLOBAL read_only = OFF;

# 3. 其他从库指向新主库
CHANGE MASTER TO
  MASTER_HOST = '新主库IP',
  MASTER_LOG_FILE = 'mysql-bin.000001',
  MASTER_LOG_POS = 154;

START SLAVE;

# 4. 验证复制状态
SHOW SLAVE STATUS\G

总结

MySQL 主从复制是企业级架构的基石,掌握其原理和运维技巧对任何后端工程师都是必修课。建议在实际部署前先在本机用 Docker 搭建测试环境(参考之前的 Docker 网络模式教程),熟悉复制流程后再应用到生产环境。更多数据库优化内容,可参考 MySQL 索引优化PostgreSQL 备份恢复。祝搭建顺利!🗄️

上一篇 服务器安全加固:SSH / 防火墙 / Fail2ban 实战指南
下一篇 前端构建工具演进:Webpack → Vite → Rspack 横评