DRBD的元数据实现:GI元组的原理

一、GI元组

DRBD使用代标识GI tuple来确定复制数据的“代”,通过GI tuple,DRBD可以确定两个节点是不是属于同一集群的事实(而不是意外连接的两个节点),确定重新同步时同步的方向(如果必要的话) ,确定是完全重新同步或者是部分重新同步是否满足需求以及确认是否发生了裂脑。因此,GI的使用在DRBD的算法中是非常重要的。

GI元组(GI tuple)由一个CurrentUUID、一个BitmapUUID和两个HistoryUUID组成,每个新的数据生成的标识都由一个8字节的、全局唯一的标识符(UUID)标志。如下图所示:

  • CurrentUUID:当前数据代的UUID,当一个资源连接并完全同步即磁盘状态为UpToDate时,两节点之间的UUID是相同的。
  • BitmapUUID:磁盘的同步位图的变化跟踪代的UUID。只有在断开模式磁盘上的同步位图才与该标识符有关。如果资源是连通的,此UUID总是空。
  • HistoryUUID:用于保存前几代的两个数据的标识符。

DRBD的元数据实现:GI元组的原理

一般来说,会有如下三种情况下,DRBD会产生一个新的GI数据代:

  • 最初设备的初始化完全同步
  • 一个断开连接的资源切换到主角色(Primary)
  • 主角色的资源断开连接

 

注意,只要资源处于连接状态,且两个节点的磁盘状态为UpToDate,那么目前两个节点上的GI元组就是相同的。

二、GI元组的变化过程

DRBD的元数据实现:GI元组的原理

 

三、通过GI元组识别集群节点的状态

(1) 新配置的资源

特征:两个节点上的currentUUID为空

DRBD的元数据实现:GI元组的原理

一个新配置的资源,没有进行完整设备初始同步。

必须手动启动。

 

(2) 初始节点建立网络连接

特征:本地节点有currentUUID,对等节点currentUUID为空。

DRBD的元数据实现:GI元组的原理

当节点间建立连接后,两节点交换GI tuple表示状态。

这是一个新配置的资源
刚启动初始设备完全同步的正常情况
此时,本地节点被选中作为初始同步源
DRBD设置磁盘上的同步位图(这意味着它进行整个设备同步)的所有位。并开始作为一个同步源进行同步。

 

(3) 本地节点Node1为Primary,Node2为Secondary时,Secondary节点故障

特征:当前节点的BitmapUUID与对等节点的CurrentUUID一致,且对等节点的的BitmapUUID为空。

DRBD的元数据实现:GI元组的原理

当前节点为主节点,对等节点为次节点
次节点发生故障
这意味着在此期间对等节点从来没有升级为Primary,并在相同的数据生成的基础上都单独工作。
现在DRBD正常启动后,本地成为同步源节点,后台重新同步。

 

(4)两个节点共有一个祖先UUID,且对等节点有最新的数据

特征:当前节点的CurrentUUID与对等节点的HistoryUUID之一相同

DRBD的元数据实现:GI元组的原理

 

两个节点共有一个祖先UUID
对等节点有最新的数据,但是保存在对等节点Bitmap中的数据是过时和不能被使用的。
此时,一个正常的同步是不够的。
需要本地节点作为同步目标,DRBD标识整个设备out-of-syn,并初始化全部进行重新同步

 

(5)裂脑情况1

特征:本地节点的CurrentUUID 和对等节点的CurrentUUID不同,而两节点BitmapUUID的匹配

DRBD的元数据实现:GI元组的原理

 

这就是裂脑,split-brain
此时前一个数据代是相同的父代。
可以调用裂脑自动恢复策略(如果有配置),否则,DRBD断开连接,并等待人工脑裂进行处理。

(6)裂脑情况2

特征:两节点的CurrentUUID 和BitmapUUID都不匹配。

DRBD的元数据实现:GI元组的原理

这也裂脑且不是相同的父代(ancestor generations)
此时,即使配置自动恢复策略,也没有用。
DRBD将断开连接,并等待人工脑裂进行处理。

(7) 集群中两个彼此之间并不认识节点
特征:两个GI元组没有一个匹配的UUID

DRBD的元数据实现:GI元组的原理

这是DRBD意外连接集群中两个彼此之间并不认识节点。
DRBD仅记录一个无关数据的警告log,然后断开连接。

来源:https://my.oschina.net/u/658505/blog/651600