zoukankan      html  css  js  c++  java
  • pt-heartbeat使用实践

    今天无意中看到了沃趣网络科技的一篇文章请不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间感觉分析的相当不错,该文章中也提到了使用pt-heartbeat这个工具检测主从延迟时间。而且我转载的一篇博文也说明了Seconds_Behind_Master的真正含义,所以还是决定自己使用pt-heartbeat这个工具,顺便在此记录一下。

    工作原理:

    1,在主上创建一张heartbeat表,按照一定的时间频率更新该表的字段(把时间更新进去)。

    2,连接到从上检查复制的时间记录,和从库的当前系统时间进行比较,得出时间的差异。

     使用方法:

    pt-heartbeat [OPTIONS] [DSN] --update|--monitor|--check|--stop

    在主库上开启守护进程来更新yayun.heartbeat表:

    pt-heartbeat -D yayun --update -h master-server --daemonize

     监控从的延迟情况:

    pt-heartbeat -D yayun --monitor -h slave-server   #一直执行,不退出
    pt-heartbeat -D yayun--check h=slave-server       #执行一次就退出

    常用参数:

    复制代码
    注意:需要指定的参数至少有 --stop,--update,--monitor,--check。其中--update,--monitor和--check是互斥的,--daemonize和--check也是互斥。
    
    --ask-pass
    隐式输入MySQL密码
    
    --charset
    字符集设置
    
    --check
    检查从的延迟,检查一次就退出,除非指定了--recurse会递归的检查所有的从服务器。
    
    --check-read-only
    如果从服务器开启了只读模式,该工具会跳过任何插入。
    
    --create-table
    在主上创建心跳监控的表,如果该表不存在。可以自己建立,建议存储引擎改成memory。通过更新该表知道主从延迟的差距。
    CREATE TABLE heartbeat (
      ts                    varchar(26) NOT NULL,
      server_id             int unsigned NOT NULL PRIMARY KEY,
      file                  varchar(255) DEFAULT NULL,    -- SHOW MASTER STATUS
      position              bigint unsigned DEFAULT NULL, -- SHOW MASTER STATUS
      relay_master_log_file varchar(255) DEFAULT NULL,    -- SHOW SLAVE STATUS
      exec_master_log_pos   bigint unsigned DEFAULT NULL  -- SHOW SLAVE STATUS
    );
    heratbeat表一直在更改ts和position,而ts是我们检查复制延迟的关键。
    
    --daemonize
    执行时,放入到后台执行
    
    --user
    -u,连接数据库的帐号
    
    --database
    -D,连接数据库的名称
    
    --host
    -h,连接的数据库地址
    
    --password
    -p,连接数据库的密码
    
    --port
    -P,连接数据库的端口
    
    --socket
    -S,连接数据库的套接字文件
    
    --file 【--file=output.txt】
    打印--monitor最新的记录到指定的文件,很好的防止满屏幕都是数据的烦恼。
    
    --frames 【--frames=1m,2m,3m】
    在--monitor里输出的[]里的记录段,默认是1m,5m,15m。可以指定1个,如:--frames=1s,多个用逗号隔开。可用单位有秒(s)、分钟(m)、小时(h)、天(d)。
    
    --interval
    检查、更新的间隔时间。默认是见是1s。最小的单位是0.01s,最大精度为小数点后两位,因此0.015将调整至0.02。
    
    --log
    开启daemonized模式的所有日志将会被打印到制定的文件中。
    
    --monitor
    持续监控从的延迟情况。通过--interval指定的间隔时间,打印出从的延迟信息,通过--file则可以把这些信息打印到指定的文件。
    
    --master-server-id
    指定主的server_id,若没有指定则该工具会连到主上查找其server_id。
    
    --print-master-server-id
    在--monitor和--check 模式下,指定该参数则打印出主的server_id。
    
    --recurse
    多级复制的检查深度。模式M-S-S...不是最后的一个从都需要开启log_slave_updates,这样才能检查到。
    
    --recursion-method
    指定复制检查的方式,默认为processlist,hosts。
    
    --update
    更新主上的心跳表。
    
    --replace
    使用--replace代替--update模式更新心跳表里的时间字段,这样的好处是不用管表里是否有行。
    
    --stop
    停止运行该工具(--daemonize),在/tmp/目录下创建一个“pt-heartbeat-sentinel” 文件。后面想重新开启则需要把该临时文件删除,才能开启(--daemonize)。
    
    --table
    指定心跳表名,默认heartbeat。
    复制代码

    测试环境: 

    Master  192.168.0.10:3306
    Slave   192.168.0.20:3306

    1,在主上运行:--daemonize表示守护进程,后台运行。

    [root@yayun_192.168.0.10 ~]# pt-heartbeat --user=root --ask-pass --host=127.0.0.1 --create-table -D yayun --interval=1 --update --replace --daemonize
    Enter password: 
    [root@yayun_192.168.0.10 ~]# 
    [root@yayun_192.168.0.10 ~]# pgrep -fl pt-heartbeat
    4156 perl /usr/bin/pt-heartbeat -D yayun --table=heartbeat --create-table --update -h 127.0.0.1 -uroot --ask-pass --daemonize
    [root@yayun_192.168.0.10 ~]# 

    3.在主上运行监测复制延迟

    [root@yayun_192.168.0.10 ~]# pt-heartbeat -D yayun --table=heartbeat --monitor -h 192.168.0.20
    0.00s [  0.00s,  0.00s,  0.00s ]
    0.00s [  0.00s,  0.00s,  0.00s ]
    0.00s [  0.00s,  0.00s,  0.00s ]
    0.00s [  0.00s,  0.00s,  0.00s ]
    0.00s [  0.00s,  0.00s,  0.00s ]

    0表示从没有延迟。 [ 0.00s, 0.00s, 0.00s ] 表示1m,5m,15m的平均值。可以通过--frames去设置。

    我们这里看见复制没有延迟,那么我们可以使用压力工具测试一下。在主库创建测试数据库sbtest;

    mysql> create database sbtest;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> 

    开始生成100w记录的数据

    复制代码
    [root@yayun_192.168.0.10 ~]#  sysbench --test=oltp --oltp-table-size=1000000 --oltp-read-only=off --init-rng=on --num-threads=16 --max-requests=0 --oltp-dist-type=uniform --max-time=1800 --mysql-user=root --mysql-socket=/tmp/mysqld.sock --mysql-password=123456 --db-driver=mysql --mysql-table-engine=innodb --oltp-test-mode=complex prepare
    sysbench 0.4.10:  multi-threaded system evaluation benchmark
    
    Creating table 'sbtest'...
    Creating 1000000 records in table 'sbtest'...
    复制代码

    再次检测复制延时:

    复制代码
    [root@yayun_192.168.0.10 ~]# pt-heartbeat -D yayun --table=heartbeat --monitor -h 192.168.0.20
    28.21s [  0.47s,  0.09s,  0.03s ]
    28.72s [  0.95s,  0.19s,  0.06s ]
    29.38s [  1.44s,  0.29s,  0.10s ]
    29.13s [  1.92s,  0.38s,  0.13s ]
    30.85s [  2.44s,  0.49s,  0.16s ]
    31.04s [  2.96s,  0.59s,  0.20s ]
    29.84s [  3.45s,  0.69s,  0.23s ]
    31.24s [  3.97s,  0.79s,  0.26s ]
    32.20s [  4.51s,  0.90s,  0.30s ]
    32.96s [  5.06s,  1.01s,  0.34s ]
    33.82s [  5.62s,  1.12s,  0.37s ]
    34.15s [  6.19s,  1.24s,  0.41s ]
    复制代码

    立马发现效果了哦^_^

    我们还可以使用--check监测一次就退出:

    [root@yayun_192.168.0.10 ~]# pt-heartbeat -D yayun --table=heartbeat --check -h 192.168.0.20
    0.00
    [root@yayun_192.168.0.10 ~]# 

    2,如何关闭主上面执行的后台进程。可以用参数--stop 去关闭:

    [root@yayun_192.168.0.10 ~]# pt-heartbeat --stop
    Successfully created file /tmp/pt-heartbeat-sentinel
    [root@yayun_192.168.0.10 ~]# 

    这样就把在主上开启的进程杀掉了,后续要继续开启后台进行的话,需要把/tmp/pt-heartbeat-sentinel 文件删除,否则启动不了。

    总结:

          通过pt-heartbeart工具可以很好的弥补默认主从延迟的问题,但需要搞清楚该工具的原理。而默认的Seconds_Behind_Master值是通过将服务器当前的时间戳与二进制日志中的事件时间戳相对比得到的,所以只有在执行事件时才能报告延时。备库复制线程没有运行,也会报延迟null。还有一种情况:大事务,一个事务更新数据长达一个小时,最后提交。这条更新将比它实际发生时间要晚一个小时才记录到二进制日志中。当备库执行这条语句时,会临时地报告备库延迟为一个小时,执行完后又很快变成0。

    ------------------

    对于MySQL数据库主从复制延迟的监控,我们可以借助percona的有力武器pt-heartbeat来实现。pt-heartbeat通过使用时间戳方式在主库上更新特定表,然后在从库上读取被更新的时间戳然后与本地系统时间对比来得出其延迟。本文主要是通过脚本来定期检查从库与主库复制的延迟度并发送邮件,供大家参考。

    有关pt-heartbeat工具的安装可以参考:percona-toolkit的安装及简介

    1、脚本概述

    2、脚本内容

    [mysql@SZDB run]$ more ck_slave_lag.sh 
    #!/bin/bash
    #set -x
    if [ $# -ne 3 ];then
          echo "usage:"
          echo "ck_slave_lag.sh <Servier-id> <MaxLag> <LogDir>"
          exit 0;
    fi
    
    # Author : Leshami
    # Blog   : http://blog.csdn.net/leshami
    
    ServerID=$1
    MaxLag=$2
    LogDir=$3
    Timestamp=`date +%Y%m%d_%H%M%S`
    Rentition=7
    LogFile=$LogDir/slave_lag_$Timestamp.log
    LagDetail=$LogDir/slave_lag_Detail_$Timestamp.log
    mailadd=leshami@12306.cn
    
    echo $ServerID
    echo $MaxLag
    echo $LogDir
    echo $LogFile
    echo $LagDetail
    echo $mailadd
    
    if [ ! -d $LogDir ];then
        mkdir -p $LogDir
    fi
    
    Lag=`/usr/bin/pt-heartbeat --user=monitor --password=xxx -S /tmp/mysql.sock -D test --master-server-id=$ServerID --check`
    Lag=`echo ${Lag%.*}`
    #Lag=3
    echo $Lag
    ptStatus=`ps -ef|grep pt-heart|grep daemonize`
    echo $ptStatus
    
    if [ $Lag -gt $MaxLag ]; then
        echo "The current date is `date` at `hostname`."          >>$LogFile 
        echo "The current lag log file is $LogFile."              >>$LogFile
        echo "The current replication lag is $Lag."               >>$LogFile
        echo "The replication lag is larger than max lag $MaxLag." >>$LogFile
       
        if [ -z "$ptStatus" ] ; then
            echo "Start a monitor daemon with below command: "        >>$LogFile 
            echo "pt-heartbeat --user=monitor --password=xxx -S /tmp/mysql.sock -D test " >>$LogFile
            echo " --master-server-id=11 --monitor --print-master-server-id --daemonize --log=$LagDetail" >>$LogFile
            /usr/bin/pt-heartbeat --user=monitor --password=xxx -S /tmp/mysql.sock -D test 
            --master-server-id=$ServerID --monitor --print-master-server-id --daemonize --log=$LagDetail
            echo "More detail please check lag log from $LagDetail." >>$LogFile
            cat $LogFile | mutt -s "Found slave lag on `hostname`." $mailadd
        fi
    fi
    
    if [ -n "$ptStatus" ] ; then
        STime=`ps -ef|grep pt-heart|grep daemonize |gawk '{print $5}'`
        Pid=`ps -ef|grep pt-heart|grep daemonize |gawk '{print $2}'`
        STime=`date '+%Y%m%d'`" "$STime
        s_STime=`date -d "$STime" '+%s'`
        s_ETime=`date +%s`
        DiffSec=`expr $s_ETime - $s_STime`
    
        echo $STime
        echo $s_STime
        echo $s_ETime
        echo $DiffSec
    
        if [ "$DiffSec" -gt 1800 ]; then
           echo "kill -9 $Pid"
           kill -9 $Pid
        fi
    fi
    
    # Remove history slave lag log.
    find $LogDir -name "*slave_lag*" -ctime +$Rentition -delete 
    exit


    3、部署参考

    [mysql@SZDB run]$ crontab -l
    
    #check slave lag
    */1 * * * * /run/ck_slave_lag.sh 11 3 /log/SlaveLag
    
  • 相关阅读:
    物理CPU,物理核,逻辑CPU,虚拟CPU(vCPU)区别 (转)
    JVM学习一:常用JVM配置参数
    docker架构
    Linux查看服务器配置
    redis清缓存
    httpclient源码分析之 PoolingHttpClientConnectionManager 获取连接 (转)
    CentOs7.6配置邮件服务并发送邮件
    linux之dmesg命令
    docker部署springboot项目
    如何查看文件是dos格式还是unix格式的?
  • 原文地址:https://www.cnblogs.com/moss_tan_jun/p/6138201.html
Copyright © 2011-2022 走看看