Please enable Javascript to view the contents

keepalived+mysql双主集群单主可写

 ·  ☕ 17 分钟  ·  ✍️ starifly · 👀... 阅读

keepalived高可用介绍及改造方案

具体配置-passwd方式

192.168.5.31

# keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id db01
}

vrrp_sync_group G1 {
 group {
  VI_1
}
}

vrrp_script check_run {
    script "/etc/keepalived/mysql_check.sh"
    interval 10
    fall 3
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens32
    virtual_router_id 51
    priority 100
    nopreempt
    advert_int 3
    authentication {
        auth_type PASS
        auth_pass admin#2023
    }
    track_interface {
          ens32
     }

    unicast_src_ip  192.168.5.31
    unicast_peer {
      192.168.5.32
    }
    track_script {
        check_run
    }
    virtual_ipaddress {
        192.168.5.190
    }
    notify_master "/etc/keepalived/change_to_master.sh"
    notify_backup "/etc/keepalived/change_to_backup.sh"
    notify_fault "/etc/keepalived/change_to_backup.sh"
}
# mysql_check.sh

#!/bin/bash

###############################################
#修改此处配置
#用户需要权限
#grant REPLICATION CLIENT  on *.* to mon_user@'%' ;
export HOME='/root'
master_ip='192.168.5.31'
master_port='3306'
master_mycom='mysql'
rep_ip='192.168.5.32'
rep_port='3306'
#记录日志位置
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'
find /etc/keepalived/  -name "keepalived_*.log" -mtime +7|xargs rm -rf
#################################################

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log}
}

logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}


check_pid()
#input:$1检查的进程关键字比如mysqld
#return:1 检测成功,但是需要注意有多个mysqld进程(物理服务器跑了多个实例)  0 检测失败,没有mysqld进程
{
  mysqld_cnt=`ps -ef|grep -w $1|grep -v 'grep'|wc -l`

  if test ${mysqld_cnt} -ge 2 ;then
     logging_log 'warn' 'more than one mysqld process!'
     return 1  #由于mysqld检测出有多个那么,只是告警而不做任何动作
  fi

  if test ${mysqld_cnt} -lt 1 ;then
     logging_log 'err' 'mysqld process is crash!!'
     logging_log_error 'err' 'mysqld process is crash!!'
     return 0 #检测mysqld已经不存在则直接进入从库检测流程
  fi

  logging_log 'info' 'one mysqld process check sucess.'
  return 1 #检测成功,进入语句检测
}


check_sta()
#input:NULL
#return:0 失败,主库测试语句不能执行 1 成功,主库测试语句可以执行
{
  #将stderr 写入到日志文件中,比如连接失败
  #${master_mycom} -h ${master_ip} -P ${master_port}  -u ${master_user} -p${master_password} -e 'select now()'
  ${master_mycom} -uroot -p123456 -h ${master_ip} -e 'select now()'
  if [ $? -eq 0 ]; then
    logging_log 'info' 'master:test select now() sucess.'
    return 1 #检测成功,测试语句能够执行
  else
    logging_log 'err' master:'test select now() fail!!'
    logging_log_error 'err' master:'test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

}


check_rep_apply_all()
#input:NULL
#return value:0 失败,检测不能切换 1 成功,检测可以切换
{
  #先测试从库是否可以连接
  ${master_mycom}  -uroot -p123456 -h ${rep_ip}  -e 'select now()'

  if [ $? -eq 0 ]; then
    logging_log 'info' 'rep:test select now() sucess.' #检测成功,测试语句能够执行,继续执行
  else
    logging_log 'err' 'rep:test select now() fail!!'
    logging_log_error 'err' 'rep:test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

  #不放到一条语句进行检测,多次检测可以提高检测的准确性
  Rep_Master_ip=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Master_Host | awk -F": " '{print $2}'`
  Rep_Master_port=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Master_Port | awk -F": " '{print $2}'`
  Slave_IO_Running=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Slave_IO_Running | awk -F": " '{print $2}'`
  Master_Log_File=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Master_Log_File | awk -F": " '{print $2}'`
  Relay_Master_Log_File=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Relay_Master_Log_File | awk -F": " '{print $2}'`
  Read_Master_Log_Pos=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Read_Master_Log_Pos | awk -F": " '{print $2}'`
  Exec_Master_Log_Pos=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Exec_Master_Log_Pos | awk -F": " '{print $2}'`
  Seconds_Behind_Master=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e  "show slave status\G" | grep -w Seconds_Behind_Master | awk -F": " '{print $2}'`

  if [ ${Rep_Master_ip} != ${master_ip} ]; then
     logging_log 'err' "rep:this rep ip ${Rep_Master_ip} is not master ip:${master_ip} !!"
     logging_log_error 'err' "rep:this rep ip ${Rep_Master_ip} is not master ip:${master_ip} !!"
     return 0 #检测失败,从库连接主库的ip和填写的主库ip不一致
  fi

  if [ ${Rep_Master_port} != ${master_port} ]; then
     logging_log 'err' "rep:this rep port ${Rep_Master_port} is not master port:${master_port} !!"
     logging_log_error 'err' "rep:this rep port ${Rep_Master_port} is not master port:${master_port} !!"
     return 0 #检测失败,从库连接主库的端口和填写的主库端口不一致
  fi

  if [ ${Master_Log_File} != ${Relay_Master_Log_File} ]; then
     logging_log 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     logging_log_error 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     return 0 #检测失败,从库读取的binlog文件和执行的binlog文件不一致
  fi

  if [ ${Read_Master_Log_Pos} != ${Exec_Master_Log_Pos} ]; then
     logging_log 'err' "rep:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     logging_log_error 'err' "rep:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     return 0 #检测失败,从库执行的binlog pos和执行的binlog pos不一致
  fi
  sleep 5
  ##是否需要检测IO线程状态,只有在IO线程运行异常的情况下进行切换
  if [ ${Slave_IO_Running} == 'Yes' ]; then
     logging_log 'err' "rep:this rep IO thread is running !!"
     logging_log_error 'err' "rep:this rep IO thread is running !!"
     return 0
  fi

  if [ ${Seconds_Behind_Master} == 'NULL' -o ${Seconds_Behind_Master} == '0' ] ; then #检测成功什么都不做
     echo 'normal'
  else
     logging_log 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     logging_log_error 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     return 0 #检测失败,延迟不为0
  fi



  logging_log 'info' "rep:check sucess.master ip:${Rep_Master_ip} master port:${Rep_Master_port} io status:${Slave_IO_Running} read_pos:${Master_Log_File} ${Read_Master_Log_Pos} exe_pos:${Relay_Master_Log_File} ${Exec_Master_Log_Pos}  Seconds_Behind_Master:${Seconds_Behind_Master}."
  return 1 #返回检测从库应用状态成功

}



#main 脚本开始


#第一步检查主库状态
#1、检测主库进程是否存在,调用check_pid
#2、检测主库是否可以跑简单的语句,调用check_sta
#如果检测成功说明不需要切换,直接返回 0给 keepdalived
#通常不会进入第二步判断
#第二步检测从库是否可以切换
#如果不能切换,同样返回 0给 keepalived
#如果可以切换,则返回 1给 keepalived

ret=0


echo '---' >> ${check_log}
#第一步检查主库状态

check_pid "mysqld"
if [ $? == '1' ] ;then  #1.mysqld检测成功 2.多个mysqld实例 都返回为1
   check_sta
   if [ $? == '0' ];then #检测sql命令失败
     ret=1 #失败
   else
     ret=0 #成功
   fi
else #检测没有mysqld存在
  ret=1 #失败
fi

#检测主库状态正常,不需要进行切换,返回1给keepalived

if [ $ret == '0' ];then
 echo "主库正常"
 exit 0
fi

#第二步检测从库是否可以切换
#检测主库状态不正常,需要检查从库状态是否满足切换条件

if [ $ret == '1' ];then
   check_rep_apply_all
   if [ $? == '1' ];then #检测从库状态成功
      echo "从库可以切换"
      exit 1
   else
      echo "从库不可以切换"  #检测失败不能切换
      exit 0
   fi
fi
# change_to_master.sh

#!/bin/bash

###############################################
#修改此处配置
#用户需要权限
#查看从库状态需要REPLICATION CLIENT权限
#修改参数需要super权限
export HOME='/root/'
NIC='ens32'
VIP='192.168.5.190'
GATEWAY='192.168.5.1'
ip='192.168.5.31'
port='3306'
mycom='mysql'
#记录日志位置
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'
#循环检测次数
check_loop=10

#循环检测间隔秒数
loop_time=5
#################################################

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive loggong ${dt_time} $1:$2" >> ${check_log}
}


logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}


check_rep_apply_all()
#input:NULL
#return value:0 失败,检测不能切换 1 成功,检测可以切换
{
  #先测试从库是否可以连接
  ${mycom}  -uroot -p123456 -h ${ip}  -e 'select now()'

  if [ $? -eq 0 ]; then
    logging_log 'info' 'master check:test select now() sucess.' #检测成功,测试语句能够执行,继续执行
  else
    logging_log 'err' 'master check:test select now() fail!!'
    logging_log_error 'err' 'master check:test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

  #不放到一条语句进行检测,多次检测可以提高检测的准确性
  Slave_IO_Running=`${mycom}  -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Slave_IO_Running | awk -F": " '{print $2}'`
  Master_Log_File=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Master_Log_File | awk -F": " '{print $2}'`
  Relay_Master_Log_File=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Relay_Master_Log_File | awk -F": " '{print $2}'`
  Read_Master_Log_Pos=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Read_Master_Log_Pos | awk -F": " '{print $2}'`
  Exec_Master_Log_Pos=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Exec_Master_Log_Pos | awk -F": " '{print $2}'`
  Seconds_Behind_Master=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Seconds_Behind_Master | awk -F": " '{print $2}'`


  if [ ${Master_Log_File} != ${Relay_Master_Log_File} ]; then
     logging_log 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     logging_log_error 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     return 0 #检测失败,从库读取的binlog文件和执行的binlog文件不一致
  fi

  if [ ${Read_Master_Log_Pos} != ${Exec_Master_Log_Pos} ]; then
     logging_log 'err' "master check:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     logging_log_error 'err' "master check:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     return 0 #检测失败,从库执行的binlog pos和执行的binlog pos不一致
  fi

  ##是否需要检测IO线程状态,只有在IO线程运行异常的情况下进行切换
  if [ ${Slave_IO_Running} == 'Yes' ]; then
     logging_log 'err' "master check:this rep IO thread is running !!"
     logging_log_error 'err' "master check:this rep IO thread is running !!"
     return 0
  fi

  if [ ${Seconds_Behind_Master} == 'NULL' -o ${Seconds_Behind_Master} == '0' ] ; then #检测成功什么都不做
     echo "1"
  else
     logging_log 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     logging_log_error 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     return 0 #检测失败,延迟不为0
  fi

  logging_log 'info' "master check:check sucess.io status:${Slave_IO_Running} read_pos:${Master_Log_File} ${Read_Master_Log_Pos} exe_pos:${Relay_Master_Log_File} ${Exec_Master_Log_Pos} Seconds_Behind_Master:${Seconds_Behind_Master}."
  return 1 #返回从库检测状态正常

}

with_out_readonly()
#input:NULL
#returnvalue:NULL
{
  logging_log 'warn' "set read_only=off"
  logging_log_error 'warn' "set read_only=off"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global read_only=0"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global super_read_only=0"
}


#main 脚本开始
#用于检测切换后是否可以打开read only选项
echo '---master-check---' >>${check_log}


i=1

while [ $i -le ${check_loop} ] ##循环次数
do
 check_rep_apply_all
 if [ $? -eq 1 ];then
    with_out_readonly #打开readonly选项
    break #跳出循环
 else
   echo "--check fail,loop $i times--" >>${check_log} #输出检测失败次数
   sleep ${loop_time} #睡眠时间
 fi
 let i+=1 #判断值+1
done

logging_log 'info' 'start to arping on change_to_master'
logging_log_error 'info' 'start to arping on change_to_master'
/sbin/arping -I $NIC -c 5 -s $VIP $GATEWAY
# change_to_backup.sh

#!/bin/bash
export HOME='/root/'
NIC='ens32'
VIP='192.168.5.190'
GATEWAY='192.168.5.1'
ip='192.168.5.31'
port='3306'
mycom='mysql'
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log}
}

logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}

with_readonly()
#input:NULL
#returnvalue:NULL
{
  logging_log 'warn' "set read_only=on"
  logging_log_error 'warn' "set read_only=on"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global read_only=1"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global super_read_only=1"
}


#main 脚本开始
#用于检测切换后是否可以打开read only选项
echo '---backup-set---' >>${check_log}

with_readonly #设置readonly

logging_log 'info' 'start to arping on change_to_backup'
logging_log_error 'info' 'start to arping on change_to_backup'
/sbin/arping -I $NIC -c 5 -s $VIP $GATEWAY

192.168.5.32

# keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id db02
}

vrrp_sync_group G1 {
 group {
  VI_1
}
}

vrrp_script check_run {
    script "/etc/keepalived/mysql_check.sh"
    interval 10
    fall 3
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens32
    virtual_router_id 51
    priority 90
    nopreempt
    advert_int 3
    authentication {
        auth_type PASS
        auth_pass admin#2023
    }
    track_interface {
          ens32
     }
    unicast_src_ip  192.168.5.32
    unicast_peer {
      192.168.5.31
    }
    track_script {
        check_run
    }
    virtual_ipaddress {
        192.168.5.190
    }
    notify_master "/etc/keepalived/change_to_master.sh"
    notify_backup "/etc/keepalived/change_to_backup.sh"
    notify_fault "/etc/keepalived/change_to_backup.sh"
}
# mysql_check.sh

#!/bin/bash

###############################################
#修改此处配置
#用户需要权限
#grant REPLICATION CLIENT  on *.* to mon_user@'%' ;
export HOME='/root'
master_ip='192.168.5.32'
master_port='3306'
master_mycom='mysql'
rep_ip='192.168.5.31'
rep_port='3306'
#记录日志位置
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'
find /etc/keepalived/  -name "keepalived_*.log" -mtime +7|xargs rm -rf
#################################################

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log}
}

logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}


check_pid()
#input:$1检查的进程关键字比如mysqld
#return:1 检测成功,但是需要注意有多个mysqld进程(物理服务器跑了多个实例)  0 检测失败,没有mysqld进程
{
  mysqld_cnt=`ps -ef|grep -w $1|grep -v 'grep'|wc -l`

  if test ${mysqld_cnt} -ge 2 ;then
     logging_log 'warn' 'more than one mysqld process!'
     return 1  #由于mysqld检测出有多个那么,只是告警而不做任何动作
  fi

  if test ${mysqld_cnt} -lt 1 ;then
     logging_log 'err' 'mysqld process is crash!!'
     logging_log_error 'err' 'mysqld process is crash!!'
     return 0 #检测mysqld已经不存在则直接进入从库检测流程
  fi

  logging_log 'info' 'one mysqld process check sucess.'
  return 1 #检测成功,进入语句检测
}


check_sta()
#input:NULL
#return:0 失败,主库测试语句不能执行 1 成功,主库测试语句可以执行
{
  #将stderr 写入到日志文件中,比如连接失败
  #${master_mycom} -h ${master_ip} -P ${master_port}  -u ${master_user} -p${master_password} -e 'select now()'
  ${master_mycom} -uroot -p123456 -h ${master_ip} -e 'select now()'
  if [ $? -eq 0 ]; then
    logging_log 'info' 'master:test select now() sucess.'
    return 1 #检测成功,测试语句能够执行
  else
    logging_log 'err' master:'test select now() fail!!'
    logging_log_error 'err' master:'test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

}


check_rep_apply_all()
#input:NULL
#return value:0 失败,检测不能切换 1 成功,检测可以切换
{
  #先测试从库是否可以连接
  ${master_mycom}  -uroot -p123456 -h ${rep_ip}  -e 'select now()'

  if [ $? -eq 0 ]; then
    logging_log 'info' 'rep:test select now() sucess.' #检测成功,测试语句能够执行,继续执行
  else
    logging_log 'err' 'rep:test select now() fail!!'
    logging_log_error 'err' 'rep:test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

  #不放到一条语句进行检测,多次检测可以提高检测的准确性
  Rep_Master_ip=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Master_Host | awk -F": " '{print $2}'`
  Rep_Master_port=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Master_Port | awk -F": " '{print $2}'`
  Slave_IO_Running=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Slave_IO_Running | awk -F": " '{print $2}'`
  Master_Log_File=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Master_Log_File | awk -F": " '{print $2}'`
  Relay_Master_Log_File=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Relay_Master_Log_File | awk -F": " '{print $2}'`
  Read_Master_Log_Pos=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Read_Master_Log_Pos | awk -F": " '{print $2}'`
  Exec_Master_Log_Pos=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e "show slave status\G" | grep -w Exec_Master_Log_Pos | awk -F": " '{print $2}'`
  Seconds_Behind_Master=`${master_mycom}  -uroot -p123456 -h ${rep_ip} -e  "show slave status\G" | grep -w Seconds_Behind_Master | awk -F": " '{print $2}'`

  if [ ${Rep_Master_ip} != ${master_ip} ]; then
     logging_log 'err' "rep:this rep ip ${Rep_Master_ip} is not master ip:${master_ip} !!"
     logging_log_error 'err' "rep:this rep ip ${Rep_Master_ip} is not master ip:${master_ip} !!"
     return 0 #检测失败,从库连接主库的ip和填写的主库ip不一致
  fi

  if [ ${Rep_Master_port} != ${master_port} ]; then
     logging_log 'err' "rep:this rep port ${Rep_Master_port} is not master port:${master_port} !!"
     logging_log_error 'err' "rep:this rep port ${Rep_Master_port} is not master port:${master_port} !!"
     return 0 #检测失败,从库连接主库的端口和填写的主库端口不一致
  fi

  if [ ${Master_Log_File} != ${Relay_Master_Log_File} ]; then
     logging_log 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     logging_log_error 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     return 0 #检测失败,从库读取的binlog文件和执行的binlog文件不一致
  fi

  if [ ${Read_Master_Log_Pos} != ${Exec_Master_Log_Pos} ]; then
     logging_log 'err' "rep:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     logging_log_error 'err' "rep:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     return 0 #检测失败,从库执行的binlog pos和执行的binlog pos不一致
  fi
  sleep 5
  ##是否需要检测IO线程状态,只有在IO线程运行异常的情况下进行切换
  if [ ${Slave_IO_Running} == 'Yes' ]; then
     logging_log 'err' "rep:this rep IO thread is running !!"
     logging_log_error 'err' "rep:this rep IO thread is running !!"
     return 0
  fi

  if [ ${Seconds_Behind_Master} == 'NULL' -o ${Seconds_Behind_Master} == '0' ] ; then #检测成功什么都不做
     echo 'normal'
  else
     logging_log 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     logging_log_error 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     return 0 #检测失败,延迟不为0
  fi



  logging_log 'info' "rep:check sucess.master ip:${Rep_Master_ip} master port:${Rep_Master_port} io status:${Slave_IO_Running} read_pos:${Master_Log_File} ${Read_Master_Log_Pos} exe_pos:${Relay_Master_Log_File} ${Exec_Master_Log_Pos}  Seconds_Behind_Master:${Seconds_Behind_Master}."
  return 1 #返回检测从库应用状态成功

}



#main 脚本开始


#第一步检查主库状态
#1、检测主库进程是否存在,调用check_pid
#2、检测主库是否可以跑简单的语句,调用check_sta
#如果检测成功说明不需要切换,直接返回 0给 keepdalived
#通常不会进入第二步判断
#第二步检测从库是否可以切换
#如果不能切换,同样返回 0给 keepalived
#如果可以切换,则返回 1给 keepalived

ret=0


echo '---' >> ${check_log}
#第一步检查主库状态

check_pid "mysqld"
if [ $? == '1' ] ;then  #1.mysqld检测成功 2.多个mysqld实例 都返回为1
   check_sta
   if [ $? == '0' ];then #检测sql命令失败
     ret=1 #失败
   else
     ret=0 #成功
   fi
else #检测没有mysqld存在
  ret=1 #失败
fi

#检测主库状态正常,不需要进行切换,返回1给keepalived

if [ $ret == '0' ];then
 echo "主库正常"
 exit 0
fi

#第二步检测从库是否可以切换
#检测主库状态不正常,需要检查从库状态是否满足切换条件

if [ $ret == '1' ];then
   check_rep_apply_all
   if [ $? == '1' ];then #检测从库状态成功
      echo "从库可以切换"
      exit 1
   else
      echo "从库不可以切换"  #检测失败不能切换
      exit 0
   fi
fi
# change_to_master.sh

#!/bin/bash

###############################################
#修改此处配置
#用户需要权限
#查看从库状态需要REPLICATION CLIENT权限
#修改参数需要super权限
export HOME='/root/'
NIC='ens32'
VIP='192.168.5.190'
GATEWAY='192.168.5.1'
ip='192.168.5.32'
port='3306'
mycom='mysql'
#记录日志位置
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'
#循环检测次数
check_loop=10

#循环检测间隔秒数
loop_time=5
#################################################

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive loggong ${dt_time} $1:$2" >> ${check_log}
}


logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}


check_rep_apply_all()
#input:NULL
#return value:0 失败,检测不能切换 1 成功,检测可以切换
{
  #先测试从库是否可以连接
  ${mycom}  -uroot -p123456 -h ${ip}  -e 'select now()'

  if [ $? -eq 0 ]; then
    logging_log 'info' 'master check:test select now() sucess.' #检测成功,测试语句能够执行,继续执行
  else
    logging_log 'err' 'master check:test select now() fail!!'
    logging_log_error 'err' 'master check:test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

  #不放到一条语句进行检测,多次检测可以提高检测的准确性
  Slave_IO_Running=`${mycom}  -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Slave_IO_Running | awk -F": " '{print $2}'`
  Master_Log_File=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Master_Log_File | awk -F": " '{print $2}'`
  Relay_Master_Log_File=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Relay_Master_Log_File | awk -F": " '{print $2}'`
  Read_Master_Log_Pos=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Read_Master_Log_Pos | awk -F": " '{print $2}'`
  Exec_Master_Log_Pos=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Exec_Master_Log_Pos | awk -F": " '{print $2}'`
  Seconds_Behind_Master=`${mycom} -uroot -p123456 -h ${ip} -e "show slave status\G" | grep -w Seconds_Behind_Master | awk -F": " '{print $2}'`


  if [ ${Master_Log_File} != ${Relay_Master_Log_File} ]; then
     logging_log 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     logging_log_error 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     return 0 #检测失败,从库读取的binlog文件和执行的binlog文件不一致
  fi

  if [ ${Read_Master_Log_Pos} != ${Exec_Master_Log_Pos} ]; then
     logging_log 'err' "master check:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     logging_log_error 'err' "master check:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     return 0 #检测失败,从库执行的binlog pos和执行的binlog pos不一致
  fi

  ##是否需要检测IO线程状态,只有在IO线程运行异常的情况下进行切换
  if [ ${Slave_IO_Running} == 'Yes' ]; then
     logging_log 'err' "master check:this rep IO thread is running !!"
     logging_log_error 'err' "master check:this rep IO thread is running !!"
     return 0
  fi

  if [ ${Seconds_Behind_Master} == 'NULL' -o ${Seconds_Behind_Master} == '0' ] ; then #检测成功什么都不做
     echo "1"
  else
     logging_log 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     logging_log_error 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     return 0 #检测失败,延迟不为0
  fi

  logging_log 'info' "master check:check sucess.io status:${Slave_IO_Running} read_pos:${Master_Log_File} ${Read_Master_Log_Pos} exe_pos:${Relay_Master_Log_File} ${Exec_Master_Log_Pos} Seconds_Behind_Master:${Seconds_Behind_Master}."
  return 1 #返回从库检测状态正常

}

with_out_readonly()
#input:NULL
#returnvalue:NULL
{
  logging_log 'warn' "set read_only=off"
  logging_log_error 'warn' "set read_only=off"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global read_only=0"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global super_read_only=0"
}


#main 脚本开始
#用于检测切换后是否可以打开read only选项
echo '---master-check---' >>${check_log}


i=1

while [ $i -le ${check_loop} ] ##循环次数
do
 check_rep_apply_all
 if [ $? -eq 1 ];then
    with_out_readonly #打开readonly选项
    break #跳出循环
 else
   echo "--check fail,loop $i times--" >>${check_log} #输出检测失败次数
   sleep ${loop_time} #睡眠时间
 fi
 let i+=1 #判断值+1
done

logging_log 'info' 'start to arping on change_to_master'
logging_log_error 'info' 'start to arping on change_to_master'
/sbin/arping -I $NIC -c 5 -s $VIP $GATEWAY
# change_to_backup.sh

#!/bin/bash
export HOME='/root/'
NIC='ens32'
VIP='192.168.5.190'
GATEWAY='192.168.5.1'
ip='192.168.5.32'
port='3306'
mycom='mysql'
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log}
}

logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}

with_readonly()
#input:NULL
#returnvalue:NULL
{
  logging_log 'warn' "set read_only=on"
  logging_log_error 'warn' "set read_only=on"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global read_only=1"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global super_read_only=1"
}


#main 脚本开始
#用于检测切换后是否可以打开read only选项
echo '---backup-set---' >>${check_log}

with_readonly #设置readonly

logging_log 'info' 'start to arping on change_to_backup'
logging_log_error 'info' 'start to arping on change_to_backup'
/sbin/arping -I $NIC -c 5 -s $VIP $GATEWAY
#!/bin/bash
export HOME='/root/'
NIC='ens32'
VIP='192.168.5.190'
GATEWAY='192.168.5.1'
ip='192.168.5.32'
port='3306'
mycom='mysql'
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log}
}

logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}

with_readonly()
#input:NULL
#returnvalue:NULL
{
  logging_log 'warn' "set read_only=on"
  logging_log_error 'warn' "set read_only=on"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global read_only=1"
  ${mycom} -uroot -p123456 -h ${ip} -e "set global super_read_only=1"
}


#main 脚本开始
#用于检测切换后是否可以打开read only选项
echo '---backup-set---' >>${check_log}

with_readonly #设置readonly

logging_log 'info' 'start to arping on change_to_backup'
logging_log_error 'info' 'start to arping on change_to_backup'
/sbin/arping -I $NIC -c 5 -s $VIP $GATEWAY

具体配置-login-path方式

# mysql_check.sh

#!/bin/bash

###############################################
#修改此处配置
#用户需要权限
#grant REPLICATION CLIENT  on *.* to mon_user@'%' ;
export HOME='/root'
master_ip='170.100.132.3'
master_port='3306'
master_mycom='/mysql/app/bin/mysql'
rep_ip='170.100.132.4'
rep_port='3306'
#记录日志位置
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'
find /etc/keepalived/  -name "keepalived_*.log" -mtime +7|xargs rm -rf
#################################################

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log}
}

logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}


check_pid()
#input:$1检查的进程关键字比如mysqld
#return:1 检测成功,但是需要注意有多个mysqld进程(物理服务器跑了多个实例)  0 检测失败,没有mysqld进程
{
  mysqld_cnt=`ps -ef|grep -w $1|grep -v 'grep'|wc -l`

  if test ${mysqld_cnt} -ge 2 ;then
     logging_log 'warn' 'more than one mysqld process!'
     return 1  #由于mysqld检测出有多个那么,只是告警而不做任何动作
  fi

  if test ${mysqld_cnt} -lt 1 ;then
     logging_log 'err' 'mysqld process is crash!!'
     logging_log_error 'err' 'mysqld process is crash!!'
     return 0 #检测mysqld已经不存在则直接进入从库检测流程
  fi

  logging_log 'info' 'one mysqld process check sucess.'
  return 1 #检测成功,进入语句检测
}


check_sta()
#input:NULL
#return:0 失败,主库测试语句不能执行 1 成功,主库测试语句可以执行
{
  #将stderr 写入到日志文件中,比如连接失败
  #${master_mycom} -h ${master_ip} -P ${master_port}  -u ${master_user} -p${master_password} -e 'select now()'
  ${master_mycom} --login-path=local_login -e 'select now()'
  if [ $? -eq 0 ]; then
    logging_log 'info' 'master:test select now() sucess.'
    return 1 #检测成功,测试语句能够执行
  else
    logging_log 'err' master:'test select now() fail!!'
    logging_log_error 'err' master:'test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

}


check_rep_apply_all()
#input:NULL
#return value:0 失败,检测不能切换 1 成功,检测可以切换
{
  #先测试从库是否可以连接
  ${master_mycom}  --login-path=sync_login  -e 'select now()'

  if [ $? -eq 0 ]; then
    logging_log 'info' 'rep:test select now() sucess.' #检测成功,测试语句能够执行,继续执行
  else
    logging_log 'err' 'rep:test select now() fail!!'
    logging_log_error 'err' 'rep:test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

  #不放到一条语句进行检测,多次检测可以提高检测的准确性
  Rep_Master_ip=`${master_mycom}  --login-path=sync_login -e "show slave status\G" | grep -w Master_Host | awk -F": " '{print $2}'`
  Rep_Master_port=`${master_mycom}  --login-path=sync_login -e "show slave status\G" | grep -w Master_Port | awk -F": " '{print $2}'`
  Slave_IO_Running=`${master_mycom}  --login-path=sync_login -e "show slave status\G" | grep -w Slave_IO_Running | awk -F": " '{print $2}'`
  Master_Log_File=`${master_mycom}  --login-path=sync_login -e "show slave status\G" | grep -w Master_Log_File | awk -F": " '{print $2}'`
  Relay_Master_Log_File=`${master_mycom}  --login-path=sync_login -e "show slave status\G" | grep -w Relay_Master_Log_File | awk -F": " '{print $2}'`
  Read_Master_Log_Pos=`${master_mycom}  --login-path=sync_login -e "show slave status\G" | grep -w Read_Master_Log_Pos | awk -F": " '{print $2}'`
  Exec_Master_Log_Pos=`${master_mycom}  --login-path=sync_login -e "show slave status\G" | grep -w Exec_Master_Log_Pos | awk -F": " '{print $2}'`
  Seconds_Behind_Master=`${master_mycom}  --login-path=sync_login -e  "show slave status\G" | grep -w Seconds_Behind_Master | awk -F": " '{print $2}'`

  if [ ${Rep_Master_ip} != ${master_ip} ]; then
     logging_log 'err' "rep:this rep ip ${Rep_Master_ip} is not master ip:${master_ip} !!"
     logging_log_error 'err' "rep:this rep ip ${Rep_Master_ip} is not master ip:${master_ip} !!"
     return 0 #检测失败,从库连接主库的ip和填写的主库ip不一致
  fi

  if [ ${Rep_Master_port} != ${master_port} ]; then
     logging_log 'err' "rep:this rep port ${Rep_Master_port} is not master port:${master_port} !!"
     logging_log_error 'err' "rep:this rep port ${Rep_Master_port} is not master port:${master_port} !!"
     return 0 #检测失败,从库连接主库的端口和填写的主库端口不一致
  fi

  if [ ${Master_Log_File} != ${Relay_Master_Log_File} ]; then
     logging_log 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     logging_log_error 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     return 0 #检测失败,从库读取的binlog文件和执行的binlog文件不一致
  fi

  if [ ${Read_Master_Log_Pos} != ${Exec_Master_Log_Pos} ]; then
     logging_log 'err' "rep:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     logging_log_error 'err' "rep:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     return 0 #检测失败,从库执行的binlog pos和执行的binlog pos不一致
  fi
  sleep 5
  ##是否需要检测IO线程状态,只有在IO线程运行异常的情况下进行切换
  if [ ${Slave_IO_Running} == 'Yes' ]; then
     logging_log 'err' "rep:this rep IO thread is running !!"
     logging_log_error 'err' "rep:this rep IO thread is running !!"
     return 0
  fi

  if [ ${Seconds_Behind_Master} == 'NULL' -o ${Seconds_Behind_Master} == '0' ] ; then #检测成功什么都不做
     echo 'normal'
  else
     logging_log 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     logging_log_error 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     return 0 #检测失败,延迟不为0
  fi



  logging_log 'info' "rep:check sucess.master ip:${Rep_Master_ip} master port:${Rep_Master_port} io status:${Slave_IO_Running} read_pos:${Master_Log_File} ${Read_Master_Log_Pos} exe_pos:${Relay_Master_Log_File} ${Exec_Master_Log_Pos}  Seconds_Behind_Master:${Seconds_Behind_Master}."
  return 1 #返回检测从库应用状态成功

}



#main 脚本开始


#第一步检查主库状态
#1、检测主库进程是否存在,调用check_pid
#2、检测主库是否可以跑简单的语句,调用check_sta
#如果检测成功说明不需要切换,直接返回 0给 keepdalived
#通常不会进入第二步判断
#第二步检测从库是否可以切换
#如果不能切换,同样返回 0给 keepalived
#如果可以切换,则返回 1给 keepalived

ret=0


echo '---' >> ${check_log}
#第一步检查主库状态

check_pid "mysqld"
if [ $? == '1' ] ;then  #1.mysqld检测成功 2.多个mysqld实例 都返回为1
   check_sta
   if [ $? == '0' ];then #检测sql命令失败
     ret=1 #失败
   else
     ret=0 #成功
   fi
else #检测没有mysqld存在
  ret=1 #失败
fi

#检测主库状态正常,不需要进行切换,返回1给keepalived

if [ $ret == '0' ];then
 echo "主库正常"
 exit 0
fi

#第二步检测从库是否可以切换
#检测主库状态不正常,需要检查从库状态是否满足切换条件

if [ $ret == '1' ];then
   check_rep_apply_all
   if [ $? == '1' ];then #检测从库状态成功
      echo "从库可以切换"
      exit 1
   else
      echo "从库不可以切换"  #检测失败不能切换
      exit 0
   fi
fi
# change_to_master.sh

#!/bin/bash

###############################################
#修改此处配置
#用户需要权限
#查看从库状态需要REPLICATION CLIENT权限
#修改参数需要super权限
export HOME='/root/'
NIC='ens192'
VIP='170.100.132.5'
GATEWAY='170.100.132.254'
ip='170.100.132.3'
port='3306'
mycom='/mysql/app/bin/mysql'
#记录日志位置
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'
#循环检测次数
check_loop=10

#循环检测间隔秒数
loop_time=5
#################################################

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive loggong ${dt_time} $1:$2" >> ${check_log}
}


logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}


check_rep_apply_all()
#input:NULL
#return value:0 失败,检测不能切换 1 成功,检测可以切换
{
  #先测试从库是否可以连接
  ${mycom}  --login-path=local_login  -e 'select now()'

  if [ $? -eq 0 ]; then
    logging_log 'info' 'master check:test select now() sucess.' #检测成功,测试语句能够执行,继续执行
  else
    logging_log 'err' 'master check:test select now() fail!!'
    logging_log_error 'err' 'master check:test select now() fail!!'
    return 0 #检测失败,测试语句不能够执行
  fi

  #不放到一条语句进行检测,多次检测可以提高检测的准确性
  Slave_IO_Running=`${mycom}  --login-path=local_login -e "show slave status\G" | grep -w Slave_IO_Running | awk -F": " '{print $2}'`
  Master_Log_File=`${mycom} --login-path=local_login -e "show slave status\G" | grep -w Master_Log_File | awk -F": " '{print $2}'`
  Relay_Master_Log_File=`${mycom} --login-path=local_login -e "show slave status\G" | grep -w Relay_Master_Log_File | awk -F": " '{print $2}'`
  Read_Master_Log_Pos=`${mycom} --login-path=local_login -e "show slave status\G" | grep -w Read_Master_Log_Pos | awk -F": " '{print $2}'`
  Exec_Master_Log_Pos=`${mycom} --login-path=local_login -e "show slave status\G" | grep -w Exec_Master_Log_Pos | awk -F": " '{print $2}'`
  Seconds_Behind_Master=`${mycom} --login-path=local_login -e "show slave status\G" | grep -w Seconds_Behind_Master | awk -F": " '{print $2}'`


  if [ ${Master_Log_File} != ${Relay_Master_Log_File} ]; then
     logging_log 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     logging_log_error 'err' "rep:this rep read binlog:${Master_Log_File} is not eq execute binlog:${Relay_Master_Log_File} !!"
     return 0 #检测失败,从库读取的binlog文件和执行的binlog文件不一致
  fi

  if [ ${Read_Master_Log_Pos} != ${Exec_Master_Log_Pos} ]; then
     logging_log 'err' "master check:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     logging_log_error 'err' "master check:this rep read pos:${Read_Master_Log_Pos} is not eq execute pos:${Exec_Master_Log_Pos} !!"
     return 0 #检测失败,从库执行的binlog pos和执行的binlog pos不一致
  fi

  ##是否需要检测IO线程状态,只有在IO线程运行异常的情况下进行切换
  if [ ${Slave_IO_Running} == 'Yes' ]; then
     logging_log 'err' "master check:this rep IO thread is running !!"
     logging_log_error 'err' "master check:this rep IO thread is running !!"
     return 0
  fi

  if [ ${Seconds_Behind_Master} == 'NULL' -o ${Seconds_Behind_Master} == '0' ] ; then #检测成功什么都不做
     echo "1"
  else
     logging_log 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     logging_log_error 'err' "rep:this rep Behind Master:${Seconds_Behind_Master}s blocking switch !!"
     return 0 #检测失败,延迟不为0
  fi

  logging_log 'info' "master check:check sucess.io status:${Slave_IO_Running} read_pos:${Master_Log_File} ${Read_Master_Log_Pos} exe_pos:${Relay_Master_Log_File} ${Exec_Master_Log_Pos} Seconds_Behind_Master:${Seconds_Behind_Master}."
  return 1 #返回从库检测状态正常

}

with_out_readonly()
#input:NULL
#returnvalue:NULL
{
  logging_log 'warn' "set read_only=off"
  logging_log_error 'warn' "set read_only=off"
  ${mycom} --login-path=super_login -e "set global read_only=0"
  ${mycom} --login-path=super_login -e "set global super_read_only=0"
}


#main 脚本开始
#用于检测切换后是否可以打开read only选项
echo '---master-check---' >>${check_log}


i=1

while [ $i -le ${check_loop} ] ##循环次数
do
 check_rep_apply_all
 if [ $? -eq 1 ];then
    with_out_readonly #打开readonly选项
    break #跳出循环
 else
   echo "--check fail,loop $i times--" >>${check_log} #输出检测失败次数
   sleep ${loop_time} #睡眠时间
 fi
 let i+=1 #判断值+1
done

logging_log 'info' 'start to arping on change_to_master'
logging_log_error 'info' 'start to arping on change_to_master'
/sbin/arping -I $NIC -c 5 -s $VIP $GATEWAY
# change_to_backup.sh

#!/bin/bash
export HOME='/root/'
NIC='ens192'
VIP='170.100.132.5'
GATEWAY='170.100.132.254'
port='3306'
mycom='/mysql/app/bin/mysql'
log_time=`date  '+%Y%m%d'`
check_log='/etc/keepalived/keepalived_'${log_time}'.log'
check_log_error='/var/log/messages'

logging_log()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log}
}

logging_log_error()
#input:$1 输入警告级别 $2 输入警告日志字符串
{
 dt_time=`date  '+%Y-%m-%d-%H:%M:%S'`
 echo "keepalive logging ${dt_time} $1:$2" >> ${check_log_error}
}

with_readonly()
#input:NULL
#returnvalue:NULL
{
  logging_log 'warn' "set read_only=on"
  logging_log_error 'warn' "set read_only=on"
  ${mycom}  --login-path=super_login -e "set global read_only=1"
  ${mycom} --login-path=super_login -e "set global super_read_only=1"
}


#main 脚本开始
#用于检测切换后是否可以打开read only选项
echo '---backup-set---' >>${check_log}

with_readonly #设置readonly

logging_log 'info' 'start to arping on change_to_backup'
logging_log_error 'info' 'start to arping on change_to_backup'
/sbin/arping -I $NIC -c 5 -s $VIP $GATEWAY

注意:如果两台mysql数据库先于keepalived启动,当keepalived启动后,第一次需要手动去除VIP所在节点数据库的只读属性。

-------他日江湖相逢 再当杯酒言欢-------
分享

飞鸟
作者: starifly ❉
天无边,智无限。


目录

点击屏幕右上角的 ···
在弹出的窗口中选择 在浏览器中打开