#!/bin/bash #set -x # 设置变量 MASTER_HOST="10.10.29.8" # 主服务器IP地址 SLAVE_HOST="10.10.29.9" # 从服务器IP地址 MYSQL_USER="root" # MySQL用户名 MYSQL_PASSWORD="Unary@2023" # MySQL密码 MYSQL_PORT=3306 # MySQL端口 #同步账户和密码 MYSQL_REPL_USER="repl" MYSQL_REPL_PASSWD="Unary@2023" # 获取当前主从关系 pre_check() { MASTER_STATUS=$(mysql -h$MASTER_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "show slave status\\G;"|grep -E "Slave_IO_Running: Yes|Slave_SQL_Running: Yes|Seconds_Behind_Master: 0"|wc -l) SLAVE_STATUS=$(mysql -h$SLAVE_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "show slave status\\G;"|grep -E "Slave_IO_Running: Yes|Slave_SQL_Running: Yes|Seconds_Behind_Master: 0"|wc -l) if [ "$MASTER_STATUS" -eq 0 ] && [ "$SLAVE_STATUS" -eq 3 ]; then echo "$MASTER_HOST 是主节点,即将切换为 $SLAVE_HOST" elif [ "$MASTER_STATUS" -eq 3 ] && [ "$SLAVE_STATUS" -eq 0 ]; then echo "$SLAVE_HOST 是主节点,即将切换为 $MASTER_HOST" # 交换主从 new_master=$MASTER_HOST MASTER_HOST=$SLAVE_HOST SLAVE_HOST=$new_master else echo "当前不是主从集群,请确认后主从状态是否正常" exit 1 fi } set_master_redonly(){ # 设置为只读 mysql -h$MASTER_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "set global super_read_only='on';set global read_only='on';" # 获取设置后的状态 on_number=$(mysql -h$MASTER_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "show VARIABLES like '%read_only%' "|grep ON |wc -l) # 检查等于 "ON"的个数,判断是否修改成功了 if [ "$on_number" != "2" ]; then echo "主节点设置只读异常,请人工确认!!" exit 1 fi } set_slaver_status(){ # 停止从节点,并重置从节点的同步信息 mysql -h$SLAVE_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "stop slave;reset slave all;" # 设置关闭只读 mysql -h$SLAVE_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "set global super_read_only='off';set global read_only='off';" # 获取设置后的状态 off_number=$(mysql -h$SLAVE_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "show VARIABLES like '%read_only%' "|grep OFF |wc -l) # 检查等于 "ON"的个数,判断是否修改成功了 if [ "$off_number" != "4" ]; then echo "从节点设置关闭只读异常,请人工确认!!" exit 1 fi } # 获取主服务器的binlog文件和位置 get_old_slaver_status() { MASTER_LOG_FILE=$(mysql -h$SLAVE_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "SHOW MASTER STATUS\\G" | grep File | awk '{print $2}') MASTER_LOG_POS=$(mysql -h$SLAVE_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "SHOW MASTER STATUS\\G" | grep Position | awk '{print $2}') } # 在从服务器上执行SQL命令,设置新的主服务器 configure_slave() { echo "Configuring slave on $host to use new master..." upsql="CHANGE MASTER to MASTER_HOST='${SLAVE_HOST}',MASTER_USER='${MYSQL_REPL_USER}',MASTER_PASSWORD='${MYSQL_REPL_PASSWD}',MASTER_LOG_FILE='${MASTER_LOG_FILE}',MASTER_LOG_POS=${MASTER_LOG_POS}" # 执行 mysql -h$MASTER_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "${upsql};start slave;" } # 检查复制状态 check_replication_status() { echo "Checking replication status on $host..." #校验原来的主节点,现在应该是从节点 REPLICATION_STATUS=$(mysql -h$MASTER_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -e "show slave status\\G;"|grep -E "Slave_IO_Running: Yes|Slave_SQL_Running: Yes|Seconds_Behind_Master: 0"|wc -l) # 判断是否修改成功了 if [ "$REPLICATION_STATUS" != "3" ]; then echo "主从切换异常,请人工确认!!" exit 1 fi echo "主从切换成功!当前 $SLAVE_HOST 是主节点" } # 主函数 main() { # 预检测 pre_check # 将主节点设置为只读 echo $MASTER_HOST set_master_redonly # 停止从节点,并关闭只读 set_slaver_status # 获取原从节点的最新日志以及偏移量 get_old_slaver_status # 修改原主节点为从节点 configure_slave # 检查切换后的状态 check_replication_status } main