主从复制架构:MySQL主从复制的部署流程与常见问题
主从复制这东西,说白了就是让两台MySQL服务器保持数据同步。一台写数据(主库),另一台或者几台只负责读(从库)。为什么这么做?你想想看,如果所有读写都压在一台机器上,哪天它挂了,整个业务就瘫了。我见过不少团队,刚开始觉得单库够用,结果流量一上来,读写全堵在那,直接雪崩。
我的经验是,主从复制是架构中最基础、也最实用的高可用手段。虽然现在有各种新方案,但主从复制依然是运维人的看家本领。今天咱们就围绕三个核心点展开:怎么部署、常见坑怎么踩、状态怎么监控。
1. 环境准备:确认版本与网络
我个人习惯在正式部署前,先检查两件事。第一,主库和从库的MySQL版本是否一致。我遇到过版本不一样导致数据类型转换出错的情况,折腾了大半天才发现问题。第二,主从之间的网络连通性,尤其注意防火墙和端口。MySQL默认端口是3306,从库需要能直接连接到主库。
2. 配置主库:开启Binlog并设置server-id
主库要能记录所有数据变更,靠的就是Binary Log(简称Binlog)。配置很简单,修改my.cnf,加上以下几行:
[mysqld]
log-bin=mysql-bin
server-id=1
binlog-format=ROW
expire_logs_days=7
max_binlog_size=256M
server-id 这个值必须在集群内全局唯一。我习惯用IP最后一段做编号,比如172.16.1.10就设成10,方便维护,不容易撞车。Binlog格式我推荐用ROW,它按行记录变更,虽然日志会大一些,但数据一致性最好。STATEMENT格式省空间,但遇到不确定函数时容易产生主从不一致。我踩过那个坑,后来再也不敢用STATEMENT了。
3. 创建复制用户
主库上专门创建一个用户,供从库连接拉取Binlog,权限只要REPLICATION SLAVE就够了,别给super或者all privileges,安全第一。
CREATE USER 'repl'@'%' IDENTIFIED BY 'StrongPassword';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
密码复杂度建议符合公司安全规范。我曾经犯过用简单密码的错,结果被扫到弱口令,从库IP被人用来发起复制攻击,幸好及时发现没有造成数据泄露。
4. 配置从库:连接主库启动复制
从库的my.cnf相对简单:
[mysqld]
server-id=2
relay-log=mysql-relay-bin
read_only=1
skip-slave-start=ON
read_only=1 是防止有人在从库上误写数据,导致数据不一致。skip-slave-start 我建议开启,避免MySQL重启后自动尝试复制,方便你先确认状态再手动启动。
现在,去从库执行CHANGE MASTER命令:
CHANGE MASTER TO
MASTER_HOST='主库IP',
MASTER_USER='repl',
MASTER_PASSWORD='StrongPassword',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
START SLAVE;
这里的MASTER_LOG_FILE和MASTER_LOG_POS需要从主库查:在主库执行SHOW MASTER STATUS;,记下File和Position的值。很多新手忘了这一步,导致从库找不到起点,复制失败。
5. 验证复制状态
在从库上运行:
SHOW SLAVE STATUS\G
你看输出,重点关注两个字段:
Slave_IO_Running:是不是YesSlave_SQL_Running:是不是Yes
如果两个都是Yes,恭喜你,主从复制已经跑起来了。我习惯每隔几分钟用脚本扫一遍从库状态,一旦看到No就立刻报警,别等问题发酵。
常见问题与避坑指南
部署完成不代表万事大吉,实际运维中问题多得很。我把自己踩过的雷列出来,你对照着看:
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| Slave_IO_Running: No | 网络不通、用户名密码错误、主库Binlog被清理 | 检查连通性、确认MASTER配置、调整expire_logs_days |
| Slave_SQL_Running: No | SQL语句冲突(主键重复、表不存在) | SHOW SLAVE STATUS看Last_Error,手动修复后STOP SLAVE; SET GLOBAL sql_slave_skip_counter=1; START SLAVE; |
| 复制延迟增长 | 从库性能不足、大事务、网络带宽不够 | 升级从库硬件、拆分大事务、开启并行复制(slave_parallel_workers) |
| 数据不一致 | 主库使用了不确定函数、从库被写数据 | 生产环境用ROW格式、确保从库read_only |
分享一个真实案例。有一次我遇到从库SQL线程一直报错,Last_Error显示在主库删了一条记录,但从库对应表里没有这条数据,所以删失败。这种情况其实是因为从库之前被手动插入了相同主键的数据,主库删的时候从库找不到。我当时用SET GLOBAL sql_slave_skip_counter=1跳过去,后续用pt-table-checksum工具完整校验了数据一致性,才彻底恢复。
关于复制延迟的深入理解
你可能会问,为什么从库的Seconds_Behind_Master有时候很大?其实它计算的是SQL线程落后主库的时间。如果主库突然写了几十万行数据,Binlog里一条记录,从库SQL线程要一条条重放,肯定慢。
我在项目中遇到最夸张的一次,延迟达到15分钟。排查后发现是主库在做大表ALTER操作,产生的Binlog太大,从库SQL线程处理不过来。后来我做了一个优化:把大ALTER拆成小批次执行,比如每次只改几千行,同时给从库开启并行复制(slave_parallel_workers设为4),延迟立刻降到了秒级。
还有一个细节:Seconds_Behind_Master在某些场景下不准确。比如主从时钟不同步,这个值就是虚的。所以我更建议用SHOW MASTER STATUS和SHOW SLAVE STATUS中的Binlog坐标对比来算真实延迟,或者用第三方工具。
主从切换的简单思路
虽然在第三章节我们主要讲部署,但我还是想提一句切换。如果你需要把从库提升为主库,流程大致是:停止从库复制 → 确认从库追上主库数据 → 在从库上STOP SLAVE; RESET MASTER; → 更改应用连接指向新主库。但我建议在切换前先做一次从库数据校验,确保没有丢事务。这步我吃过亏,切换完发现少了几天数据,最后只能从备份恢复,血泪教训。
好,关于主从复制的部署流程和常见问题,今天就聊到这儿。记住,复制不是一锤子买卖,上线后要持续监控、定期巡检,才能让你的数据库架构真正扛得住压力。