MySQL 主从复制入门
用一主一从把数据实时复制到第二台服务器,实现读写分离与热备。
在单台服务器上跑 MySQL,一旦机器故障或读请求压满就会成为瓶颈。主从复制(Replication)让你把主库的数据变更实时同步到一台或多台从库上,是应对这两类问题最经典的方案。
它能解决什么
- 读写分离:写请求打到主库,读请求分摊到从库,横向扩展读性能。
- 热备与容灾:从库时刻保持一份准实时副本,主库宕机时可快速切换。
- 离线任务隔离:把报表、备份、大查询放到从库,不影响主库线上写入。
原理:binlog
MySQL 的复制建立在 binlog(二进制日志) 之上。主库把每一次数据变更写入 binlog,从库通过一个 I/O 线程把这些日志拉取过来落成 relay log,再由 SQL 线程重放,从而让自己的数据追上主库。整个过程是异步的,正常情况下延迟在毫秒级。
主库配置
先编辑主库配置文件(Ubuntu/Debian 一般在 /etc/mysql/mysql.conf.d/mysqld.cnf),开启 binlog 并设置唯一的 server-id:
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
改完重启服务:
sudo systemctl restart mysql
然后登录 MySQL,创建一个专供从库使用的复制账号,并授予 REPLICATION SLAVE 权限:
CREATE USER 'repl'@'%' IDENTIFIED BY 'StrongPass!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
记录当前主库的日志位点,后面配置从库时要用:
SHOW MASTER STATUS;
-- 记下 File(如 mysql-bin.000003) 和 Position(如 154)
从库配置
从库同样要设置一个不同的 server-id(例如 2),重启后在从库上执行连接命令。新版 MySQL(8.0.23+)推荐使用 REPLICA/SOURCE 语法,旧的 CHANGE MASTER TO / START SLAVE 仍可用但已弃用:
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '主库IP',
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'StrongPass!',
SOURCE_LOG_FILE = 'mysql-bin.000003',
SOURCE_LOG_POS = 154;
START REPLICA;
验证复制状态
在从库上查看状态:
SHOW REPLICA STATUS\G
重点看两行,必须都是 Yes 才算正常:
- ReplicaIORunning: Yes
- ReplicaSQLRunning: Yes
再关注 SecondsBehindSource,它表示从库落后主库的秒数,正常应接近 0。如果某行是 No,LastError 字段会给出具体原因。
常见坑
- server-id 冲突:主从(以及每台从库)的 server-id 必须全局唯一。重复会导致复制报错或诡异中断,这是最常见的错误。
- 初始数据不一致:START REPLICA 只会同步「从记录的位点之后」的增量。若主库已有历史数据,必须先用 mysqldump --single-transaction --source-data=2 导出并导入从库,再从导出时记录的位点开始复制,否则两边数据会永久错位。
- 网络与账号:确认防火墙放行 3306,复制账号的 host 允许从库 IP 连接。
小结
主从复制的核心就三步:主库开 binlog + 唯一 server-id + 建复制账号,从库用 CHANGE REPLICATION SOURCE 指向主库并 START REPLICA,最后用 SHOW REPLICA STATUS 确认两个线程都在跑。只要守住 server-id 唯一和初始数据一致这两条,就能在你的服务器上稳定跑起一套读写分离与热备架构。