MySQL 主从复制配置教程:读写分离、自动备份,数据库零丢失高可用


网站访问量上来了、数据库读写压力大,或者担心数据库单独一台机器万一挂了数据丢失——这时候就该给数据库做主从复制(Master-Slave Replication)了。它把主库的数据实时同步到从库:主库负责写入,从库负责读取(读写分离),主库挂了还能随时切到从库。这篇文章从零讲清 MySQL 主从复制的原理、搭建步骤和常见坑。

一、什么是主从复制

MySQL 主从复制就是让一台"从库"实时复制"主库"的数据变化。核心机制是:

  1. 主库(Master)把所有数据变更记到二进制日志(binlog)
  2. 从库(Slave)通过 I/O 线程拉取主库的 binlog
  3. 从库的 SQL 线程把日志里的操作重放到本地

主从复制带来的三大价值:

  • 读写分离:主库写、从库读,分摊压力
  • 数据备份:从库相当于实时的异地备份
  • 高可用:主库故障时,把从库切换为主库,业务不停

二、环境准备

需要两台服务器(或用一台服务器装两个 MySQL 实例,但生产环境建议两台独立机器):

  • 主库:IP 192.168.1.10,MySQL 主账号
  • 从库:IP 192.168.1.11,MySQL 从账号

两台机都要能互相访问 3306 端口,并已装好 MySQL(版本建议相同,至少主库版本 ≤ 从库版本)。

三、配置主库(Master)

1. 修改主库配置文件 /etc/my.cnf:

[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
expire_logs_days = 7

2. 重启 MySQL:

systemctl restart mysqld

3. 创建同步专用账号:

CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY '强密码';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
FLUSH PRIVILEGES;

4. 查看主库状态,记录 File 和 Position:

SHOW MASTER STATUS;

记下输出的 File(如 mysql-bin.000001)和 Position(如 154),从库配置要用。

四、初始化从库数据

如果主库已有数据,需要先把数据同步到从库。

1. 锁定主库,导出数据:

FLUSH TABLES WITH READ LOCK;   -- 在另一个会话执行,锁表
mysqldump -u root -p --single-transaction --master-data=2 数据库名 > master.sql

2. 解锁主库:

UNLOCK TABLES;

3. 把数据导入从库:

scp master.sql root@192.168.1.11:/root/
mysql -u root -p < master.sql

五、配置从库(Slave)

1. 修改从库配置文件 /etc/my.cnf:

[mysqld]
server-id = 2
log-bin = mysql-bin
relay-log = mysql-relay
read-only = 1

2. 重启从库:

systemctl restart mysqld

3. 连接主库并启动同步:

CHANGE MASTER TO
  MASTER_HOST='192.168.1.10',
  MASTER_USER='repl',
  MASTER_PASSWORD='强密码',
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=154;

START SLAVE;

六、验证同步是否正常

1. 查看从库状态:

SHOW SLAVE STATUS\G

关键看两个字段,必须都是 YES:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

如果一个是 NO,重点关注错误信息(后面有排查)。

2. 实际测试同步:

在主库建一张测试表并插入数据:

-- 主库
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE tb1(id INT, name VARCHAR(20));
INSERT INTO tb1 VALUES(1, 'hello');

在从库查询(read-only 从库只能读):

-- 从库
USE testdb;
SELECT * FROM tb1;   -- 应能看到刚插入的数据

能看到数据,说明主从同步成功。

七、实现读写分离

主从复制完成后,还要让应用"把写放主库、把读放从库",才叫真正的读写分离。常用做法:

  • 应用程序配置双数据源:在应用配置里指定写库和读库地址,框架(如 Spring、Django)支持一主多从。
  • 中间件(MyCat / ProxySQL):在应用和数据库之间加一层代理,自动路由读写请求。
  • MySQL Router:Oracle 官方提供的读写分离路由组件。

对个人站来说,如果只是想要高可用的数据备份,可以先只做主从复制,读写分离等数据量大时再加。

八、故障切换(主从切换)

主库挂了,要把从库临时顶上去:

1. 在从库停止同步并解除只读:

STOP SLAVE;
RESET MASTER;
SET GLOBAL read_only=OFF;

2. 把应用连接地址指向从库 IP。

3. 修好旧主库后,再反过来把它作为新主库的新从库(角色互换)。

(完整的自动故障切换建议用 MHA 或 MySQL InnoDB Cluster,这里只讲手动应急。)

九、常见问题排查

Q1:Slave_IO_Running: Connect 报错?

最常见是 Repl 账号连接不上。检查: - 主库账号的网络权限是否允许从库 IP(192.168.1.%) - 服务器防火墙是否放行 3306 - CHANGE MASTER TO 里的密码是否填对

Q2:Slave_IO_Running: No,Slave_SQL_Running 正常?

通常是网络或 binlog 拉取问题。看 Last_IO_Error,常见是主库 binlog 被清理导致拉不到。

Q3:Slave_SQL_Running: No?

一般是 SQL 重放报错(如数据冲突)。看 Last_SQL_Error。如果是误操作,可以手动跳过错误:

STOP SLAVE;
SET GLOBAL sql_slave_skip_counter=1;  -- 跳过一条(仅应急)
START SLAVE;

Q4:主从数据不一致?

长期误差可重新初始化从库:重新 mysqldump 主库数据导入从库,再 CHANGE MASTER TO 到新的 binlog 位置。

总结

MySQL 主从复制是数据库高可用的基本功:主库写、从库读、实时备份、故障切换,一套配好网站数据就有了"双保险"。核心步骤是——主库开 binlog 建同步账号、从库配置 server-id 并 CHANGE MASTER TO,最后重点盯 Slave_IO_Running 和 Slave_SQL_Running 两个状态。配合本站的 MySQL 教程和备份教程,你的数据库就稳了。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Nginx 限流限速配置教程:防 CC 攻击、保护后端,limit_req 与 limit_conn 实战

域名邮箱搭建教程:企业邮箱自定义域名,让客户一眼看出的专业形象

评 论
更换验证码