drbd+pacemaker实现数据库高可用的问题总结

前面的一篇文章记录下drbd+pacemaker+corosync实现postgresql数据库的高可用(参考 这里),经过一段时间的测试和测试环境使用,总结下遇到的问题。

1.drbd的脑裂问题。
drbd脑裂是指当两个节点(假设只有两个节点)因为网络问题或某一个节点的主机故障等问题,造成数据不能实时同步,就会产生脑裂,drbd脑裂在drbd配置文件的net部分有三个场景,并分别有相应的自动处理策略:

after-sb-0pri:这个场景是因为网络故障等原因,现在有0个primary节点,即两个节点都处于从状态,此时两个节点可能都有了新数据(这时候是很糟糕的,两个节点都有数据了,但又不能合并,必须确定一个主节点,并让另一个节点以此为准同步数据),那以谁的数据为准呢?必须要有所取舍了,此时的处理策略有如下几种:
disconnect:直接退出集群,即两个节点均不再参与数据同步,成为孤立节点
discard-younger-primary:丢弃最先的主节点数据,也即是最后成为主节点的节点为新的主节点
discard-least-changes:谁的数据改变最少则谁被抛弃,也即是谁的改变多以谁为主节点
discard-zero-changes:没有改变数据的节点被抛弃,也就是说如果某个节点没有改变数据,说明这个节点发生了故障,要作为从节点。

after-sb-1pri:这个场景是发生脑裂后,现在有1个主节点,另一个节点要么丢弃现有的数据,并以另一个节点为主进行数据同步,要么采用别的办法,如disconnect,策略有如下几种:
disconnect:和上面的解释相同,直接退出drbd集群,不再参与数据同步
consensus:和after-sb-0pri的处理策略相同
call-pri-lost-after-sb:也和after-sb-0pri的处理策略相同,但如果有配置handler脚本的话执行脚本进行处理
discard-secondary:把此节点直接当做脑裂受害者,把另一个节点当做主节点进行数据同步,注意,如果此节点有新数据的话也直接丢弃了。

after-sb-2pri:这个场景是有两个节点都是主节点的情况,处理策略和上面的一个差不多,只是没用了discard-secondary 和 consensus策略,因为两个都是主节点了,就没用所谓的丢弃从节点的策略。

介绍完上面的三种策略,我们就要根据场景来选择了,比如数据库同步场景,我们想让数据最安全,当发生网络故障、某一个节点主机故障等情况,要做到不丢数据,最保险的做法是三个节点都采用disconnect,即直接退出集群不再同步,不丢弃任何数据,但集群切换后,需要手工修复,即要dba人工确定哪个节点的数据时主节点,并把另一个节点作为从节点进行数据同步(方法见 这里)。配置如下:
net {
after-sb-0pri discard-zero-changes;
        after-sb-1pri disconnect;
        after-sb-2pri disconnect;
}
如果数据不是很重要,不涉及金融数据,想让某台节点故障后自动进行数据同步,可以采用如下策略:
net {
after-sb-0pri discard-zero-changes;
        after-sb-1pri discard-secondary;
        after-sb-2pri disconnect;
}
这样当一台机器挂掉后另一台启动后可以自动以另一台为主节点进行数据同步而不需要手工数据同步。

2.和pacemaker配合时的问题
使用pacemaker来做集群故障切换时,会遇到另一个问题,当两个节点发生脑裂后,如现在两个都是从节点,且两个从节点的数据目前不处于同步状态,pacemaker也会切换的,这时候会因为pacemaker启动了陈旧的数据而造成数据不一致,这个场景可能发生在这种情况:
1.两台主备节点正常运行,数据处于drbd同步状态
2.一台主节点挂掉了,从节点接替了主节点,然后有新数据进来了,这时主节点处于离线状态,新数据现在只在一个节点上有,这时就出现不一致数据状态
3.这时从节点也挂掉了
4.这时原来的主节点修复好了,这时pacemaker会启动主节点的资源,这时又一部分新数据进来,到了原来的主节点上
5.这时原来的从节点修复好了,这时候就两个节点都有一部分新数据,造成了数据不一致
为了避免这种情况,需要采用如下办法:
在drbd的disk配置部分,加入如下配置:
disk { 
on-io-error detach; 
fencing resource-only;
}
handler部分要加入如下配置:
handlers { 
split-brain "/usr/lib/drbd/notify-split-brain.sh root";
pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-
trigger ; reboot -f"; 
pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-
trigger ; reboot -f"; 
local-io-error "/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; 
halt -f"; 
fence-peer "/usr/lib/drbd/crm-fence-peer.sh"; 
after-resync-target "/usr/lib/drbd/crm-unfence-peer.sh";
 其中红色部分就是当脑裂发生时,pacemaker要调用的脚本和节点恢复后的数据恢复脚本。
加上这段后,如果某一个节点处于离线,另一个节点再发生离线,先前的节点即使修复了也不会让他作为主节点启动的,因为pacemaker认为此节点数据是outdate(过时的)数据,pacemaker会一直等待直到有最新数据的节点修复后才能启动资源,这样是最安全的。

3.drbd的空间扩展。
drbd资源扩展起来有如下几个方法:
1.新建一个drbd资源,然后加入pacemaker集群管理器中进行资源管理,不过数据库要用这个新盘的话就要用表空间之类的方式了,原来的磁盘是多大就多大。
2.创建lvm作为底层drbd磁盘,如果有空间扩展需要,在主备节点均新增同样大小的磁盘并加入lvm中。但要注意的是drbd资源需要手工调整下才能重新认识到新加的磁盘:
 #drbdadm resize datatest
这样drbd能认到新的底层lvm磁盘
但正在挂载使用的文件系统不会立即更改大小的,可以用如下办法在线扩展文件系统大小:
[root@db173 ~]# resize2fs /dev/drbd3 
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/drbd3 is mounted on /test; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/drbd3 to 786399 (4k) blocks.
The filesystem on /dev/drbd3 is now 786399 blocks long.

其他方案如德哥的github的高可用方案也很好( https://github.com/digoal/sky_postgresql_cluster),不过需要外部硬件如戴尔的idrac的ipmi远程关机功能支持,而解决了drbd脑裂问题,就可以放心使用这种方案了。

你可能感兴趣的:(数据库,drbd,pacemaker)