一、主从切换的那些事儿
数据库主从切换就像接力赛跑,主库(Master)突然摔倒时,从库(Slave)必须稳稳接过接力棒,还要保证数据不丢、不乱。这个过程的核心挑战是:如何在切换时确保数据一致性?
举个实际场景:某电商平台大促时,主库扛不住压力宕机了,运维团队需要快速切换到从库。但如果切换过程中有订单数据丢失,用户付了钱却没生成订单,那可就出大事了。
二、数据一致性的三大保障机制
1. 半同步复制(Semisynchronous Replication)
MySQL的半同步复制要求主库执行事务后,至少一个从库接收并写入relay log才返回成功。这就像你寄快递,快递员必须亲口告诉你“对方签收了”才算完成。
-- 在主库上启用半同步复制(MySQL 5.7+示例)
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 3000; -- 超时3秒后降级为异步
-- 在从库上启用插件
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
注意:如果从库延迟超过超时时间,主库会退化为异步复制,此时需要监控报警。
2. GTID全局事务标识
GTID(Global Transaction Identifier)给每个事务分配唯一ID,像快递单号一样追踪数据流向。切换时,从库只需确认自己执行到了哪个GTID即可。
-- 查看主从库的GTID执行状态(MySQL 5.6+)
SHOW MASTER STATUS\G -- 主库当前GTID
SHOW SLAVE STATUS\G -- 从库已接收的GTID
-- 切换后从库追平数据的命令
CHANGE MASTER TO
MASTER_HOST='new_master_ip',
MASTER_AUTO_POSITION = 1; -- 启用GTID自动定位
3. 数据校验工具pt-table-checksum
Percona的pt-table-checksum可以在切换前静默比对主从数据差异,像会计对账一样逐行核对:
# 安装Percona工具包后执行校验(示例)
pt-table-checksum \
--host=主库IP --user=校验用户 \
--recursion-method=dsn=D=test,t=dsns \
--no-check-binlog-format
输出解读:DIFFS列显示不一致的行数,需优先修复差异再切换。
三、完整切换流程实战
假设我们使用MySQL 8.0,从192.168.1.100切换到192.168.1.101:
- 预检查阶段
-- 在主库锁定写入(维护窗口期)
FLUSH TABLES WITH READ LOCK;
SET GLOBAL read_only = ON;
-- 在从库确认延迟为0
SHOW SLAVE STATUS\G
-- 确保 Seconds_Behind_Master = 0
- 切换操作
# 在从库提升为主库
STOP SLAVE;
RESET MASTER;
SET GLOBAL read_only = OFF;
# 修改应用连接串
# 旧:jdbc:mysql://192.168.1.100:3306
# 新:jdbc:mysql://192.168.1.101:3306
- 事后验证
-- 在新主库创建测试数据验证
CREATE TABLE switch_test(id INT);
INSERT INTO switch_test VALUES(1);
-- 在其他从库查询是否同步
四、避坑指南与进阶策略
常见坑点
- 脑裂问题:原主库恢复后未设为只读,导致双主写入。解决方案:
-- 在原主库恢复时强制设为只读 SET GLOBAL super_read_only = ON; - 大事务延迟:一个事务更新10万行数据会导致从库卡住。建议拆分为小事务。
增强方案
- 延迟从库:故意配置一个延迟1小时的从库,用于误操作回滚:
CHANGE MASTER TO MASTER_DELAY = 3600; - MGR集群:MySQL Group Replication提供更高一致性的多主架构,但复杂度较高。
五、总结
主从切换不是简单的IP切换,而是一套包含状态监控、数据校验、流量控制的系统工程。就像飞机迫降需要检查清单一样,每个步骤都必须严格执行。选择半同步+GTID+定期校验的组合拳,能兼顾性能与可靠性。
最后记住:永远要有预案B——比如提前准备好延时从库,或者使用ProxySQL实现自动流量切换。
评论