使用 DRBD 与 Heartbeat 实现 Mysql 高可用
2014-06-26 by dongnan
环境
软件
操作系统: RHEL 6.2
软件版本: drbd-8.4.4
软件版本: heartbeat-3.0.4
软件版本: mysql-server-5.1.52
磁盘
建议使用相同大小的分区或磁盘,本例假设使用分区 /dev/sdb1 配置如下:
物理磁盘: /dev/sdb
DRBD磁盘: /dev/drbd0
网络
主机名&角色
tail -n2 /etc/hosts
172.27.233.41 pn1   # 主节点
172.27.233.42 pn2   # 备节点
Heartbeat 使用 eth0 网络设备
pn1(主): 172.27.233.41
pn2(备): 172.27.233.42
vip: 172.27.233.48
DRBD 使用 eth1 网络设备
pn1(主): 10.0.0.41
pn1(备): 10.0.0.42
注意,eth1网络设备使用网线直连。
要求
- 两个节点的时间必须同步,建议使用 ntpdate同步时间。
- 两个节点间能够互相通信,并且可以解析对方主机名(修改/etc/hosts文件)。
- 确保 uname -n得到的结果和主机名保持一致。
- 禁止 mysqld服务开机自动启动
- 关闭 selinux 、iptables(或者打开用于同步数据的端口)。
DRBD
安装
配置
如果没有使用安装脚本部署drbd,可以按照下面的步骤配置:
主配置文件:drbd.conf 将会载入 drbd.d 目录下的 global_common.conf 与 res 结尾的配置文件。
tail -n2 /etc/drbd.conf
include "drbd.d/global_common.conf";
include "drbd.d/*.res";
主配置文件
# 备份
cp /etc/drbd.d/global_common.conf /etc/drbd.d/global_common.conf.bak
# 编辑
vim /etc/drbd.d/global_common.conf
部分配置选项
global {
    usage-count yes;        #是否对使用信息作统计,默认为yes
}
startup {
    wfc-timeout 120;       #等待连接的超时时间
    degr-wfc-timeout 120;  
}
disk {
    on-io-error detach;    #当IO出现错误时执行的动作
}
net {
    protocol C;            #复制模式为第3种
    verify-alg md5;        #同步的验证方式
}
资源文件
以res结尾的文件是资源文件,以为mysql创建资源文件为例,操作步骤如下:
# 编辑
vim /etc/drbd.d/mysql.res
# 内容
resource mysql {     #定义资源名称为mysql,名字不能包含空格
        on pn1 {     #定义primary节点的配置
                device /dev/drbd0;          #定义drbd设备
                disk /dev/sdb1;             #定义使用的磁盘分区
                address 10.0.0.41:20000;    #定义节点的IP和对应端口
                meta-disk internal;
        }
        on pn2 {     #定义secondary节点的配置                    
                device /dev/drbd0;
                disk /dev/sdb1;
                address 10.0.0.42:20000;
                meta-disk internal;
        }
}
备份节点
复制配置文件至pn2即可
scp -r /etc/drbd.d/* root@pn2:/etc/drbd.d/
创建元数据
分别在两个节点上执行以下命令
drbdadm create-md mysql
启动DRBD
分别在两个节点上执行,单独启动一个节点时,会一直处在等待另一个节点上线状态:
/etc/init.d/drbd start
查看drbd状态
cat /proc/drbd
version: 8.4.4 (api:1/proto:86-101)
GIT-hash: 599f286440bd633d15d5ff985204aff4bccffadd build by root@pn1, 2013-11-24 14:15:03
 0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C 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:20970844
可以看到两个节点并磁盘未同步(Inconsistent),而且角色都处于Secondary状态。
同步数据
pn1设置成为主节点并开始同步数据:
drbdadm -- --overwrite-data-of-peer primary mysql
cat /proc/drbd
version: 8.4.4 (api:1/proto:86-101)
GIT-hash: 599f286440bd633d15d5ff985204aff4bccffadd build by root@pn1, 2014-06-25 10:47:16
 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:5201860 nr:0 dw:0 dr:5202524 al:0 bm:317 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:41828
    [==================>.] sync'ed: 99.3% (40/5120)M
    finish: 0:00:03 speed: 13,884 (11,792) K/sec
注意: --overwrite参数仅适用于初次设置,并且触发数据同步。
同步完成后的状态:

注意: 磁盘状态将转变为 UpToDate/UpToDate。
创建文件系统
同步完成后就可以为其格式化文件系统,注意要在pn1(primary)上执行:
mkfs.ext4 /dev/drbd0
DRBD同步测试
主节点
mkdir /mysqldata
mount /dev/drbd0 /mysqldata
写入测试
hostname > /mysqldata/file
将设备卸载,同时将角色由主降为备
umount /mysqldata
drbdadm secondary mysql
备份节点
将pn2角色升为主,同时挂载drbd0设备
mkdir /mysqldata
drbdadm primary mysql  
mount /dev/drbd0 /mysqldata
读取测试
cat /mysqldata/file
卸载drbd设备
umount /mysqldata
drbdadm secondary mysql
注意: 在pn1写入的数据,pn2挂载后可以正常读写,说明同步成功。
注意事项
- 两个节点中,同一个时刻只能有一台处于primary状态,另一台处于secondary状态;
- 挂载 drbd设备之前必须切换到primary状态;
- 处于 secondary状态的服务器上不能挂载drbd设备;
- 转换状态之前,确保drbd设备没有挂载;
- 确保两个节点的drbd服务开机启动chkconfig drbd on。
Mysql
安装
yum install mysql-server
配置
停止服务:
/etc/init.d/mysqld stop
更改mysql数据目录,设置在 drbd 设备上:
# 编辑
vim /etc/my.cnf
# 内容
[mysqld]
datadir=/mysqldata
验证
挂载 drbd 设备,pn1 确保角色为primary:
drbdadm primary mysql
mount /dev/drbd0 /mysqldata
拷贝数据到drbd0设备
cp -r /data/mysql/* /mysqldata/
chown -R mysql.mysql /mysqldata/
启动mysql服务:
/etc/init.d/mysqld start
检查mysql服务是否存活:
mysqladmin -uroot ping
mysqld is alive
没有错误信息,代表mysql工作正常,最后关闭mysqld服务:
tail /mysqldata/pn1.err
/etc/init.d/mysqld stop
备份节点
pn2(secondary)节点需要执行
- 安装mysql数据库
- 停止mysql服务
- 更改mysql数据目录
- 更改mysql数据目录的属主与属组
注意事项
确保 mysqld 服务开机禁止启动(chkconfig mysqld off),Heartbeat 会启动mysqld服务。 
Heartbeat
安装
在两个节点安装 heartbeat 过程略。
配置
cd /usr/share/doc/heartbeat*/
cp authkeys haresources ha.cf /etc/ha.d/
cd /etc/ha.d/
主配置文件
# 编辑配置文件
vim /etc/ha.d/ha.cf
# 清空并添加以下内容
debugfile /var/log/ha.debug
logfile /var/log/ha.log
keepalive 1
deadtime 30
initdead 120
udpport 1694
auto_failback off
ucast eth0 172.27.233.42   # 注意这里填写对方IP
node pn1
node pn2
ping 172.27.233.254     # 这里为网关/路由器IP
respawn hacluster /usr/lib64/heartbeat/ipfail
crm off
注意: 根据实际情况,修改配置参数
参数含义
- debugfile /var/log/ha.debug: 日志
- logfile /var/log/ha.log: 日志
- keepalive 1: 心跳频率,1表示1秒;- 200ms则表示- 200毫秒
- deadtime 30: 节点死亡时间,就是过了- 30秒后还没有收到心跳就认为对方节点死亡
- initdead 120: 初始化时间
- udpport 1694: 心跳使用- udp协议- 1694端口
- auto_failback off: 主节点恢复过后主动抢占资源,如果为- off则只当备用节点当掉后,主节点才取回资源
- ucast eth0 172.27.233.42: 定义单播心跳包从哪个接口发出,采用udp单播来通知心跳,注意这里填写对方IP
- node pn1: 主节点名称
- node pn2: 备用节点名称
- ping 172.27.233.254: 通过ping 网关来监测心跳是否正常
认证文件
# 编辑文件
vim /etc/ha.d/authkeys
#添加以下内容
auth 1
1 md5 testheartbeat  # md5后边的字符串为密码
# 更改认证文件权限为600
chmod 600 /etc/ha.d/authkeys
资源文件
# 定义资源,`VIP`,`DRBD`设备挂载,`mysqld`服务
vim /etc/ha.d/haresources
# 添加以下内容
# 其中 172.27.233.58 为VIP
pn1 IPaddr::172.27.233.48/24/eth0 drbddisk::mysql Filesystem::/dev/drbd0::/mysqldata::ext4  mysqld
备份节点
拷贝配置文件至备份节点
scp -p authkeys haresources ha.cf root@pn2:/etc/ha.d/
注意: 注意需要根据实际情况,修改备份节点的配置文件.
验证
卸载drbd设备,将角色由主降为备:
umount /mysqldata
drbdadm secondary mysql
启动主备节点的heartbeat服务:
service heartbeat start
主节点绑定VIP:
ifconfig eth0:0
eth0:0    Link encap:Ethernet  HWaddr 00:50:56:9C:00:0C  
          inet addr:172.27.233.48 Bcast:172.27.233.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
主节点挂载drbd设备:
mount | tail -n1
/dev/drbd0 on /mysqldata type ext4 (rw)
主节点 mysql 服务已经启动:
mysqladmin ping
mysqld is alive
注意事项
- 确保两个节点的heartbeat服务开机启动(chkconfig heartbeat on)。
- 在两个节点的 ha.cf配置文件定义单播心跳包,这里填写对方节点IP。