前几天,我们的linux-HA 的主从数据库同时poweroff 了
系统宕机,
在6月份也莫名其妙的发生过一次,当时不得其解,将其归结为偶然事件。
这次再发生就不能放过了,可以用重现,说明问题是存在的。
问题发生后,我们的猜测: 1 是 主机ipmi 部件有bug,在特定条件下无法响应 fence设备的请求,导致发送了reboot命令后
impi设备只执行了poweroff 或者就干脆 fence设备,解析错了pacemaker 的指令, 吧reboot 解析为poweroff
2 fence设备对reboot 命令的执行不是原子的,即需要向主机ipmi设备提交两次指令,先提交poweroff 然后再提交poweron 指令
strace 了 fence-ipmilan 的执行发现他是通过调用 impitool 的lib库来执行的,而不是直接调用ipmitool 这个client命令来执行,
把我们当初设想的,为ipmitool 写个shell 来包装的做法给否决了。
那么就只有查看fence_ipmilan的源代码来分析了。
通过查看源代码,就是这里了,印证了我们的猜测,fence-ipmilan 是对reboot 的操作不是原子的,而是分拆为两个命令来提交到主机的ipmi模块。
到这里 ,我们就可以反推出当时主机同时宕机的原因了。
先是是主库 发现从库 离线,然后启动fence设备去reboot 从库,对从库发送了reboot命令,但是当只提交了一个poweroff 的时候,
这个时候从库也发现了主库离线了,从库也启用fence设备去reboot 主库,这个时候,主库还在等待,ipmi 返回poweroff 的执行状态,
还没有向从库提交poweron 的指令,所以从库就直接poweroff 了,而主库的ipmi设备接收了从库的reboot命令只完成了poeeroff ,
但是从库已经被主库关机了,这个时候,它已经无法发出剩下的那个poweron请求了。
从这里我们猜测当时应该是集群发生脑裂了。 两台机器同时认为对方发生了离线了,需要把对方fence 掉。
而且对端主机的对reboot 的返回,都没有完成,就出现这个问题了。
关于解决方案, 双机模式下,确实发生脑裂的几率会大很多,
目前想到的一个比较可行的方案: 对其中一台fence设备,设置一个合适的时间间隔,等待一个时间后,再fence掉对方,
而另一台机器则直接fence 对方的机器,这样即使发生了脑裂,应该只有一台机器会把对方fence掉
这里可能会发生一个情况,对方机器启动后, 会继续fence对方,还是要经过双方都要重启一次。
另一个方案是只部署一个fence设备,只fence 一台机器,但是这个情况需要测试。
经过测试,这个方式是可行的,一台机器利用delay 选项 演示fence 另一台机器直接fence 可以解决这个问题。
系统宕机,
在6月份也莫名其妙的发生过一次,当时不得其解,将其归结为偶然事件。
这次再发生就不能放过了,可以用重现,说明问题是存在的。
问题发生后,我们的猜测: 1 是 主机ipmi 部件有bug,在特定条件下无法响应 fence设备的请求,导致发送了reboot命令后
impi设备只执行了poweroff 或者就干脆 fence设备,解析错了pacemaker 的指令, 吧reboot 解析为poweroff
2 fence设备对reboot 命令的执行不是原子的,即需要向主机ipmi设备提交两次指令,先提交poweroff 然后再提交poweron 指令
strace 了 fence-ipmilan 的执行发现他是通过调用 impitool 的lib库来执行的,而不是直接调用ipmitool 这个client命令来执行,
把我们当初设想的,为ipmitool 写个shell 来包装的做法给否决了。
那么就只有查看fence_ipmilan的源代码来分析了。
1 | if (!strcasecmp(op, "reboot")) { printf("Rebooting machine @ IPMI:%s...", ip); fflush(stdout); if(!strcasecmp(method, "cycle")) { ret = ipmi_op(i, ST_STATUS, power_status); |
2 | if (ret == STATE_OFF) { /* State is off -> use onoff method because cycle is not able to turn on*/ snprintf(method, sizeof(method), "onoff"); } } |
3 | if (!strcasecmp(method, "cycle")) { ret = ipmi_cycle(i); } else { /* Original onoff method */ ret = ipmi_off(i); translated_ret = (ret==0?ERR_OFF_SUCCESSFUL:ERR_OFF_FAIL); if (ret != 0) { goto out; } ret = ipmi_on(i); } |
到这里 ,我们就可以反推出当时主机同时宕机的原因了。
先是是主库 发现从库 离线,然后启动fence设备去reboot 从库,对从库发送了reboot命令,但是当只提交了一个poweroff 的时候,
这个时候从库也发现了主库离线了,从库也启用fence设备去reboot 主库,这个时候,主库还在等待,ipmi 返回poweroff 的执行状态,
还没有向从库提交poweron 的指令,所以从库就直接poweroff 了,而主库的ipmi设备接收了从库的reboot命令只完成了poeeroff ,
但是从库已经被主库关机了,这个时候,它已经无法发出剩下的那个poweron请求了。
从这里我们猜测当时应该是集群发生脑裂了。 两台机器同时认为对方发生了离线了,需要把对方fence 掉。
而且对端主机的对reboot 的返回,都没有完成,就出现这个问题了。
关于解决方案, 双机模式下,确实发生脑裂的几率会大很多,
目前想到的一个比较可行的方案: 对其中一台fence设备,设置一个合适的时间间隔,等待一个时间后,再fence掉对方,
而另一台机器则直接fence 对方的机器,这样即使发生了脑裂,应该只有一台机器会把对方fence掉
这里可能会发生一个情况,对方机器启动后, 会继续fence对方,还是要经过双方都要重启一次。
另一个方案是只部署一个fence设备,只fence 一台机器,但是这个情况需要测试。
经过测试,这个方式是可行的,一台机器利用delay 选项 演示fence 另一台机器直接fence 可以解决这个问题。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/133735/viewspace-1068927/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/133735/viewspace-1068927/