问题

我们经常使用浮动 IP(SIP,或叫 VIP),来完成数据库的高可用部署。业务通过访问浮动 IP,始终访问主数据库。

如果业务正在访问数据库时,数据库主从发生切换,导致 SIP 漂移,那正在使用的数据库连接会受到影响么?

实验

我们创建同子网的两台虚拟机,分别安装 MySQL。

再准备一台额外的虚拟机,用来模拟业务,访问数据库,此处省略安装过程。

下图以 37 为例,这里设置了 PS1,并确认机器上有创建好数据库,

39 与之类似:

我们再选取一个 SIP: x.x.x.200,将其绑定到 37 上,

向子网进行 arp 宣告,通知大家 ip 变更了:

现在业务机器上,测试一下访问 SIP 成功:

我们在数据库中用 sysbench 灌入数据,此处省略步骤,只看结果:

然后向数据库执行一个 select,这里我们用了一个 sleep,使得数据库返回结果集慢一些,大概每秒输出 1000 行左右:

执行 SQL 后,MySQL 客户端会不停输出结果,如果发生了任何连接问题,我们可以立刻发现。
现在让 SIP 发生一次切换。准备好如下命令:先在 37 上卸下 SIP,再在 39 上加上 SIP,发送 arp 宣告。
准备好命令后,开始拼手速,让命令以很短的时间先后执行。
执行后,会发现业务机上跑的 select 输出停了,会停很久以后,
我们来看看这个现象的原理:
在 37 上,我们可以找到这根连接:

几十秒后,进入 FIN-WAIT-1 阶段,也就是说 37 已经感知到这根连接不太对,再 48 秒后,会关闭这根连接:

而此时在业务机器上,这根连接依然存在,会在 116 分钟以后,探测 tcp keepalive 失败后,才感知到连接出问题:

我们试着将业务机的 tcp keepalive 间隔调小一点,看看能不能让业务机更快感知到连接出了问题:

再重做一下实验,会发现几秒钟后,MySQL client 就会感知到连接出了问题:

我们来抓个包看看:

重做试验,用 Wireshark 打开抓包结果:

可以看到 SIP 切换后,TCP Keepalive 包发往了交换机,但没有收到应答包。当超过 TCP Keepalive 的指定次数后,应用机器感知到了连接错误,发起了 RST 断开连接。
也就是说:当 SIP 发生切换时,旧连接发出的包已经被丢弃了,旧连接会一直等待应答,所以需要 TCP keepalive 这种主动探测机制,才会探测到无应答的状况。

小贴士

当应用连接到数据库时,建议要配置 TCP keepalive 功能,并且间隔要调小到业务能接受的范围内。默认的 TCP keepalive 的间隔是几小时才能感知故障。

但是:不要模仿实验中这样,调整操作系统级别的 TCP Keepalive 参数。应在应用建立连接时将 TCP keepalive 参数配置在连接级别。

关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!