从库执行show slave status \G;
查看字段 Seconds_Behind_Master。
1、主从无延迟的时候Seconds_Behind_Master值为0。
2、当从库IO线程或者SQL线程故障时,Seconds_Behind_Master值为NULL。
A:备库Seconds_behand_master值是通过将服务器当前的时间戳与二进制日志中的事件的时间戳对比得到的,所以只有在执行事件时才能报告延迟
B:如果备库复制线程没有运行,就会报延迟为null
C:一些错误,如主备的max_allowed_packet不匹配或者网络不稳定时,可能中断复制或者停止复制线程,但Seconds_behand_master将显示为0而不是显示错误
D:即使备库线程正在运行,备库有时候可能无法计算延迟时,如果发生这种情况,备库会报0或者null
E:一个较大的事务可能导致延迟波动,如:有一个事务更新数据长达一个小时,最后提交,这条更新将比它实际发生时间要晚一个小时才记录到二进制日志中,当备库执行这条语句时,会临时地报告备库延迟一个小时,然后很快又变回0
F:如果分发主库落后了,并且其本身也有已经追赶上它的备库,备库的延迟将显示为0,而事实上备库和源主库之间此时是有延迟的。
#desc:脚本 #通过从库监控Seconds_Behind_Master的值监控延迟情况。 #该值为null或着超过告警阈值会报错. #本脚还通过mysql命令执行情况判定mysql服务可用状态。 #author:wjf #date:2018/04/27 source ~/.bash_profile source ~/.bashrc #----Seconds_Behind_Master的值 v_sbm='NULL' #----检测域值,单位s v_threshold=-1 #----机器标示 v_machine_mark=81.77_test4 #----发送手机号 v_mobile=`cat /home/oracle/bin/alert_dba_lists| grep -v "#"` #-----发送告警信息函数 function f_send_msg { if [ ! $# -eq 2 ] then echo "usage:" echo "f_send_msgexit 0; fi ${v_java_home_bin}/java -jar /opt/config/inf/alarm.jar 1 $1 $2 } #-----判定mysql服务状态 v_mysql_status=`mysql -uwjf_ro -p123 -e "show slave status\G"|grep Seconds_Behind_Master` if [ $? -eq 1 ] then v_err_msg="mysql is not available! " f_send_msg ${v_mobile} ${v_err_msg} exit fi #------判定延迟情况 v_sbm=`echo ${v_mysql_status}|awk -F ":" '{print $2}'` if [ "${v_sbm}" = " NULL" ] then v_err_msg="${v_machine_mark}_delay Seconds_Behind_Master is ${v_sbm}!" f_send_msg ${v_mobile} ${v_err_msg} elif [ ${v_sbm} -gt ${v_threshold} ] then v_err_msg="${v_machine_mark}_delay Seconds_Behind_Master is ${v_sbm}!" f_send_msg ${v_mobile} ${v_err_msg} fi "
pt-heartbeat是percona-toolkit工具箱中工具的一个。mysql环境中需要安装percona-toolkit。
pt-heartbeat工作原理如下
1,在主上创建一张heartbeat表,按照一定的时间频率更新该表的字段(把时间更新进去)。
2,从主库连接到从库上检查复制的时间记录,和主库的当前系统时间进行比较,得出时间的差异。
该方法能规避使用Seconds_Behind_Master的各种问题。
主库启用定时刷数据的后台进程
pt-heartbeat -D wjf2 -h localhost -P 3306 --user=root --ask-pass --create-table --daemoniz --interval=1 --update # -D 指定heartbeat表建在哪个库,该库需要时开启复制的库。 # -h -P指定连接的库IP和port信息,指定的连接信息库里面必须有权限。 # --user --ask-pass 执行连接的用户名和密码 # --create-table 指创建heartbeat表,若库里没有则创建。 # --daemoniz 该任务放在后台,持续执行。 # --intervael 指定update heartbeat表的频率,默认是1s # --update 更新主库的heartbeat表。 # --查看具体执行内容 mysql> use wjf; mysql> select * from heartbeat;
主库执行延迟监控命令
#----监控一次后退出 pt-heartbeat -D wjf -h slave_ip -P 3306 --user=root --ask-pass --check # --check参数执行一次并退出. #----持续监控 pt-heartbeat -D wjf -h slave_ip -P 3306 --user=root --ask-pass --monitor --interval=1 --log=/tmp/wjf_check.log --daemoniz #----监控结果 0.00s [ 0.00s, 0.00s, 0.00s ] 0表示从没有延迟。 [ 0.00s, 0.00s, 0.00s ] 表示1m,5m,15m的平均值。可以通过--frames去设置. # --monitor 持续监控 # --interval 每次监控时间间隔,默认1s # --log 将输出结果存放在日志文件。需要跟--daemoniz配合使用。 # --daemoniz 该任务放在后台,持续执行。
停止pt-heartbeat
#pt-heartbeat --stop Successfully created file /tmp/pt-heartbeat-sentinel #该命令会停掉所有pt-heartbeat进程,包括刷数据进程和监控进程。后续重新启动pt-heartbeat前需要先把/tmp/pt-heartbeat-sentinel删掉。 或者可以使用kill 方式。
#desc #本监控内容包含了 mysql主服务状态监控 、mysql从服务状态监控、pt-heartbeat进程监控、延迟时间监控。 #author:wjf #date:2018/04/27 #----延迟阈值 v_delay_threshold=1 #----机器标示 v_machine_mark=81.90_csdb #----连接信息 v_master_ip=172.16.81.90 v_master_port=3306 v_master_db=wjf v_master_user=wjf_ro v_master_passwd=123 v_slave_ip=172.16.81.77 v_slave_port=3306 #-----告警相关 #----发送手机号 v_mobile=`cat /home/oracle/bin/alert_dba_lists| grep -v "#"` #-----发送告警信息函数 function f_send_msg { if [ ! $# -eq 2 ] then echo "usage:" echo "f_send_msgexit 0; fi ${v_java_home_bin}/java -jar /opt/config/inf/alarm.jar 1 $1 $2 } v_hb_status=`ps -ef |grep pt-heartbeat|grep update|grep daemoniz|wc -l` v_ser_status=`mysql -u${v_master_user} -P${v_master_port} -p${v_master_passwd} -D${v_master_db} -e "exit"` if [ $? -eq 1 ] then v_err_msg="mysql service unavailable!" f_send_msg ${v_mobile} ${v_err_msg} exit 0 elif [ ${v_hb_status} -eq 0 ] then v_err_msg="pt-heartbeat is unavailable!" f_send_msg ${v_mobile} ${v_err_msg} exit 0 fi v_delay_time=`pt-heartbeat -h ${v_slave_ip} -P ${v_slave_port} -u ${v_master_user} -p ${v_master_passwd} -D ${v_master_db} --check` if [ ! $? -eq 0 ] then v_err_msg="slave mysql is unavailable!" f_send_msg ${v_mobile} ${v_err_msg} exit 0 elif [ `echo "${v_delay_time} >= ${v_delay_threshold}"|bc` -eq 1 ] then v_err_msg="${v_machine_mark}_delay time is ${v_delay_time}!" f_send_msg ${v_mobile} ${v_err_msg} fi "