MySQL主从复制配置心跳功能介绍
在MySQL主从复制时,有时候会碰到这样的故障:在Slave上Slave_IO_Running和Slave_SQL_Running都是Yes,Slave_SQL_Running_State显示Slavehasreadallrelaylog;waitingfortheslaveI/Othreadtoupdateit,看起来状态都正常,但实际却滞后于主,Master_Log_File和Read_Master_Log_Pos也不是实际主上最新的位置。一种可能是Master上的binlogdump线程挂了。但有时候,在Master上检查也是完全正常的。那Slave的延误又是怎么造成的呢?
在MySQL的复制协议里,由Slave发送一个COM_BINLOG_DUMP命令后,就完全由Master来推送数据,Master、Slave之间不再需要交互。如果Master没有更新,也就不会有数据流,Slave就不会收到任何数据包。但是如果由于某种原因造成Master无法把数据发送到Slave,比如发生过网络故障或其他原因导致Master上的TCP连接丢失,由于TCP协议的特性,Slave没有机会得到通知,所以也没法知道收不到数据是因为Master本来就没有更新呢还是由于出了故障。
好在MySQL5.5开始增加了一个复制心跳的功能。
如
stopslave; changemastertomaster_heartbeat_period=10; setglobalslave_net_timeout=25; startslave;
就会让Master在没有数据的时候,每10秒发送一个心跳包。这样Slave就能知道Master是不是还正常。slave_net_timeout是设置在多久没收到数据后认为网络超时,之后Slave的IO线程会重新连接Master。结合这两个设置就可以避免由于网络问题导致的复制延误。master_heartbeat_period单位是秒,可以是个带上小数,如10.5。最高精度为1毫秒。
slave_net_timeout的默认是3600,也就是一小时。也就是说,在之前的情况下,Slave要延误1小时后才会尝试重连。而在没有设置master_heartbeat_period时,将slave_net_timeout设得很短会造成Master没有数据更新时频繁重连。
很奇怪的是,当前的master_heartbeat_period值无法通过showslavestatus查看,而要使用showstatuslike‘Slave_heartbeat_period'查看。此外,状态变量Slave_last_heartbeat表示最后一次收到心跳的时间,Slave_received_heartbeats表示总共收到的心跳次数。
如:
mysql>showstatuslike'slave%'; +----------------------------+---------------------+ |Variable_name |Value | +----------------------------+---------------------+ |Slave_heartbeat_period |5.000 | |Slave_last_heartbeat |2014-05-0811:48:57| |Slave_open_temp_tables |0 | |Slave_received_heartbeats |1645 | |Slave_retried_transactions|0 | |Slave_running |ON | +----------------------------+---------------------+ 6rowsinset(0.00sec)