DRBD(实现数据库高可用)


    Distributed Replicated Block Device(DRBD)是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。

    数据镜像:实时、透明、同步(所有服务器都成功后返回)、异步(本地服务器成功后返回)


环境


node1:192.168.163.172

node2:192.168.163.173



安装过程


先修改hosts文件


[root@node1 ~]# cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.163.172 node1

192.168.163.173 node2



[root@node2 ~]# cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.163.172 node1

192.168.163.173 node2


主机名也要修改


[root@node1 ~]# hostname

node1


[root@node2 ~]# hostname

node2


两边实现ssh免密登录

[root@node1 ~]# ssh-copy-id node2


[root@node2 ~]# ssh-copy-id node1



设置时钟同步:

[root@node1 ~]# crontab -l

*/5 * * * * ntpdate cn.pool.ntp.org 


[root@node2 ~]# crontab -l

*/5 * * * * ntpdate cn.pool.ntp.org 


安装derb:

# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

# yum install -y kmod-drbd84 drbd84-utils


编辑全局配置文件

vim /etc/drbd.d/global_common.conf 

global {
    usage-count no;  #是否参加DRBD使用统计,默认为yes。官方统计drbd的装机量
    # minor-count dialog-refresh disable-ip-verification
}
common {
    protocol C;      #使用DRBD的同步协议
    handlers {
        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";
    }
    startup {
        # wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb
    }
    options {
        # cpu-mask on-no-data-accessible
    }
    disk {
        on-io-error detach; #配置I/O错误处理策略为分离
        # size max-bio-bvecs on-io-error fencing disk-barrier disk-flushes
        # disk-drain md-flushes resync-rate resync-after al-extents
        # c-plan-ahead c-delay-target c-fill-target c-max-rate
        # c-min-rate disk-timeout
    }
    net {

        # protocol timeout max-epoch-size max-buffers unplug-watermark
        # connect-int ping-int sndbuf-size rcvbuf-size ko-count
        # allow-two-primaries cram-hmac-alg shared-secret after-sb-0pri
        # after-sb-1pri after-sb-2pri always-asbp rr-conflict
        # ping-timeout data-integrity-alg tcp-cork on-congestion
        # congestion-fill congestion-extents csums-alg verify-alg
        # use-rle
    }
    syncer {
        rate 1024M;    #设置主备节点同步时的网络速率
    }
}


创建配置文件


[root@node1 ~]# vim /etc/drbd.d/mysql.res 

resource mysql {
protocol C;
meta-disk internal;
device /dev/drbd1;
syncer {
verify-alg sha1;
}
net {
allow-two-primaries;
}
on node1 {
disk /dev/sdb2; #在node1创建的分区
address 192.168.163.172:7789;
}
on node2 {
disk /dev/sdb2; #在node2创建的分区
address 192.168.163.173:7789;
}
}


然后把node1的配置文件复制到node2上:

scp -rp  /etc/drbd.d/* node2:/etc/drbd.d/


在node2上面启动:

[root@node2 ~]#  drbdadm create-md mysql

initializing activity log

initializing bitmap (160 KB) to all zero

Writing meta data...

New drbd meta data block successfully created.

[root@node2 ~]# modprobe drbd


查看内核是否已经加载了模块:

[root@node2 drbd.d]# lsmod | grep drbd

drbd                  396875  1 

libcrc32c              12644  4 xfs,drbd,ip_vs,nf_conntrack

###

[root@node2 ~]# drbdadm up mysql

[root@node2 ~]# drbdadm -- --force primary mysql


查看状态:

[root@node1 ~]# cat /proc/drbd

version: 8.4.10-1 (api:1/proto:86-101)

GIT-hash: a4d5de01fffd7e4cde48a080e2c686f9e8cebf4c build by mockbuild@, 2017-09-15 14:23:22


 1: cs:WFConnection ro:Primary/Unknown ds:UpToDate/DUnknown C r-----

    ns:0 nr:0 dw:0 dr:912 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


同样的操作在 node2 也执行一遍

[root@node2 ~]# drbdadm create-md mysql

[root@node2 ~]# modprobe drbd

[root@node2 ~]# drbdadm up mysql


两边都安装mariadb

yum install -y mariadb mariadb-server


修改配置文件,将数据库路径指向/test 目录

vim /etc/my.cnf

[mysqld]
datadir=/test
socket=/var/lib/mysql/mysql.sock


查看状态,看到 node1 是Primary

[root@node1 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.
Please consider using drbdtop.
 1:mysql/0  Connected Primary/Secondary UpToDate/UpToDate



创建一个 /test 目录

mkdir /test


在 node1 格式化并挂载

[root@node1 ~]# mkfs.xfs /dev/drbd1

[root@node1 ~]# mount /dev/drbd1 /test


挂载成功

[root@node1 ~]# df -h

Filesystem           Size  Used Avail Use% Mounted on

/dev/mapper/cl-root   17G  1.5G   16G   9% /

devtmpfs             902M     0  902M   0% /dev

tmpfs                912M     0  912M   0% /dev/shm

tmpfs                912M  8.5M  904M   1% /run

tmpfs                912M     0  912M   0% /sys/fs/cgroup

/dev/sda1           1014M  185M  830M  19% /boot

tmpfs                183M     0  183M   0% /run/user/0

/dev/drbd1           991M   32M  892M   4% /test

=================================================


测试环节:


先启动数据库,并创建一个数据库

[root@node1 ~]# systemctl start mariadb

MariaDB [(none)]> create database xhk777;

Query OK, 1 row affected (0.04 sec)


停止 node1 的mariadb服务,并卸载刚才的挂载

[root@node1 ~]# systemctl stop mariadb

[root@node1 ~]# umount /test


将 node1 降级为 secondary 

[root@node1 ~]# drbdadm secondary mysql


将 node2 升级为 primary


[root@node2 ~]# drbdadm primary mysql

注释:在单主模式下的DRBD,两个节点同时处于连接状态,任何一个节点都可以在特定的时间内变成主;但两个节点中只能一为主,如果已经有一个主,需先降级才可能升级;在双主模式下没有这个限制


在 node2 上查看状态,可以看到 node2 已经为 primary

[root@node2 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.

Please consider using drbdtop.


 1:mysql/0  Connected Primary/Secondary UpToDate/UpToDate 


这时候挂载,并启动数据库


[root@node2 ~]# mount /dev/drbd1 /test

[root@node2 ~]# systemctl start mariadb


查看数据库,发现有刚才所创建的 xhk777

MariaDB [(none)]> show databases;
+---------------------+
| Database            |
+---------------------+
| information_schema  |
| #mysql50#lost+found |
| mysql               |
| performance_schema  |
| xhk                 |
| xhk777              |
+---------------------+
6 rows in set (0.06 sec)


实验成功,我们还可以模拟 node1 恢复起来后发生脑裂的情况

在 node2 上面禁止通信

[root@node2 ~]# iptables -P INPUT DROP


在 node1 查看状态时,已经发现不了 node2 的存在了

[root@node1 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.

Please consider using drbdtop.


 1:mysql/0  WFConnection Secondary/Unknown UpToDate/DUnknown 


将 node1 升级为 primary

[root@node1 ~]# drbdadm primary mysql

[root@node1 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.

Please consider using drbdtop.


 1:mysql/0  WFConnection Primary/Unknown UpToDate/DUnknown 


像之前一样挂载目录并启动 mariadb 服务

[root@node1 ~]# mount /dev/drbd1 /test


[root@node1 ~]# systemctl start mariadb


node1 的数据库服务正常

MariaDB [(none)]> show databases;
+---------------------+
| Database            |
+---------------------+
| information_schema  |
| #mysql50#lost+found |
| mysql               |
| performance_schema  |
| xhk                 |
| xhk777              |
+---------------------+
6 rows in set (0.05 sec)


这个时候将node2的防火墙策略改为允许,就会出现脑裂的情况

iptables -P INPUT ACCEPT


分别查看状态,发现 node1 和 node2 都是为 primary

[root@node1 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.

Please consider using drbdtop.


 1:mysql/0  StandAlone Primary/Unknown UpToDate/DUnknown /test ext4 991M 32M 892M 4% 


[root@node2 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.

Please consider using drbdtop.


 1:mysql/0  StandAlone Primary/Unknown UpToDate/DUnknown /test ext4 991M 32M 892M 4% 


解决方法就是把 node1 作为备用节点

[root@node1 ~]# systemctl stop mariadb

[root@node1 ~]# umount /test

[root@node1 ~]# drbdadm secondary mysql

[root@node1 ~]# drbdadm connect --discard-my-data mysql


查看 node1 的状态

[root@node1 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.

Please consider using drbdtop.


 1:mysql/0  WFConnection Secondary/Unknown UpToDate/DUnknown 


发现还是Unknown,再到 node2 上重新连接

[root@node2 ~]# drbdadm connect mysql


再次查看状态

[root@node1 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.

Please consider using drbdtop.


 1:mysql/0  Connected Secondary/Primary UpToDate/UpToDate 


[root@node2 ~]# drbd-overview 

NOTE: drbd-overview will be deprecated soon.

Please consider using drbdtop.


 1:mysql/0  Connected Primary/Secondary UpToDate/UpToDate /test ext4 991M 32M 892M 4% 


恢复正常!!!