前面写过一篇关于使用drbd+corosync+pacemaker实现postgresql高可用的博客,其实drbd的对等节点如果不在线的话,即主节点的数据更改如果无法及时传送到备节点达到一定时间,会造成数据不一致,即使故障节点在长时间离线后恢复,drbd可能也不能正常同步了。或者另外一种情况,主备都在线,但心跳网络断了而出现脑裂,两个节点都认为自己是主节点,也会造成两个节点的数据不一致,这样需要人工干预,告诉drbd以哪个节点为主节点,或者在drbd配置脑裂的行为。下面是长时间备节点不在线后出现的情况:
备节点:
[root@pgtest4 ~]# cat /proc/drbd
version: 8.4.4 (api:1/proto:86-101)
GIT-hash: 74402fecf24da8e5438171ee8c19e28627e1c98a build by root@pgtest4, 2014-06-08 16:39:23
1: cs:StandAlone ro:Secondary/ Unknown ds:UpToDate/DUnknown r-----
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:57596
cs(连接状态)出现standalone,即孤立的
ro(角色)对等节点为unknown(非正常状态),本地节点为secondary(从节点)
ds(磁盘状态)是uptodate/dunknown,也是本地节点为处于正在更新状态,而对等节点为unknown状态。
从以上可以看出,备节点发生了drbd脑裂,注意,drbd的脑裂和集群的脑裂是两个概念,而此时的集群状态是正常的:
[root@pgtest3 ~]# crm status
Last updated: Fri Jun 27 08:34:28 2014
Last change: Fri Jun 27 08:34:22 2014 via crm_attribute on pgtest4
Stack: classic openais (with plugin)
Current DC: pgtest3 - partition with quorum
Version: 1.1.8-7.el6-394e906
2 Nodes configured, 2 expected votes
5 Resources configured.
Node pgtest4: standby
Online: [ pgtest3 ]
Master/Slave Set: ms_postgresql [postgresql]
Masters: [ pgtest3 ]
Stopped: [ postgresql:1 ]
pgresource (lsb:postgresql): Started pgtest3
pgstore (ocf::heartbeat:Filesystem): Started pgtest3
vip (ocf::heartbeat:IPaddr): Started pgtest3
即使使用crm node standby命令也可以正常把集群资源转移到pgtest4备节点上,但两个节点的数据已经不一致了。
所以此时要非常小心,如果使用pgtest4而且又有新数据进来,就会和pgtest3的数据冲突了,将来必须以一份数据为主,要么pgtest3,要么pgtest4,但数据都会丢一些,下面手工进行同步,以pgtest3为主,重新同步:
[root@pgtest4 ~]# drbdadm secondary r0 #首先让drbd节点配置为从节点
[root@pgtest4 ~]# drbdadm connect --discard-my-data r0 #从主节点同步数据,并且discard自己的数据
[root@pgtest4 ~]# cat /proc/drbd
version: 8.4.4 (api:1/proto:86-101)
GIT-hash: 74402fecf24da8e5438171ee8c19e28627e1c98a build by root@pgtest4, 2014-06-08 16:39:23
1: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
ns:0 nr:79104 dw:79104 dr:0 al:0 bm:26 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
现在状态就变成connect的了,ro也变成Secondary/Primary的了,这时再切换节点并连接pg查看数据,数据已经是一致状态了。
因此使用drbd做高可用要特别注意的一点就是:尽量保证主备同时在线,如果备节点需要维护等而长期不在线,当在线时最好手工同步下数据,不过如果没有配置资源粘性的话,很有可能资源会自动往主节点上跑,因此建议设置资源粘性,让资源在飘到一个节点上后就不动了,配置方法如下:
crm(live)# configure
crm(live)configure# rsc_defaults resource-stickiness=100
crm(live)configure# verify
crm(live)configure# commit
另附drbd的状态含义:
一个资源可能有以下连接状态之一:
StandAlone独立的:网络配置不可用。资源还没有被连接或者是被管理断开(使用drbdadm disconnect命令),或者是由于出现认证失败或者是裂脑的情况。
Disconnecting断开:断开只是临时状态,下一个状态将是StandAlone独立的。
Unconnected悬空:是尝试连接前的临时状态,可能的下一个状态为WFconnection和WFReportParams。
Timeout超时:与对等节点连接超时,也是临时状态,下一个状态为Unconected悬空。
BrokerPipe:与对等节点连接丢失,也是临时状态,下一个状态为Unconected悬空。
NetworkFailure:与对等节点失去连接后的临时状态,下一个状态为Unconected悬空。
ProtocolError. 与对等节点失去连接后的临时状态,下一个状态为Unconected悬空。
TearDown拆解:临时状态,对等节点连接关闭,下一个状态为Unconected悬空。
WFConnection.等待和对等节点建立网络连接。
WFReportParams:已经建立TCP连接,本节点等待从对等节点传来的第一个网络包。
Connected连接:Drbd已经建立连接,数据镜像现在可用,节点处于正常状态。
StartingSyncS:完全同步,有管理员发起的刚刚开始同步。未来可能的状态为SyncSource或PausedSyncS。
StartingSyncT:完全同步,有管理员发起的刚刚开始同步,下一状态为WFSyncUUID。
WFBitMapS:部分同步刚刚开始,下一步可能的状态:SyncSource或PausedSyncS。
WFBitMapT:部分同步刚刚开始,下一步可能的状态:WFSyncUUID。
WFSyncUUID:同步即将开始,下一步可能的状态:SyncTarget或PausedSyncT。
SyncSource:以本节点为同步源的同步正在进行。
SyncTarget:以本节点为同步目标的同步正在进行。
PausedSyncS:以本地节点是一个持续同步的源,但是目前同步已经暂停。可能是因为另外一个同步正在进行或者是使用命令drbdadm pause-sync暂停了同步。
PausedSyncT:以本地节点为持续的同步目标,但是目前同步已经暂停,这可能是因为另外一个同步正在进行或者是使用命令drbdadm pause-sync暂停了同步。
VerifyS:以本地节点为验证源的线上设备验证正在执行。
VerifyT:以本地节点为目标源的线上设备验证正在执行。