mysql主从复制的延时判断

前言

mysql主从复制虽然让我们的数据有了保障,为我们提供了高可用的基础,但是由于master的dump线程是多线程,而slave的SQL线程是单线程,在高并发的场景下,二者速度差异被放大,所以会造成复制延时,如果此时master宕机,master的事务还没有被提交,或者提交了以后slave还没有把数据复制到relylog上,此时故障切换,slave成为了主,那么这部分数据就会丢失。这也是为什么一直一来Mysql主从复制的延时一直都是这个架构的痛点,官方和社区爱好者也在为减少同步延时而不断努力着,直到mysql5.6提供基于库的多线程复制,还有Mariadb的并行复制,但是使用5.5的版本也比较多。如何准确判断复制是否存在延时呢?可以通过pt-heartbeat工具或者用shell/python脚本完成。

判断复制延时的标准

切记不要通过Second_Behind_Master去判断,因为该值仅表示slave上的IO线程和SQL线程之间的延迟。先贴出slave_status配置文件

1.首先看Master_Log_File(master文件位置) 和Relay_Master_Log_File(sql线程执行的文件位置) 是否有差异,如果有差异证明二者延迟很大。

2.如果二者没有差异,进一步比较 Exec_Master_Log_Pos(sql线程执行的Pos位置) 和 Read_Master_Log_Pos (master的Pos位置)的差异,如果前者的值小于后者,证明存在延迟。那么更加严谨的做法是同时在主库执行show master status和在从库上面执行show slave status 的输出进行比较。MHA就是这样保证数据一致性的。MMM都没有做到。这也算MHA比MMM更加优秀的地方。

3.这里<Relay_Master_Log_File+Exec_Master_Log_Pos >对应着<Relay_Log_File, Relay_Log_Pos>都是一个东西,都代表着slave当前sql线程执行日志的位置点。既然有了(Relay_Master_Log_File, Exec_Master_Log_Pos)能够表明同步状态,还要(Relay_Log_File, Relay_Log_Pos)做什么呢? 我感觉(Relay_Log_File, Relay_Log_Pos) 是给程序看的,记录Relay log中的执行点, 而(Relay_Master_Log_File, Exec_Master_Log_Pos)可以给人看,能够清楚的表明Master和Slave之间的同步状态。

书写判断脚本

#王庭威
# slave
s_psswd=123456
s_user=root
s_port=3306
s_host=localhost

# master
m_psswd=123456
m_user=repl
m_port=3306
m_host=192.168.137.101

slave_wan_ip=`ip a |grep ens33 |grep inet |awk ‘{print $2}’`

while true
do
sleep 1
echo -e “\e[1;33m###################################\e[0m”
Master_Log_File=$(mysql -u$s_user -p$s_psswd -h$s_host -P$s_port -e “show slave status\G” | grep -w Master_Log_File | awk -F”: ” ‘{print $2}’)
Relay_Master_Log_File=$(mysql -u$s_user -p$s_psswd -h$s_host -P$s_port -e “show slave status\G” | grep -w Relay_Master_Log_File | awk -F”: ” ‘{print $2}’)
Read_Master_Log_Pos=$(mysql -u$s_user -p$s_psswd -h$s_host -P$s_port -e “show slave status\G” | grep -w Read_Master_Log_Pos | awk -F”: ” ‘{print $2}’)
Exec_Master_Log_Pos=$(mysql -u$s_user -p$s_psswd -h$s_host -P$s_port -e “show slave status\G” | grep -w Exec_Master_Log_Pos | awk -F”: ” ‘{print $2}’|sed ‘s/[ \t]*$//g’)
Master_Log_File_Num=`echo $Master_Log_File | awk -F ‘.’ ‘{print $2}’ | sed ‘s/^0\+//’`
Master_File=$(mysql -u$m_user -p$m_psswd -h$m_host -P$m_port -Nse “show master status” | awk ‘{print $1}’)
Master_Pos=$(mysql -u$m_user -p$m_psswd -h$m_host -P$m_port -Nse “show master status” | awk ‘{print $2}’|sed ‘s/[ \t]*$//g’)
Master_File_Num=`echo $Master_File | awk -F ‘.’ ‘{print $2}’ | sed ‘s/^0\+//’`

if [ -z $Master_Log_File ] && [ -z $Relay_Master_Log_File ] && [ -z $Read_Master_Log_Pos ] && [ -z $Exec_Master_Log_Pos ]
then
echo -e “\e[1;31mSLAVE 没有取到值,请检查参数设置!\e[0m”
exit 1
fi

if [ $Master_Log_File = $Relay_Master_Log_File ] && [ $Read_Master_Log_Pos = $Exec_Master_Log_Pos ]
then
if [ $Master_Log_File = $Master_File ] && [ $Exec_Master_Log_Pos = $Master_Pos ]
then
echo -e “\e[1;32mMaster-slave 复制无延迟 ^_^\e[0m”
else
if [ $Master_Log_File_Num -lt $Master_File_Num ] || [ $Master_Pos -lt $Exec_Master_Log_Pos ]
then
log_count=$(expr $Master_file_Num – $Master_Log_File_Num)
pos_count=$(expr $Master_Pos – $Exec_Master_Log_Pos)
echo -e “\e[1;31mMaster-slave 复制延迟 !!!\e[0m”
echo -e “\e[1;31mMaster:$m_host Slave:$slave_wan_ip\e[0m”
echo -e “\e[1;31mMaster当前binlog: $Master_File”
echo -e “\e[1;31mSlave当前binlog: $Master_Log_File”
echo -e “\e[1;31mbinlog相差文件数: $log_count\e[0m”
echo -e “\e[1;31mPos点相差: $pos_count\e[0m”
fi
fi
fi
done

 

 

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Loading...