1. #!/bin/bash
  2.  
  3. dir=`dirname $0`
  4. prg=`basename $0`
  5. tmp=$dir/$prg.$$.tmp
  6.  
  7. function log
  8. {
  9.   echo "`date +'%m/%d %H:%M:%S'` $1"
  10. }
  11.  
  12. trap 'rm -f ${tmp}* ; exit' 0 1 2 3 9 15 19 23 24
  13.  
  14. DB_HOST="127.0.0.1"
  15. DB_NAME=ui
  16. delay=60
  17. NOTIFICATION_MULTIPLE=12
  18. STOP_WHEN_SECS=30
  19. QUIET="N"
  20.  
  21. # Override default parameters
  22. . $dir/admin.cnf
  23.  
  24. USAGE="$prg [-h <host>] [-d <db>] [-i <delay>] [-n <notification multiple>] [-s <stop when secs>]"
  25.  
  26. # Parse the command line arguments:
  27. while getopts h:d:i:n:s:q c ; do
  28.   case $c in
  29.     h)  DB_HOST="${OPTARG}" ;;
  30.     d)  DB_NAME="${OPTARG}" ;;
  31.     i)  delay="${OPTARG}" ;;
  32.     n)  NOTIFICATION_MULTIPLE="${OPTARG}" ;;
  33.     s)  STOP_WHEN_SECS="${OPTARG}" ;;
  34.     q)  QUIET="Y" ;;
  35.     *)  echo "$USAGE" ; exit 2 ;;
  36.   esac
  37. done
  38.  
  39. MYSQL="mysql -D $DB_NAME -h $DB_HOST"
  40.  
  41. prev="999"
  42. passed=0
  43. count=0
  44. while [ $prev -gt $STOP_WHEN_SECS ] ; do
  45.   #echo "S: prev=$prev curr=$curr start=$start passed=$passed STOP_WHEN_SECS=$STOP_WHEN_SECS"
  46.   count=$((count+1))
  47.  
  48.   SBM=$($MYSQL -e 'show slave status\G' | grep Seconds_Behind_Master | awk '{print $2}')
  49.   if [ "$SBM" == "NULL" ] ; then
  50.     $MYSQL -e 'show slave status\G' | mail -s "$prg: Slave is broke. Exitting on $DB_HOST" $RECIPIENTS
  51.     exit
  52.   fi
  53.  
  54.   curr=$($MYSQL -NB -e 'select unix_timestamp(now())-unix_timestamp(ts) from heartbeat')
  55.   if [ $prev == 999 ] ; then
  56.     prev=$curr
  57.     start=$curr
  58.     passed=$delay
  59.     echo "           s_behind d_behind   c_sec_s   eta_d | O_c_sec_s O_eta_d O_eta_h     ETA"
  60.     sleep $delay
  61.     #echo "M: prev=$prev curr=$curr start=$start passed=$passed STOP_WHEN_SECS=$STOP_WHEN_SECS"
  62.     continue
  63.   fi
  64.  
  65.   if [[ $((count%10)) == 0 ]] ; then
  66.     echo "           s_behind d_behind   c_sec_s   eta_d | O_c_sec_s O_eta_d O_eta_h     ETA"
  67.   fi
  68.  
  69.   passed=$((passed+delay))
  70.   echo "$prev $curr $start $passed $delay" | awk '
  71.  {
  72.    prev=$1; curr=$2; start=$3; passed=$4; delay=$5;
  73.    speed = (delay-(curr-prev))/delay;
  74.    o_speed = (start-(curr-passed))/passed
  75.    if (speed == 0)    speed_d = 1;
  76.      else             speed_d = speed;
  77.    eta = curr/speed_d;
  78.    if (eta<0)         eta = -86400;
  79.    o_eta = curr/o_speed;
  80.    printf("%8d %8.6f %9.3f %7.3f | %9.3f %7.3f %7.2f %7s\n",
  81.       curr, curr/86400, speed, eta/86400, o_speed, o_eta/86400, o_eta/3600,
  82.       strftime("%H:%M",systime()+o_eta))
  83.  }' | while read s_behind d_behind c_sec_s eta_d pipe O_c_sec_s O_eta_d O_eta_h eta ; do
  84.     printf "%11s%8d %8.6f %9.3f %7.3f | %9.3f %7.3f %7.2f %7s\n" "`date +'%m/%d %H:%M'`" $s_behind $d_behind $c_sec_s $eta_d $O_c_sec_s $O_eta_d $O_eta_h $eta
  85.     if [ $curr -lt $STOP_WHEN_SECS ] ; then
  86.       if [ "$QUIET" == "N" ] ; then
  87.         $MYSQL -e 'show slave status\G' | mail -s "$prg: slave is caught up! on $DB_HOST" $RECIPIENTS
  88.       fi
  89.       exit
  90.     fi
  91.     if [ "$QUIET" == "N" ] ; then
  92.     if [[ $((count%NOTIFICATION_MULTIPLE)) == 0 ]] ; then
  93.       echo "Estimated time to catchup: ${O_eta_h}h, ETA: $eta" | mail -s "$prg: slave is ${curr}s behind on $DB_HOST" $RECIPIENTS
  94.     fi
  95.     fi
  96.   done
  97.  
  98.   prev=$curr
  99.   sleep $delay
  100.   #echo "E: prev=$prev curr=$curr start=$start passed=$passed STOP_WHEN_SECS=$STOP_WHEN_SECS"
  101. done