BGP多线主机迁移血泪史:IP切换后数据库主从崩了?这份避坑指南救你一命
前言:别让BGP多线切换变成数据灾难
BGP多线主机的核心优势是网络冗余和低延迟,但IP地址变更或机房迁移时,数据迁移环节稍有不慎,轻则主从同步中断,重则数据丢失。本文不聊概念,直接拆解真实案例,给出可执行的命令和排错套路。
一、迁移前:DNS TTL和IP白名单是必填的坑
不要等切换后再改DNS。先降低源站DNS记录TTL(例如60秒),确保客户端快速感知新IP。同时检查源端和目标端的安全组/iptables:
# 检查源端iptables是否有永久IP白名单(例如CDN回源、监控系统)
iptables -L INPUT -n --line-numbers | grep ACCEPT
# 如果白名单写死了旧IP,迁后新IP会被拒绝
另外,BGP多线主机的广播IP通常依赖运营商路由表,迁移前务必向IDC确认新IP的BGP宣告是否完成。我曾见过新IP已配置但路由未生效,导致数据同步到一半中断。
二、数据迁移核心:数据库主从重搭的GTID陷阱
大多数新手直接mysqldump全量导出并导入新机,然后CHANGE MASTER TO,结果报错:Slave has more or less data than master。根源在GTID(全局事务标识符)不一致。
正确做法:使用mysqldump时保留GTID信息
# 源库导出(注意带上--master-data=2和--set-gtid-purged=ON)
mysqldump -u root -p --all-databases --single-transaction --master-data=2 --set-gtid-purged=ON --triggers --routines > dump.sql
# 目标库导入
mysql -u root -p < dump.sql
# 检查dump文件中记录的MASTER_LOG_FILE和MASTER_LOG_POS
head -50 dump.sql | grep "CHANGE MASTER TO"
很多教程忽略--set-gtid-purged=ON,导致新库GTID_PURGED为空,主从同步后立即报错。另外注意目标库的server_uuid必须与源库一致吗?不!必须不同,否则UUID冲突。迁移前先删除目标库的auto.cnf:
# 在目标库上
systemctl stop mysqld
rm -f /var/lib/mysql/auto.cnf
systemctl start mysqld # 自动生成新uuid
然后执行RESET MASTER;(只在从库/新库做)清理旧GTID信息。
三、BGP多线IP切换瞬间:ARP缓存与TCP连接保活
当新IP生效,旧IP会下线。如果迁移的是高并发业务,老机器上大量TCP ESTABLISHED连接会瞬间中断。解决方案:
- 迁移前在旧机器上先修改reuse端口和超时参数:
# 允许快速回收TIME_WAIT连接
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_fin_timeout = 15" >> /etc/sysctl.conf
sysctl -p
- 使用
tcpkill或iptables平滑杀掉旧连接(避免新机器收到残包):
# 在旧机器上只允许新连接7秒后超时
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 3306 -m state --state NEW -j DROP
sleep 7
iptables -F # 清空规则(实际建议更精细)
但更推荐用DNS轮询切换+健康检查,例如配合轻云互联的BGP多线负载均衡方案,让旧连接自然耗尽。
四、排错现场:同步断了,怎么快速定位?
主从同步报错Last_SQL_Errno: 1032(在从库找不到记录)或1062(主键重复)。别急着跳事务,先看GTID差距:
# 主库查看已执行GTID
SHOW MASTER STATUS\G
# 从库查看已执行和已接收
SHOW SLAVE STATUS\G
# 如果GTID_EXECUTED和GTID_PURGED差异大,手动补全
SELECT @@GLOBAL.GTID_PURGED;
-- 在从库手动设置(仅限确认丢失的事务不影响业务)
STOP SLAVE;
RESET SLAVE ALL;
SET @@global.gtid_purged = '源库的GTID列表';
CHANGE MASTER TO MASTER_HOST='新主库IP', MASTER_USER='...', MASTER_PASSWORD='...', MASTER_AUTO_POSITION=1;
START SLAVE;
注意:BGP多线主机的新IP如果通过内网互通(比如同机房),用内网地址做主从延迟更低。我曾遇到外网IP同步因带宽瓶颈延迟飙到300秒,换成内网IP后降为1秒。
五、文件同步:rsync + 硬链接增量你要会
除了数据库,应用代码、附件等海量小文件迁移,用scp会慢死。正确做法:
# 全量同步(先做一次)
rsync -avz --delete --progress /data/ root@新IP:/data/
# 增量同步(切断旧流量前再跑一次)
rsync -avz --delete --progress --link-dest=/data/ /data/ root@新IP:/data/
--link-dest参数能复用上一轮快照的硬链接,大幅减少传输量。经验:最后一步迁移时,先停掉旧机器的写服务,执行最后一次增量,然后切换DNS或更改BGP路由宣告。
六、终极验证:检查点清单
- 网络层:
traceroute新IP确保不走绕路;curl -w "@curl-format.txt" -o /dev/null -s测延迟。 - 数据库层:
SELECT * FROM performance_schema.replication_applier_status\G确认无错误。 - 应用层:模拟用户请求,检查session/cookie不因IP变更而丢失。
- 监控层:提前配置新IP的Zabbix/Prometheus,避免报警盲区。
迁移过程中如果业务允许降级,可临时放宽备份策略。最后提醒:不管是哪家IDC,BGP多线主机的迁移测试一定要在非业务高峰期做,并且保留旧机器至少24小时。不少新手图省事直接销毁旧机,结果发现新机内存不够、磁盘IO高,回滚无门。我常用轻云互联的BGP多线主机做迁移演练,他们支持同一账号下内网互通,配合快照秒级回滚,省去不少容错成本。