基于一主两从环境部署

环境准备:

主机名 外网IP 内网IP 角色
web01 10.0.0.7 172.16.1.7 master主库
web02 10.0.0.8 172.16.1.8 slave从库一
web03 10.0.0.9 172.16.1.9 slave从库二

由于Mysql安装包过大,码云无法上传,建议手动下载,替换安装包路径即可!!!
Mysql:TP
下载地址:TP

#!/bin/bash
. /etc/init.d/functions
. ./vare.txt
#------------------------------------函数定义----------------------------------------------
#定义mysql安装函数
MySQL_install(){
# '解压'
tar xf /opt/mysql-5.7.42-linux-glibc2.12-x86_64.tar.gz -C /opt/
# '创建安装目录并将解压好的压缩包移动至该目录'
mkdir /app && mv /opt/mysql-5.7.42-linux-glibc2.12-x86_64 /app/mysql-5.7.42
sleep 1
ln -s /app/mysql-5.7.42 /app/mysql
#创建数据目录
mkdir /app/mysql/data
# '创建mysql用户并授权'
groupadd mysql && useradd -r -g mysql mysql
chown -R mysql:mysql /app/mysql/ && chmod 755 /app/mysql/
sleep 1
#'安装依赖'
yum install -y libaio-devel >/dev/null 2>&1
sleep 1
# '拷贝启动脚本'
cd /app/mysql/support-files && cp mysql.server /etc/init.d/mysqld
sleep 1
# '初始化'
cd /app/mysql/bin/
output=$(./mysqld --initialize-insecure --user=mysql --datadir=/app/mysql/data --basedir=/app/mysql 2>&1 >/dev/null)
# '修改配置文件'
echo '
[mysqld]
basedir=/app/mysql
datadir=/app/mysql/data' > /etc/my.cnf
cat >> /usr/lib/systemd/system/mysql.service << EOF
[Unit]
Description=mysqld

[Service]
#Type=notify
ExecStart=/app/mysql/bin/mysqld --defaults-file=/etc/my.cnf --user=mysql
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target
EOF
#重新加载文件
systemctl daemon-reload
sleep 1
echo 'PATH="/app/mysql/bin:$PATH"' > /etc/profile.d/mysql.sh
sleep 1
source /etc/profile
systemctl start mysqld
sleep 1
echo "服务端口已启动"
netstat -tupln | grep '3306'
sleep 1
}
#本地密钥生成
push_public_key(){
yum install -y sshpass &>/dev/null
  for ip in $master_ip "${slave_ip[@]}";do
    ping -W1 -c1 $ip &>/dev/null
    if [ $? -eq 0 ];then
      sshpass -p $host_pwd ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_dsa.pub $ip &>/dev/null
    action "主机:$ip" /bin/true
        else
    action "主机:$ip" /bin/false
  fi
  done
}
#ip判断
check_ipaddress(){
if [[ $1 =~ $check_ip ]];then
  echo "$1 ok" &>/dev/null
else
  echo "Usage:请输入正确的IP地址。"
  exit 2
fi
}
# 远程执行函数
# 修改 remote_execute 函数
remote_execute() {
    local ip="$1"
    local action="$2"
    ssh "$ip" "$(typeset -f MySQL_install); $action"
}

# 定义函数操作的数组
function_list=("MySQL_install")
#---------------------------------------代码-------------------------------------------
echo -e "\033[33m----------建议使用.(点)执行脚本方式!!!!!----------\033[0m\n"
##集群服务器互生密钥
echo -e "\033[33m-------------------集群服务器密钥生成----------------\033[0m\n"
if [ ! -f ~/.ssh/id_dsa.pub ];then
  ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1
    push_public_key
    for host_ip in $master_ip "${slave_ip[@]}";do
            scp  -r ~/.ssh/ $host_ip:/root/ &>/dev/null
            ssh -q $host_ip  "scp -r ~/.ssh/  ssh $host_ip:/root/  &>/dev/null "
    done
else
    push_public_key
    for host_ip in $master_ip "${slave_ip[@]}";do
    scp  -r ~/.ssh/ $host_ip:/root/ &>/dev/null
    ssh -q $host_ip  "scp -r ~/.ssh/  ssh $host_ip:/root/  &>/dev/null "
done
fi
#检测是否安装MySQL
echo -e "\033[33m-------------------检测是否安装MySQL-----------------\033[0m\n"
for i in $master_ip "${slave_ip[@]}"; do
    for action in "${function_list[@]}"; do
        # Check if MySQL is installed on the remote node
        if ssh "$i" "[ -z \"\$(find / -type f -name mysql  2>/dev/null)\" ]"; then
            # 仅当节点未安装 MySQL 时执行安装函数
            echo "节点 $i 未安装 MySQL,执行安装函数"
            scp ./file/mysql-5.7.42-linux-glibc2.12-x86_64.tar.gz "$i":/opt/ &>/dev/null
            # Assuming remote_execute is a function that performs actions on the remote node
            remote_execute "$i" "$action"
        rm -rf /opt/mysql-5.7.42-linux-glibc2.12-x86_64.tar.gza &>/dev/null
        else
            echo "节点 $i 已安装 MySQL,跳过安装"
        fi
    done
done

#判断集群数量
echo -e "\033[33m----------------------判断集群数量----------------------\033[0m\n"
expr 1 + $num &>/dev/null
if [ $? -ne 0 ];then
  echo "Usage:集群个数必须是一个整形"
  exit 1
fi
echo -e "\033[33m-------------------------IP判断------------------------\033[0m\n"
# master的IP地址
check_ipaddress $master_ip
#slave的IP地址(多台使用空格开)
# 验证从库IP数组
for ip in "${slave_ip[@]}"; do
  check_ipaddress "$ip"
done

#my.cnf配置文件推送
echo -e "\033[33m-----------------------my.cnf配置文件推送----------------\033[0m\n"
# 在循环中读取和递增
i=1
for host in $master_ip ${slave_ip[@]}; do
ssh root@$host "cat > /etc/my.cnf <<EOF
[mysqld]
basedir=$base_dir
datadir=$binlog_dir
server_id=$((i++))
log-bin=mysql-bin
relay_log_purge=0
EOF"
done

#重启数据库
echo -e "\033[33m----------------------------重启数据库--------------------\033[0m\n"
for service in  $master_ip ${slave_ip[@]};do
        ssh -q $service "systemctl stop mysqld && systemctl start mysqld "
done
#master主库创建主从用户
echo -e "\033[33m----------------------------创建主从用户-------------------\033[0m\n"
echo "GRANT REPLICATION SLAVE ON *.* TO '$repl_user'@'$ssh_ip' IDENTIFIED BY '$repl_password';" | ssh $master_ip mysql
#截取binlog日志文件和起始点
node_file=$(ssh "$master_ip" "mysql -N -e 'show master status;' | awk '{print \$1}'")
node_pos=$(ssh "$master_ip" "mysql -N -e 'show master status;' | awk '{print \$2}'")

#从库change 语句
for n in "${slave_ip[@]}"; do
ssh ${n} "mysql -e 'CHANGE MASTER TO MASTER_HOST=\"$master_ip\", MASTER_USER=\"${repl_user}\", MASTER_PASSWORD=\"${repl_password}\", MASTER_LOG_FILE=\"${node_file}\", MASTER_LOG_POS=${node_pos},MASTER_PORT=$port;'"
done
#启动从库
echo -e "\033[33m-----------------------------启动从库----------------------\033[0m\n"
for slave in ${slave_ip[@]};do
        ssh -q $slave << EOF
        mysql -e 'stop slave;'
        mysql -e 'start slave;'
        mysql -e 'set global read_only=1;'
EOF
done

#再次创建主从用户
echo -e "\033[33m--------------再次创建主从用户,用于同步到从库上----------------\033[0m\n"
echo "GRANT REPLICATION SLAVE ON *.* TO '$repl_user'@'$ssh_ip' IDENTIFIED BY '$repl_password';" | ssh $master_ip mysql &>/dev/null
echo "grant all on *.* to $mha_manager_user@'$ssh_ip' identified by '$mha_manager_password';" | ssh $master_ip mysql  &>/dev/null

#MHA——node安装
echo -e "\033[33m--------------------------MHA-node安装----------------------\033[0m\n"
for install in $master_ip ${slave_ip[@]};do
 scp ./file/mha4mysql-node-0.56-0.el6.noarch.rpm $install:/opt &>/dev/null
 ssh $install "yum localinstall -y /opt/mha4mysql-node-0.56-0.el6.noarch.rpm &>/dev/null"
done
#MHA-manager安装
echo -e "\033[33m------------------------MHA-manager安装---------------------\033[0m\n"
scp ./file/mha4mysql-manager-0.56-0.el6.noarch.rpm "$manager_ip":/opt  &>/dev/null
ssh $manager_ip "yum localinstall -y /opt/mha4mysql-manager-0.56-0.el6.noarch.rpm &>/dev/null"

# manager配置
echo -e "\033[33m-----------------------配置manager-------------------------\033[0m\n"
check_ipaddress $manager_ip
if [ ! $manager_ip == $master_ip ]; then
        ssh $manager_ip "mkdir -p $mha_log_dir"
     scp ./master_ip_failover.sh $manager_ip:$mha_worker_dir &>/dev/null
        ssh $manager_ip " cat > /etc/mha/app1.cnf << EOF
[server default]
manager_log=${mha_log_dir}/manager.log
manager_workdir=${mha_worker_dir}/app1
master_ip_failover_script=${mha_worker_dir}/master_ip_failover.sh
master_binlog_dir=$binlog_dir
user=$mha_manager_user
password=$mha_manager_password
ping_interval=2
repl_password=$repl_password
repl_user=$repl_user
ssh_user=root
ssh_port=22

[server1]
hostname=$master_ip
port=3306
EOF"
for n in $(seq 2 $num); do
        ssh $manager_ip "cat >> /etc/mha/app1.cnf <<EOF
[server$n]
hostname=${slave_ip[(($n-2))]}
port=$port
EOF"
done

else 
    echo -e "\e[1;31m Warning: 尽量不要把MHA装在主库上\e[0m"
    exit 2
fi
echo -e "\033[33m----------------------启动环境检测--------------------------\033[0m\n"
ssh $manager_ip '
/usr/bin/masterha_check_ssh --conf=/etc/mha/app1.cnf > check-ssh.txt 2>&1
/usr/bin/masterha_check_repl --conf=/etc/mha/app1.cnf > check-repl.txt 2>&1
cat >> /usr/lib/systemd/system/mysql-mha.service  << EOF
[Unit]
Description=MHA Manager Service
After=network.target

[Service]
ExecStart=/usr/bin/masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/logs/manager.log 2>&1

[Install]
WantedBy=default.target
EOF
systemctl daemon-reload
'

check_ssh=`ssh $manager_ip cat /root/check-ssh.txt | grep -o 'successfully'`
check_repl=`ssh $manager_ip cat /root/check-repl.txt | grep -o 'Health is OK'`

if [[ "successfully" == $check_ssh ]]; then
    if [[ "Health is OK" == $check_repl ]]; then
        echo "启动环境检测成功" >/dev/null
    else
        echo "启动环境检测失败"
    fi
    exit
fi

#启动MHA
echo -e "\033[33m-------------------------启动MHA-----------------------------\033[0m\n"
ssh "$manager_ip" 'systemctl start mysql-mha.service' 2>&1