drbd快速部署:

DRBD的3种协议: 协议A:异步复制协议。本地写成功后立即返回,数据放在发送的buffer中(可能会丢失) 协议B:半同步复制协议。本地写成功后,将数据发送到对方后(是否写入不考虑)立即返回 协议C:同步复制协议。本地和对方服务器磁盘都写成功确认后返回成功

生产环境使用协议C,使用不同的协议影响网络流量,从而影响网络时延 ** DRBD的企业应用场景:** heartbeat+drbd+nfs/mfs/gfs
heartbeat+drbd+mysql/oracle 即涉及到到数据库时结合heartbeat使用(使用heartbeat的第二种方式,即使用heartbeat同时转移VIP和应用服务,参考heartbeat的快速部署)

实验环境(仍然以之前的heartbeat两台主备节点作为drbd服务的主备节点): 主节点: eth0 10.0.0.75 mheartbeat.com 管理IP,用于wan数据转发,mheartbeat.com是主机名 eth1 172.16.1.75 用于服务器之间心跳线直连(做) VIP 10.0.0.77 提供程序A挂载服务

备节点: eth0 10.0.0.76 sheartbeat.com 管理IP,用于wan数据转发,sheartbeat.com是主机名 eth1 172.16.1.76 用于服务器之间心跳线直连 VIP 10.0.0.88 提供程序B挂载服务

管理IP分别是10.0.0.75(mheartbeat.com)和10.0.0.76(sheartbeat.com)

目标:主备分别配置好drbd服务后,实现在主节点上的/dev/sdb写数据,数据会实时同步到备节点的另一块磁盘上。 一旦主节点宕机或硬盘损坏导致数据不可用,备节点上的数据可以顶上,因为是完整备份。不仅仅是一个完整备份,结合其它服务,还可以瞬间接替损坏数据或宕机的主节点,实现了数据的异机实时同步,从而达到数据高可用不影响业务的目的。

注意:drbd主备模式,即应用时仅有主节点端写入数据,备节点端处于数据热备状态,备节点drbd的分区是不可见的(未格式化,未挂载,处于非活动状态,不能人为写入数据) 多drbd分区主主的双向同步模式,实际生产环境中,也可配置主主模式: 即在主的一端一个分区写入数据,备的一端仅处于数据同步状态。 备的一端另一个分区可以作主,原来的主的一端另一个分区作为备

drbd服务通过直连线或以太网实时互相数据同步

生产环境中,drbd一般不会单独使用,而是和一些软件配合使用,如nfs、mfs等。nfs或mfs利用drbd的特性进行两台数据存储服务器间的实时同步。加上高可用工具heartbeat,可以实现共享存储服务器的高可用性。此时heartbeat会通过串口线后直连线对存储服务器做健康检查,同时控制drbd、nfs、VIP等资源的动态切换(使用heartbeat的第二种方式)。一端出现故障时,进行资源的自动转移,确保业务高可用的目的。

1、关闭防火墙和selinux

2、配置主机名解析(两台都要配置)

cat >> /etc/hosts<<end mheartbeat.com 172.16.1.75 sheartbeat.com 172.16.1.76 end

ping的结果必须和uname -n 相同

3、配置时间同步

echo "#time sync" echo "*/5 * * * * /usr/sbin/ntpdate time1.aliyun.com &> /dev/null" >> /var/spool/cron/root

4、添加主机路由

mheartbeat.com上:route add -host 172.16.1.76 dev eth1
sheartbeat.com上:route add -host 172.16.1.75 dev eth1 #heartbeat心跳信息专用,本节也用于drbd数据同步通道,生产环境中heartbeat心跳信息独享,单独配置一块网卡给drbd使用

5、磁盘分区

在mheartbeat.com上分出一块1G大小的分区,分成2个区 [root@mheartbeat ~]# fdisk /dev/sdb Command (m for help): p Disk /dev/sdb: 1073 MB, 1073741824 bytes Device Boot Start End Blocks Id System Command (m for help): n Command action e extended p primary partition (1-4) p

Partition number (1-4): 1 First cylinder (1-130, default 1): 1 Last cylinder, +cylinders or +size{K,M,G} (1-130, default 130): +800M

Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (104-130, default 104): Using default value 104 Last cylinder, +cylinders or +size{K,M,G} (104-130, default 130): 129

Command (m for help): p

Disk /dev/sdb: 1073 MB, 1073741824 bytes Disk identifier: 0x9cfe88e8 Device Boot Start End Blocks Id System /dev/sdb1 1 103 827316 83 Linux /dev/sdb2 104 129 208845 83 Linux Command (m for help): w [root@mheartbeat ~]# partprobe

在sheartbeat.com上分出一块2G大小的分区,分成2个区 使用同样的方法在备节点的sdb上也分出两个分区: [root@sheartbeat ~]# fdisk /dev/sdb Command (m for help): p Disk /dev/sdb: 2147 MB, 2147483648 bytes Device Boot Start End Blocks Id System /dev/sdb1 1 230 1847443+ 83 Linux /dev/sdb2 231 260 240975 83 Linux

6、分别在主备节点上安装drbd

使用yum安装需要先配置elrepo源 rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm

法一:yum install drbd84-utils kmod-drbd84 -y #安装过程有点慢 法二:编译安装 上传drbd-8.4.4.tar.gz源码包 tar xf drbd-8.4.4.tar.gz cd drbd-8.4.4 ./configure --prefix=/application/drbd-8.4.4 --with-kvm --with-heartbeat --sysconfdir=/etc/ make KDIR=/usr/src/kernels/$(uname -r)/ make install

#不管是yum安装还是编译安装都要加载drbd模块到内核 lsmod |grep drbd modprobe drbd lsmod |grep drbd

echo "modprobe drbd" >> /etc/rc.local tail -1 /etc/rc.local

[root@mheartbeat ~]# cat /etc/drbd.conf

You can find an example in /usr/share/doc/drbd.../drbd.conf.example

include "drbd.d/global_common.conf"; include "drbd.d/*.res";

可以看出,drbd的配置文件被分成两个部分,且在/etc/drbd.conf文件中加载这两个配置文件: global_common.conf中主要定义global段和common段,文件必须要以.conf结尾,在/etc/drbd.conf文件中使用include加载 *.res文件是资源配置文件,文件名称无所谓,但扩展名必须是.res,在/etc/drbd.conf文件中使用include加载

也可以不加载这两个文件,仅使用/etc/drbd.conf这一个配置文件,所有的配置都写入到这一个文件中,如果所有配置都写入到这一个配置文件中,global段仅能出现一次,且global段必须位于配置文件的最开始处

7、配置drbd

配置文件详解: cat /etc/drbd.conf

You can find an example in /usr/share/doc/drbd.../drbd.conf.example

#include "drbd.d/global_common.conf"; #include "drbd.d/*.res"; #将这两行加载文件的配置注释掉,所有配置全部集中到这一个文件中

global { #minor-count 64; #设定允许定义从(设备)的个数(1~255),默认32,当要定义的resource超过此选项的设定,需要重新载入drbd内核模块 #dialog-refresh 5; #设定为0或正数,默认值为1 #disable-ip-verification; #是否禁用ip检查验证 usage-count no; #不让linbit公司收集目前drbd的使用情况 }

common { #这个部分里设置的一些配置可以被配置的每个资源所继承。 protocol C;

disk { #精细地调节drbd底层存储的属性 on-io-error detach; no-disk-flushes; no-md-flushes; }

net { #精细地调节drbd的网络相关的属性

sndbuf-size 512k;				
#调节TCP send buffer的大小,0(自动调节大小),128k(默认值),512k(高吞吐量网络使用),不要超过2M

#timeout 60         #6 seconds (unit =  0.1 seconds)
#单位位0.1秒。如果搭档节点在该时间内发来应答包,认为搭档节点死亡,断开本次TCP/IP连接。默认值为60,即6秒。该选项的值必须小于connect-int和ping-int的值

#connect-int 10     #10 seconds (unit =  1 seconds)
#如果无法立即连接上远程DRBD设备,系统将断续尝试连接。该选项设定的是两次尝试间隔时间,单位秒,默认10s

#ping-int 10        #10 seconds (unit = 1 seconds)
#如果连接到远程DRBD设备的TCP/IP的空闲时间超过此值,系统将生成一个keep-alive包来检测对等节点是否还存活,单位秒,默认10秒

#ping-timeout 5     #500ms    (unit =  0.1 seconds)   
#如果对端没有在此时间内应答keep-alive包,它将被认为已经死亡。单位是0.1秒,默认值是500ms

max-buffers 8000;
#设定由drbd分配的最大请求数,单位是页面大小(PAGE_SIZE),大多数系统每个页面大小为4KB。这些buffer用来存储即将写入磁盘的数据。最小值为32(即128KB),这个值大一点好!!!

max-epoch-size 8000;		
#设定了两次write barriers之间最大的数据块数。如果选项的值小于10,将影响系统性能,大一点好!!!
#max-buffers设定的是最大的数据块数,max-epoch-size设定的是所能请求的最大块数,多数情况下,这两个选项应该并行地设置,而且两个选项的值应该保持一致。默认值都是2048,在大多数合理的高性能硬件RAID控制器中,把它们设定为8000比较好。

unplug-watermark 1024;
#ko-count 4;
#设定一个值,该设定的值乘以timeout设定值,得到一个数字N,如果secondary节点没有在此时间内完成单次写请求,它将从集群中被移除。取值范围0~200,默认值为0,即禁用该功能。


#allow-two-primaries;
#允许一个集群中有两个primary node。该模式需要特定文件系统的支撑,目前只有OCFS2和GFS可以,传统的ext3、ext4、xfs等都不行!

cram-hmac-alg "sha1";
#指定HMAC算法来启用对等节点授权。drbd强烈建议启用对等节点授权机制。可以指定/proc/crypto文件中识别的任一算法。必须在此指定算法,以明确启用对等节点授权机制

shared-secret "hdhwXes23sYEhart8t";
#设定在对端节点授权中使用的密码,最长64个字符

after-sb-0pri disconnect;
after-sb-1pri disconnect;
after-sb-2pri disconnect;
rr-conflict   disconnect;         #这几个参数是配置出现脑裂时如何处理,这里不使用脚本脚本处理,一旦出现脑裂,人工介入手动处理
#data-integrity-alg "md5";
#设定内核支持的一个算法,用于网络上的用户数据的一致性校验,可以使用内核所支持的任一算法,该功能默认关闭
#no-tcp-cork;

}

syncer { rate 330M; #同步速率,默认的速率是250KB/s,此值的设定较好的是设定有效复制带宽的30%,若连接点间无其他IO设置大一些 al-extents 517; verify-alg crc32c; } }

#resource 部分,data是资源名称,可随意指定;每个资源配置必须有两个on <host>子部分。其他的配置从common部分继承(如果存在的话)或使用默认设置 resource data { on mheartbeat.com { #mheartbeat.com其中一个节点的主机名称,即uname -n返回的结果 device /dev/drbd0; #该节点的drbd设备 disk /dev/sdb1; #该节点的要使用的存储实体数据的实体设备,分区、磁盘等 address 172.16.1.75:7788; #用来和另一个节点传输数据的网卡及端口 meta-disk /dev/sdb2 [0]; #存放元数据的实体设备,这里将元数据和实体数据分开存放了,使用internal替代/dev/sdb2 [0]则元数据和实体数据存放在一起 } on sheartbeat.com { device /dev/drbd0; disk /dev/sdb1; address 172.16.1.76:7788; meta-disk /dev/sdb2 [0]; } }

配置完成后,将上述配置文件拷贝一份到另外一个节点

8、同时在2个节点上初始化DRBD设备元数据

[root@mheartbeat ~]# drbdadm create-md data [root@sheartbeat ~]# drbdadm create-md data #data为配置文件中指定的资源名称,也可使用all替代data,这样将会初始化配置文件中所有的资源

9、同时在2个节点上启动drbd服务

法一: /etc/init.d/drbd start 法二: drbdadm up data #data为配置文件中指定的资源名称,也可使用all替代data,这样将会启动配置文件中所有的资源 这条指令相当于同时执行下面3条指令: drbdadm attach data drbdadm syncer data drbdadm connect data

注意:启动drbd服务之前必须初始化元数据,且初始化元数据之前不能启动drbd(若启动使用/etc/init.d/drbd stop关闭),否则初始化drbd元数据后再启动将会报错

10、查看状态

法一: [root@mheartbeat ~]# drbd-overview 0:data/0 Connected Secondary/Secondary Inconsistent/Inconsistent 法二: [root@mheartbeat ~]# cat cat /proc/drbd cat: cat: No such file or directory version: 8.4.9-1 (api:1/proto:86-101) GIT-hash: 9976da086367a2476503ef7f6b13d4567327a280 build by mockbuild@Build64R6, 2016-12-13 18:38:15 0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----- ns:0 nr:0 dw:0 dr:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:d oos:827316

同样的方法也可以在另外一个节点上查看,从上面可以看出当前两个节点都是备节点状态

注意:到现在位置两个drbd还没有指定哪个是主节点,哪个是备节点 drbd的主节点需在命令行手动设置(无论哪个节点都可以),而不能通过配置文件指定(heartbeat的主节点可通过配置文件指定) 如果两个节点磁盘是空的,无数据的,可以任意选择同步源。如果一个节点的磁盘有要保存的数据,那就选择有数据的这个节点作为同步源。如果选择错了,则会造成数据丢失。

11、设置主节点

在要设置为主节点的主机上进行如下操作: 法一: [root@mheartbeat ~]# drbdadm -- --overwrite-data-of-peer primary data #data是配置文件中设定的资源名称 法二: drbdsetup /dev/drbd0 primary -o 法三: drbdadm primary --force data

注意:上述3个指令设定主节点,仅在第一次配置drbd时使用,drbd配置完成后不能在使用

查看状态: [root@mheartbeat ~]# drbd-overview
0:data/0 Connected Primary/Secondary UpToDate/UpToDate [root@mheartbeat ~]# cat cat /proc/drbd
version: 8.4.9-1 (api:1/proto:86-101) GIT-hash: 9976da086367a2476503ef7f6b13d4567327a280 build by mockbuild@Build64R6, 2016-12-13 18:38:15 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----- ns:827316 nr:0 dw:0 dr:828004 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:d oos:0 可以看出,mheartbeat.com主机以及被设置成主节点

上述状态详解: 第一行:软件版本 Version :表示当前使用的DRBD的版本号

第二行:同步状态 0:指的是/dev/drbd0 cs: 即connection state,表连接状态 ro:即roles,本地节点和远程节点的角色 ds: 即disk states,本地和远程节点的硬盘状态 C :表示所使用的协议是C 后面六个表示的是I/O状态标记 r或s : 表示I/O操作正在进行;s表示I/O挂起,正常的是r -或a : a表示延迟后再同步, -表示正常同步 -或p : p表示因对端启动同步挂起而引起的数据再同步的情况;-表示正常 -或u : u表示因本地启动同步挂起而引起的数据再同步的情况;-表示正常 -或d,b,n,a : d表示因为DRBD内部原因引起的I/O阻塞,类似一种过渡磁盘状态;b表示备用设备I/O正在阻塞;n表示网络套接字的阻塞;a:表示同时发生I/O设备阻塞和网络阻塞 -或s : s表示当挂起更新时的活动日志时的标记;正常是-

第三行:性能指标 ns:即network send,表示通过网络发送到对等节点的数据量,单位是Kibyte nr:即network receive,表示通过网络接收来自对等节点的数据量,单位是Kibyte dw:即disk write,表示写到本地资产的网络数据,单位是Kibyte dr:即disk read,表示从本地磁盘读出的网络数据,单位是Kibyte al:即activity log,表示对元数据的活动日志区域的更新数 bm:即bit map,表示对元数据的位图区域的更新数 lo:即local count,表示被DRBD所打开的本地I/O子系统的请求数 pe:即pending,表示发送到对等节点的请求数,但是对等节点还没有做出相应 ua:即unacknowledged,表示对等节点所接受的请求数,但是还没做出相应 ap:即application pending,表示转发到DRBD的块I/O请求数,但是还没有做出相应 ep:即epochs,表示epoch对象的数量,通常当在用 barrier或none写的顺序方法而加载I/O的时候会增加 wo:即write order,表示当前所使用的写的顺序方法:b(barrier),f(flush),d(drain),n(none) oos:即out of sync,表示当前还没有同步的存储量

其它常用指令: [root@mheartbeat ~]# drbdadm cstate data #查看资源的连接状态 Connected [root@mheartbeat ~]# drbdadm role data #查看资源的角色 Secondary/Primary [root@mheartbeat ~]# drbdadm dstate data #查看资源的硬盘状态 UpToDate/UpToDate

drbdadm up <resource name>/all #手动启动指定的或所用的资源 drbdadm down <resource name>/all #临时禁用指定的或所用的资源 注意:这两个指令在drbd配置完成后使用,可随意的启用或禁用指定的或全部的资源

drbdadm primary <resource name> #将其中一个资源角色设置为主节点 drbdadm secondary <resource name> #将其中一个资源角色设置为备节点 注意: 这两个指令在drbd配置完成后使用,可随意的转换指定资源的角色。 在单主模式(DRBD的默认模式),同一时间只允许有一个节点时 primary 模式;双主模式,两个节点可同时都是primary 模式。

11、在主节点上创建文件系统

注意:drbd只能在主节点上创建文件系统及挂载,备节点上绝不可创建文件系统,因为备节点上的文件系统是从主节点同步过去的

[root@mheartbeat ~]# mkfs.ext4 /dev/drbd0 #drbd一旦启动后,就只能使用/dev/drbd0 设备来操作

12、挂载并测试

[root@mheartbeat ~]# mount /dev/drbd0 /mnt/ [root@mheartbeat ~]# cd /mnt/ [root@mheartbeat mnt]# touch test{1..10} [root@mheartbeat mnt]# ll total 16 drwx------ 2 root root 16384 Apr 5 20:24 lost+found -rw-r--r-- 1 root root 0 Apr 5 20:26 test1 -rw-r--r-- 1 root root 0 Apr 5 20:26 test10 -rw-r--r-- 1 root root 0 Apr 5 20:26 test2 -rw-r--r-- 1 root root 0 Apr 5 20:26 test3 -rw-r--r-- 1 root root 0 Apr 5 20:26 test4 -rw-r--r-- 1 root root 0 Apr 5 20:26 test5 -rw-r--r-- 1 root root 0 Apr 5 20:26 test6 -rw-r--r-- 1 root root 0 Apr 5 20:26 test7 -rw-r--r-- 1 root root 0 Apr 5 20:26 test8 -rw-r--r-- 1 root root 0 Apr 5 20:26 test9

13、在备节点上查看文件是否同步过去

主备节点角色互换(这个过程称之为故障转移,这里是为了查到数据同步的结果) 对主Primary/Secondary模型的drbd服务来讲,在某个时刻只能有一个节点为Primary,因此,要切换两个节点的角色,只能在先将原有的Primary节点设置为Secondary后,才能原来的Secondary节点设置为Primary

主节点上的操作: 先卸载挂载的目录,再将主节点设置为从节点 [root@mheartbeat ~]# umount -lf /mnt [root@mheartbeat ~]# drbd-overview 0:data/0 Connected Primary/Secondary UpToDate/UpToDate [root@mheartbeat ~]# drbdadm secondary data [root@mheartbeat ~]# drbd-overview
0:data/0 Connected Secondary/Secondary UpToDate/UpToDate

从节点上操作: 将从节点设置为主节点,再挂载 [root@sheartbeat ~]# drbdadm primary data [root@sheartbeat ~]# drbd-overview 0:data/0 Connected Primary/Secondary UpToDate/UpToDate [root@sheartbeat ~]# mount /dev/drbd0 /mnt/ [root@sheartbeat ~]# ll /mnt total 16 drwx------ 2 root root 16384 Apr 5 20:24 lost+found -rw-r--r-- 1 root root 0 Apr 5 20:26 test1 -rw-r--r-- 1 root root 0 Apr 5 20:26 test10 -rw-r--r-- 1 root root 0 Apr 5 20:26 test2 -rw-r--r-- 1 root root 0 Apr 5 20:26 test3 -rw-r--r-- 1 root root 0 Apr 5 20:26 test4 -rw-r--r-- 1 root root 0 Apr 5 20:26 test5 -rw-r--r-- 1 root root 0 Apr 5 20:26 test6 -rw-r--r-- 1 root root 0 Apr 5 20:26 test7 -rw-r--r-- 1 root root 0 Apr 5 20:26 test8 -rw-r--r-- 1 root root 0 Apr 5 20:26 test9 #可以看出,数据同步成功

DRBD脑列问题

在使用drbdadm-overview或cat /proc/drbd查看drbd的状态时,如何主备中任何一个出现Unknown状态,说明drbd出现了脑裂问题 修复过程如下

主节点操作: drbdadm primary data mount /dev/drbd0 /mnt/

备节点操作: drbdadm secondary data drbdadm -- --overwrite-my-data connect data

主节点上操作: drbdadm connect data

查看修复结果: drbd-overview cat /proc/drbd

备节点扩容问题:

有前面可知: 主节点分区时为1G(/dev/sdb1:800M实体数据,/dev/sdb2:剩余部分元数据) 备节点分区时为2G(/dev/sdb1:1800M实体数据,/dev/sdb2:剩余部分元数据)

上面测试数据是否同步成功,已经将主备节点角色互换,现在看看角色互换后备节点上(实际上此时成为了主节点)磁盘空间有多大 [root@sheartbeat ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 8.6G 1.6G 6.6G 20% / tmpfs 491M 0 491M 0% /dev/shm /dev/sda1 190M 35M 146M 20% /boot /dev/drbd0 780M 824K 739M 1% /mnt #可看出只有780M,即之前主节点的大小,而剩余的空间(应该有1800M)不能使用

下面来扩容,使剩余的空间也能够使用(备节点扩容,因此在备节点操作,不要搞错了) umount /mnt drbdadm down all e2fsck -f /dev/sdb1
resize2fs /dev/sdb1
mount /dev/sdb1 /mnt ll -h /mnt/

注意: 这种扩容方式,一旦扩容后,这对主备drbd就不能在使用了 可以使用mount /dev/drbd0 /mnt/挂载测试此时会提示错误: [root@sheartbeat ~]# mount /dev/drbd0 /mnt/ mount: wrong fs type, bad option, bad superblock on /dev/drbd0, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so

主要原因是备节点扩容后,文件系统信息已经发生了变化,已经不再和原来主节点文件系统相同了,如果想继续维持这一对drbd,此时可以将原来的主节点分区删除重新创建一个分区(分区容量要大于,至少要等于扩容后的备节点分区大小) 此时重新在原来的主节点上设置drbd配置

下面是操作过程: 首先删除原来作为主节点的分区 然后重新创建分区: [root@mheartbeat ~]# fdisk /dev/sdb Command (m for help): p

Disk /dev/sdb: 2684 MB, 2684354560 bytes #可以看出新分区比原来的备节点分区要大 Disk identifier: 0x965656bb

Device Boot Start End Blocks Id System Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-326, default 1): 1 Last cylinder, +cylinders or +size{K,M,G} (1-326, default 326): +1900M Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (244-326, default 244): Using default value 244 Last cylinder, +cylinders or +size{K,M,G} (244-326, default 326): 325

Command (m for help): w

[root@mheartbeat ~]# partprobe [root@mheartbeat ~]# drbdadm create-md data [root@mheartbeat ~]# drbdadm up data

原备节点上操作: [root@sheartbeat ~]# drbdadm up data #之前扩容时,drbd被关掉,这里重新开启 [root@sheartbeat ~]# cat /proc/drbd #查看状态,已经开始同步新的文件系统信息 version: 8.4.9-1 (api:1/proto:86-101) GIT-hash: 9976da086367a2476503ef7f6b13d4567327a280 build by mockbuild@Build64R6, 2016-12-13 18:38:15 0: cs:SyncSource ro:Secondary/Secondary ds:UpToDate/Inconsistent C r----- ns:1492844 nr:0 dw:0 dr:1492844 al:8 bm:0 lo:0 pe:1 ua:0 ap:0 ep:1 wo:d oos:355476 [===============>....] sync'ed: 81.0% (355476/1847444)K finish: 0:00:04 speed: 82,884 (82,884) K/sec

[root@sheartbeat ~]# drbdadm -- --overwrite-data-of-peer primary data #这次将原备节点作为主节点(这个操作一定不能在原主节点上操作,否则之前同步过来的数据全部被擦除),因为此时的备可能正在被其它服务使用或挂载

[root@sheartbeat ~]# cat /proc/drbd #查看状态,可以看出原来的备此时成为主 version: 8.4.9-1 (api:1/proto:86-101) GIT-hash: 9976da086367a2476503ef7f6b13d4567327a280 build by mockbuild@Build64R6, 2016-12-13 18:38:15 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----- ns:1847443 nr:0 dw:0 dr:1848114 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:d oos:0

[root@mheartbeat ~]# cat /proc/drbd #查看状态,可以看出原来的主此时成为备 version: 8.4.9-1 (api:1/proto:86-101) GIT-hash: 9976da086367a2476503ef7f6b13d4567327a280 build by mockbuild@Build64R6, 2016-12-13 18:38:15 0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----- ns:0 nr:1847447 dw:1847447 dr:0 al:16 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:d oos:0

[root@sheartbeat ~]# mount /dev/drbd0 /mnt #这次挂载没有再出现错误 [root@sheartbeat ~]# ll /mnt #挂载后查看原来的数据有还在 total 16 drwx------ 2 root root 16384 Apr 5 20:24 lost+found -rw-r--r-- 1 root root 0 Apr 5 20:26 test1 -rw-r--r-- 1 root root 0 Apr 5 20:26 test10 -rw-r--r-- 1 root root 0 Apr 5 20:26 test2 -rw-r--r-- 1 root root 0 Apr 5 20:26 test3 -rw-r--r-- 1 root root 0 Apr 5 20:26 test4 -rw-r--r-- 1 root root 0 Apr 5 20:26 test5 -rw-r--r-- 1 root root 0 Apr 5 20:26 test6 -rw-r--r-- 1 root root 0 Apr 5 20:26 test7

到此,这对主备drbd重新搭建起来

排错与恢复

如何处理硬盘驱动器故障取决于配置处理I/O错误的方法和配置的元数据的方法。 ① 从你的硬盘驱动器手动分离DRBD 如果你的DRBD配置成为pass on I/O errors的I/O错误处理模式的话(不推荐的),你必须首先分离DRBD资源,也就是说,使它和它的支持存储器分离:

drbdadm detach <resource name>

然后通过drbdadm dstate命令查看资源现在已经是diskless模式。 drbdadm dstate <resource name> Diskless/UpToDate #返回结果

如果在primary节点上出现磁盘故障,除了上面的步骤还要做一个角色切换的操作。 ② 如果DRBD被配置为当出现I/O错误的时候可自动从硬盘驱动器分离(推荐这样),那么DRBD应该会自动从它的支持存储器中分理出资源,不需要手动干预。仍旧可以使用drbdadm dstate命令来查看资源是否运行在diskless 模式。

③ 在使用internal meta data设置时替换故障磁盘 如果使用internal meta data,那么完全可以绑定DRBD设备到一个新的磁盘上。如果新的的磁盘使用另外一个设备名而不是故障磁盘的设备名,那么必须修改DRBD配置文件中相关的选项。操作流程是:

  1. 创建一个新的元数据集,即 drbdadm create-md <resource name>
  2. 重新添加资源,即 drbdadm attach <resource name> 之后就会自动并立即开始新磁盘的完全同步。可以通过/proc/drbd来监控同步过程。

④ 在使用external meta data设置时替换故障磁盘 使用external meta data的过程和使用internal meta data的过程基本相同。但是使用external meta data不会自动识别硬盘已被交换,还有多一个操作步骤:

即 1. drbdadm create-md <resource name> 2. Drbdadm attach <resource name> 3. Drbdadm invalidate <resource name> 此处,drbdadm invlidate <resource name> 命令会触发同步。同样同步过程可以通过/proc/drbd来查看。

节点故障的处理

当DRBD检测到对等节点当机时(既可以是真正的硬件故障,也可是手动干预的),DRBD会将它的连接状态从Connected状态转到WFConnection状态,并且等待重新发现对端。然后DRBD资源会处在disconnetced模式。在disconnected模式中,资源和它的相关块设备完全不可用,并且必要的话可能会被提升或降低角色,但是没有修改过的块会被复制到对端节点上去。当失去连接时,DRBD会将内部信息存储在正在被修改的块中。

① 临时secondary节点故障的处理 如果在一个节点处于secondary角色的资源临时性的出现故障(例如,因为替换内存而引起大小调整的内存问题),不需要做进一步的手工干预——除了那种明显需要修复的故障节点外,并且会自己返回在线状态。当这种情况发生的时候,两个节点只需简单的重新建立连接状态,在系统启动之后,DRBD会复制所有在此期间在primary节点上修改过块到secondary节点上。

② 临时primary节点故障的处理 从DRBD的观点来看,primary节点故障和secondary节点故障处理几乎差不多。还在线的节点检测到另一个节点发生故障,并切换模式到disconnected。DRBD并不会提升还在线节点到primary角色,这是由集群管理程序负责完成的。

当故障节点修复完并返回集群,它会在secondary节点上提升角色,因此和上小节一样不需要在进行手工干预。还有,角色的提升不是有DRBD完成,而是由集群管理程序负责。

DRBD会通过一种特殊的机制来确保当primary节点出现故障时块设备的一致性。

③ 永久性节点故障的处理 如果节点遇到不可恢复或者永久性的破坏,需要做以下几步:

  1. 替换一个和故障件性能和磁盘容量相似的硬件。(注意:如果硬件的性能差一些也是可以的,但不推荐这样做。而替换的硬盘容量一定不能小于故障件否则DRBD会拒绝连接被替换的节点。)
  2. 安装基本的系统和应用程序。
  3. 安装DRBD和拷贝/etc/drbd.conf/和在/etc/drbd.d/下所有还存在的节点。
  4. 配置DRBD但绝不能初始化设备同步。 在这个地方没有必要手动启动完全设备同步,它会自动连接到还在线的primary节点上。

手动恢复脑裂

在连接再次有效的时候DRBD检测到脑裂,并且对等节点会交换初始DRBD握手协议。如果DRBD检测到两个节点都是primary角色,它会立即断开复制连接。 这会在系统日志文件中出现以下信息: Split-Brain detected, dropping connection!

在检测到脑裂之后,一个节点将会总是处于StandAlone资源连接状态。另外一个节点或许既可能是StandAlone状态(如果两个节点同时检测到脑分裂),也可能是WFConnection状态(如果对等节点断开了连接,在另外一个节点有机会检测到脑分裂之前)。

在此时,除非配置DRBD可是从脑裂中自动恢复,否则必须手动干预,通过选择哪个一个修改过的节点将会被丢弃。手动干预需要使用以下几个命令: drbdadm secondary <resource name> drbdadm connect --discard-my-data <resource name>

(注意使用上面的几个命令时,脑分裂的牺牲者需要处在StandAlone的连接状态,否则会返回错误信息。可以使用drbdadm disconnect <resource name>来确保它是standalone状态。)

在另一个节点上,如果它的连接状态也是StandAlone,可以输入: drbdadm connect <resource name>

可以省略上面这个步骤,如果节点已经处在WFConnection状态的话,它之后会自动重新连接。 如果被脑裂影响的是栈资源,就使用drbdadm --stacked 代替drbdadm。 在连接的情况下,脑裂的牺牲者会立即改变它的连接状态为SyncTarget,已经修改过的会被剩下的主节点覆盖。 在再同步完成之后,脑裂会被认为已经解决了,两个节点有构成了一致的冗余复制存储系统。

补充1:启用双主模式

启用双主模式既可以是永久性的也可以额是临时性的。使用双主模式,资源必须被配置成协议C。 永久性双主模式的配置: ① 必须在net区域,设置allow-two-primaries选项为yes。 ② 之后同步修改后的文件到对等节点,然后在分别在两个节点上运行drbdadm adjust <resource name> (该指令仅在启用双主时生效) ③ 最后就可以在两个节点上同事执行drbdadm primary <resource name>命令

临时性双主模式的配置: ① 在单主模式中临时启用双主模式可以使用: drbdadm net-options --protocol=C --allow-two-primaries <resource name> ②  结束掉临时双主模式时使用: drbdadm net-options --protocol=C --allow-two-primaries=no

自动启动双主模式: ① 如果希望在重启系统或重启DRBD时,自动启动双主模式(已经被配置为支持双主模式),则在common配置段的startup区域,将become-primary-on 选项设置为both即可。

补充2:使用在线设备验证

启用在线验证: ① 默认情况下是没有启动的。若启用,就在net区段配置选项verify-alg <algorithm>; algorithm可以是sha1、md5、crc32c中的任何一种。 在线验证的调用: ② 在启用在线验证后,就可以使用 drbdadm verify <resource>来进行调用了。使用此命令可以对资源启动在线验证。如果找到的任何没有同步的块,它会将这些块做标记并且写信息到内核日志里面。 ③ 如果在验证中找到了没有同步的块,那么可以在验证完成后使用 drbdadm disconnect <resource name> drbdadm connect <resource name> 两条命令实现再同步

自动在线验证(即配置定时任务): ④ 可以通过创建名为/etc/cron.d/drbd-verify的文件,内容如下 00 00 * * 0 root/sbin/drbdadm verify <resource name>/all 或echo "00 00 * * 0 root/sbin/drbdadm verify <resource name>/all &> /dev/null" >> /var/spool/cron/root

补充3:配置同步速率

① 永久固定的同步速率配置: 在disk区段配置resync-rate选项为一个给定值,如下所示 resource <resource name> { disk { resync-rate 40M; ...... } ......

					}

默认的速率是250KB/s。此值的设定最好是带宽的30%。如果连接点之间没有其它IO消耗,设置更大,加快同步速度

② 临时固定的同步速率配置: drbdadm disk-options --resync-rate=110M <resource name> 若要恢复临时的设定,用如下命令: drbdadm adjust <resource name>

③ 可变同步速率配置: 如果多个DRBD资源共享一个单独的复制/同步网络,固定速率的同步或许不是一个最优的选择,在这种情况下,可以使用可变速率。 可变同步速率的最佳配置是取决于可用的网络带宽,应用程序的I/O模式,链路阻塞情况等。理想的配置也取决于是否使用了DRBD代理。

下面是一个和DRBD代理同时使用的配置: resource <resource name> { disk { c-plan-ahead 200; c-max-rate 10M; c-fill-target 15M; }

}

补充4:配置基于校验的同步

默认是没有启用的,若启用如下所示:

resource <resource name> { net { csums-alg <algorithm>; #可使用的算法有sha1、md5、crc32c ..... } ..... }

补充4:配置阻塞策略和挂起复制

在一个复制带宽高度变化的环境中,复制链路有时会发生阻塞。在默认的配置中,这种情况将引起主节点的阻塞,这是不希望发生的。 因此,可以配置DRBD在遇到这种持续复制情况时挂起。这是会导致主节点的数据领先于备用节点。在这种模式下,DRBD将一直保持复制通道处于打开状态,但不会切换到disconnected模式,而是直到又一次有可用带宽时再次进行复制。

以下是DRBD代理的配置: resource <resource name> {

net { on-congestion pull-ahead; congestion-fill 2G; congetstion-extents 2000; }

}

通常在设置congestion-fill和congestion-extents明智的做法是和pull-ahead一起设定。 当在DRBD代理上复制时,Congestion-fill一般取分配给DRBD缓冲内存大小的90%; 而在非DRBD代理上复制时,congestion-fill一般取TCP发送缓冲区大小的90%。

Congestion-extents一般取配置的al-extents的90%。

补充5:配置I/O错误处理策略

处理底层I/O错误的DRBD策略是由on-io-error选项决定的,如:

resource <resource name> {

disk{
		on-io-error <strategy>;		
		.....
	}
......

}

此选项有三个取值:

  1. detach 默认,推荐设置。出现底层I/O错误时,节点将会丢弃它的支持设备,以无盘的模式继续运行。
  2. pass-on 设置此值DRBD将向它的上层报告I/O错误。在主节点上它会报告给被挂载的文件系统。在备节点上将被忽略,因为备用节点上没有上层。
  3. call-local-io-error 表示调用自定义的脚本来处理I/O错误。

补充5:配置复制流量完整性检查 默认未启用,若启用配置如下:

resource <resource name> {

net {

	data-integrity-alg <algorithm>;			#可设置的算法有:sha1、md5、crc32c
	......

} ...... }

补充6:重置资源的大小(注意这里的调整和上面实验所做的调整<扩展备节点空间>意义不同,注意体会)

① 在线增加 需要满足两个条件:

  1. 支持设备必须是逻辑卷(LVM)
  2. 当前的资源必须处于connected的连接状态。

在两个节点给设备增加大小后,再确认只有一个节点处于primary状态。然后执行: drbdadm resize <resource name> #此命令会触发新扇区的同步,完成主节点到备用节点间的同步

若添加的空间是干净没有数据的,可以使用--assume-clean 选项: drbdadm -- --assume-clean resize <resource name>

② 离线增加

  1. 资源被配置为external meta data时(即前面使用的配置方式) 当DRBD在处于非活动情况下,在俩个节点的支持设备被增加时,并且DRBD资源使用的是external meta data,那么新的大小会自动被识别,不需要管理员干预。DRBD设备将在下次两个节点活动并且成功建立网络连接之后,显示增加后的新容量。

  2. 资源被配置为internal meta data时 当DRBD资源被配置为使用 internal meta data时,元数据必须被移动到这增加容量后设备的末端,若让新的大小生效,需要完成以下几步:

● 取消你的DRBD资源配置: drbdadm down <resource name>

● 增加容量前保存元数据到一个文本文件中: drbdadm dump-md <resource name> > /tmp/metadata 以上必须在两个节点上分别运行。不能再一个节点上保存了元数据然后在考到另外一个节点上,否则就无法工作。

● 在两个节点上给支持的块设备增加容量 ● 分别在两个节点上调整/tmp/metadata 文件中la-size-sect的大小信息(注:la-size-sect指定的是扇区的多少)

● 重新初始化元数据区域 drbdadm create-md <resource name>

●分别在两个节点上重新导入更正的元数据 drbdmeta_cmd=$(drbdadm -d dump-md test-disk) ${drbdmeta_cmd/dump-md/restore-md} /tmp/metadata

●重新启用DRBD资源 drbdadm up <resource name>

●在一个节点上,设置DRBD为primary: drbdadm primary <resource name> 到此,已完成DRBD设备大小的扩容。

③ 在线缩小容量 注:在线缩小容量,仅支持external metadata 在缩小DRBD设备时必须首先缩小DRBD的上层,即文件系统。文件系统是否可以被缩小取决于所使用的文件系统。大多数文件系统不支持在线缩减。XFS也不支持在线缩减(必须将设备卸载后再缩减,注意缩减文件系统大多情况会损坏数据,操作时一定要确认)。

因此,在缩小文件系统后,就可以使用以下命令在线缩小DRBD设备容量了。 drbdadm resize --size=<new-size> <resource name>

④ 离线缩小容量 ● 在DRBD还处于配置运行状态时,在一个节点上缩小文件系统 ● 取消DRBD资源的配置 drbdadm down <resource name>

●在缩小前保存元数据到一个文件中: drbdadm dump-md <resource name> > /tmp/metadata 以上必须在两个节点上分别运行。不能再一个节点上保存了元数据然后在考到另外一个节点上。否则就无法工作。

● 在两个节点上给支持的块设备缩小容量 ● 分别在两个节点上调整/tmp/metadata 文件中la-size-sect的大小信息(注:la-size-sect指定的是扇区的多少)。 ● 只要你使用的是internal metadata,就可以重新初始化元数据区域 drbdadm create-md <resource name>

●分别在两个节点上重新导入更正的元数据 drbdmeta_cmd=$(drbdadm -d dump-md test-disk) ${drbdmeta_cmd/dump-md/restore-md} /tmp/metadata ●重新启用DRBD资源 drbdadm up <resource name>

●在一个节点上,设置DRBD为primary: drbdadm primary <resource name> 到此,已完成DRBD设备大小的缩减。

补充7: 禁用支持设备flushes

应该仅在有电池支撑的写缓存的设备(即BBWC,battery-backed write cache)中运行DRBD时,可以禁用设备flushes。大多数存储控制器都会在电源快用尽时,自动禁用写缓存并切换至‘直接写’模式。强烈推荐启用此功能。

如果在没有使用BBWC或使用了BBWC但电池已经耗尽的时,禁用此功能,很可能会造成数据丢失。 DRBD允许你单独的启用或禁用复制数据集和DRBD自身的元数据。这两个选项默认是启用的。你可以在配置文件的disk区段来禁用或启用这两个或一个选项。如:

resource <resource name> {

disk {

		disk-flushes on;或md-flushes no;
		......
	}
......

}

补充8:配置脑裂特性

① 配置脑裂,是在handlers 区段,如: esource <resource name> {

handlers {

		split-brait <handler>;
		......
	}

...... }

<handler>可以是系统中任何可执行的程序。DRBD本身自带了一个脑分裂处理脚本/usr/lib/drbd/notify-split-brain.sh。它会给指定地址发送一个e-mail消息通知。

例如,配置发送给管理员root的消息: resource <resource name> {

handler {

	split-brain “/usr/lib/drbd/notify-split-brain.sh root”;
	......
	}

...... }

② 脑分裂自动恢复策略 DRBD提供的脑裂恢复处理,是基于脑分裂处理程序所检测到的处于primary角色的节点数量。要实现这种功能,DRBD需要在net配置区段查找以下几个关键字:

● after-sb-0pri: 检测到了脑裂,但是没有主机节点处于primary角色。 对于此选项DRBD有以下几个值: • disconnect :不会自动恢复,如果配置了脑裂处理脚本,就会调用这个脚本,断开连接并继续保持在disconnected 模式; • discard-younger-primary:丢弃并回滚最近在承担primary角色的主机上所做的修改; • discard-least-changes:丢弃并回滚在修改较少的主机上所做的修改; • discard-zero-changes:如果有节点没有发生一点改变,那么在另一个节点上会应用所做的所有修改,并继续。

● after-sb-1pri:检测到有脑裂,同时在一个节点上资源为primary角色。对于这个选项也有一下几个值: • disconnect:和after-sb-0pri一样 • consensus :和after-sb-0pri一样应用相同的恢复策略,如果在应用这些策略后,脑裂的牺牲者是可以选择的,那么就可以实现自动恢复。否则,表现完全好像指定是disconnect值一样。 • call-pri-lost-after-sb:应用在after-sb-0pri指定的恢复策略。如果在应用这些策略后,脑裂的牺牲者是可以选择的,那么就会在作为牺牲节点的主机上调用pri-lost-after-sb处理程序。这个处理程序必须在handlers区段配置好,并且可以强制从集群中移除。 •discard-secondary:无论当前哪个主机是secondary角色,这个主机将作为脑分裂的牺牲主机。

● after-sb-2pri:表已经检测到脑分裂,同时两个节点都是primary角色。这选项使用after-sb-1pri相同的值,除了discard-secondary和consensus外。

注意:这些关键字选项还有其他的值,因为很少被使用到,所以在此没有提及。详细内容请参考drbd.conf的帮助文档。

补充9: DRBD代理

DRBD代理既可以和DRBD安装在同一台电脑上,也可以是完全独立的一台服务器。DRBD代理可以为分布在多个节点上的多个DRBD设备提供代理服务。 DRBD代理对DRBD是完全透明的。在这种情况下可能会有大量的数据包通过,因而日志文件会变的相当的大。这样会使当主节点崩溃时,同步时间会很长。为了避免这种情况,建议启用csums-alg 设置。

① Drbd-proxy的安装(略) ② 许可证文件 从官网下载许可证文件drbd-proxy.license。它必须被拷贝到/etc目录底下,并将此文件的所有者和组改为drbdpxy cp -a drbd-proxy.license /etc/ chown drbdpxy.drbdpxy /etc/drbd-proxy.license

③ 配置 配置DRBD代理,是在配置文件中附加一个叫做proxy的区段,并且在主机区段附加proxy on区段。以下是直接在DRBD的节点上,配置DRBD代理的例子:

resource <rerouce name> {

net {

	Protocol A; 					#也可以使B或C

}

deviceminor 0;

disk  /dev/sdb1;

meta-disk  /dev/sdb2;

proxy {

memlimit 100M;

plugin {

zliblevel 9;

}

}

On <hostname1> {

address 127.0.0.1:7789;

Proxy on <hostname1> { inside 127.0.0.1:7788; outside 192.168.1.103:7788; }

}

On <hostname2> {

address 127.0.0.1:7789;

proxy on { inside 127.0.0.1:7788; outside 192.168.1.105:7788; }

}

}

注:inside IP地址是DRBD和DRBD代理之间通信用的。Outside IP地址使用来在代理之间进行通信用的。

④ 管理DRBD代理 可是使用drbdadm proxy-up 和drbdadm proxy-down 来配置或删除与指定资源的本地DRBD代理进程的连接。这些命令可以通过/etc/init.d/drbdproxy start/stop来实现。

也可以使用drbd-proxy-ctl,使用drbd-proxy-ctl -c “help” 来显示可使用的命令。

⑤ 关于DRBD代理的插件 从DRBD代理3.0开始允许在WAN连接中使用少量指定的插件。当前可使用的插件是zlib 和 lzma。 zlib插件使用GZIP算法进行压缩。使用此插件的好处是它CPU使用率很低。 lzma插件使用liblzma2库。它使用了几百兆的库文件,因此它可以非常高效的增量压缩重复的数据。但是它需要更多的CPU和内存,因此压缩比会比zlib好很多。若使用此插件必须在许可证文件中启用此功能。

注意:在proxy区段原有的compression on 在新版本中将不再使用,当前使用的是zlib level 9(8.4).

⑥ 疑难排解 DRBD proxy 通过syslog使用LOG_DEAMON来记录日志。日志信息可以在/var/log/daemon.log中查看到。可以使用如下命令启用DRBD proxy日志的debug模式:

drbd-proxy-ctl -c ‘set loglevel debug’