Heartbeat+DRBD+MySQL Replication故障处理

不久前的一次机房网络故障,再一次对我们在Heartbeat+DRBD+MySQL数据库架构运维水平的一个考验,之前不止一次的测试与线上部署,还有之后大言不惭的关于该架构组件的所谓深入理解,在这一次不经意的意外面前又是“很囧”的收场,慌张呀!这次断网导致H-D-M全线异常,真是千载难逢,都让我们赶上啦lol: 下面就把这次的小幸运小幸福和大家分享下,以下是按照问题处理的先后顺序依次讲述。

- MySQL Replication同步异常

当发生网络故障一个小时后,从库io_thread和主库的连接被中断,抛出错误提示:[ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236),没想到竟遇到了一个古董级的Bug,有点喜出望外了(心想,我也能遇到bug)。最后解决办法,只能拿备份重新做一遍主从。后来,好奇想查查,究竟是怎么导致这个问题,竟发现,从库relay log中的记录比主库binlog中的记录多了2条insert和1条update(0_0!!!…不合逻辑呀?!!)。

- DRBD状态异常

处理完数据库同步问题后,当时并没有去查看DRBD的状态,直到周一才发现出问题了,简单地通过命令cat /proc/drbd就可以查看,DRBD的状态是否正常。查看/var/log/messages知道网络故障导致DRBD发生脑裂,彼此都认为对方已经死了,然后自己都将角色作为Primary,并积极获取资源,当时的两端的连接状态都为StandAlone,角色都为Primary。在发生脑裂不久后原active node被heartbeat强制将系统重启,最后,原active node角色变为Secondary/Unknown,原standby node角色依然是脑裂时的Primary/Unknown,两端的连接状态,分别为WFConnection和StandAlone。解决方法如下:

Step 1 - On New Secondary:

# service heartbeat stop

# service drbd stop

# drbdadm create-md r0

# service drbd start

# service heartbeat start

Step 2 – On New Primary:

# service drbd reload

之后就进入漫长数据同步阶段,重新将Primary上的数据块文件拷贝到Secondary上,最后完成同步。

- Heartbeat通信异常

通过查看/var/log/ha-dug日志,发现在出现网络故障后4分钟内,Heartbeat服务在active node与standby node间反复做资源释放与获取的操作,最后资源被之前的standby node获得,而之前的active node因为DRBD资源的问题,请求系统重启“CRIT: Resource STOP failure. Reboot required!”。系统重启后,Heartbeat服务并没有被开启,chkconfig里面没有把heartbeat设置为开机自启动,drbd是被设置开启自启的。其实,周日在处理问题时,没有考虑到heartbeat问题,理所当然的人为,资源是被正常切换,而认为heartbeat当时是正常(~脸红~:<太业余了…),更不好意思的是,周一发现heartbeat没有开启,我手动开启后,“习惯性”地依旧没有查看日志,就默认它了(唉…鄙视我吧!)。最后是在第3天,田老师检查整个系统,发现ha-dug里面警示异常提示。折腾了半天,最后等到晚上访问低谷的时候,采取了看上去不是方法的办法,解决如下:

# less /var/log/ha-dug      — 发现问题

On Active Node(之前的standby–>切换后active):

WARN: Gmain_timeout_dispatch: Dispatch function for retransmit request took too long to execute: 390 ms (> 10 ms)

ERROR: Message hist queue is filling up (500 messages in queue)

On Standby Node(之前的active–>切换后standby):

WARN: Rexmit of seq 17224382 requested. 41 is max.

在当前的active node上执行如下命令:

# top  — 注意有4个僵尸进程(zombie),同时会发现heartbeat的cpu使用达到100%左右

Tasks: 245 total,   2 running, 239 sleeping,   0 stopped,   4 zombie

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

2106 root      -2   0  422m 376m 4788 R 100.1  1.6   5002:17 heartbeat

# ps aux |grep defunct |grep -v grep   — 找出是哪4个僵尸进程

root     15678  0.0  0.0      0     0 ?        Z    10:57   0:00 [heartbeat] <defunct>

root     17932  0.0  0.0      0     0 ?        Z    13:48   0:00 [heartbeat] <defunct>

root     19176  0.0  0.0      0     0 ?        Z    Jul11   0:00 [status] <defunct>

root     19626  0.0  0.0      0     0 ?        Z    Jul11   0:00 [heartbeat] <defunct>

既然,heartbeat服务有问题,那么很自然的就想到重启该服务,重启heartbeat是也会释放掉所有的资源的,会影响到正常业务,所以,选择到晚上闲时操作。出于安全为了不让资源切换到standby node上(其实,当时的情况heartbeat以及不能工作),我先停掉了standby node上的heartbeat,接着去停止active node上的服务,但是过了几分钟都没有相应,事实上,heartbeat的主进程已经僵死了,最后我“鼓足勇气”—kill -9 heartbeat-PID,然后先重启active node,再重启standby node,最后,查看日志一切都恢复正常了。之前,在做kill操作后,active node上的资源并没有释放,依然正常运行。
– — – END — – –
即便这次费不小的劲,看似把问题都一一解决了,但心里依然没谱,对于之后可能发生的问题还是没有十足的把握;事实上,还是对于Heartbeat和DRBD技术本身,理解的不够透彻,Heartbeat对于资源的切换、检测后的判断以及对于日志输出的理解都还有很多疑惑,DRBD发生脑裂时资源争夺,会对数据块有多大影响,等等,所以就像田老师的感慨说的,我们之前做的仅仅就是能够把这个架构简单的打起来而已,根本谈不上专业的运维。
文章来自:mysqlsystems
Comment are closed.