青成林语

协助他人,成就彼此 ^_^
自动化部署Mysql数据库的脚本
# !/bin/bash
# author hlc
# createTime 2024-06-17
# modifyTime 2024-06-18
# version 1.0
# description 自动安装Mysql
source /etc/init.d/functions


# 定义参数
# 用于循环
count=0
# 时间
date=$(date "+%H:%M:%S:%N")
#==========Mysql服务器参数==========
# Mysql服务器用户名
name=root
# Mysql服务器IP地址
host=192.168.217.101
# Mysql用户名
mysqlName=root
# Mysql要设置的密码
mysqlPasswd=Xls@123..
# mysql安装包校验文件名称
mysqlMD5=mysql.tar.gz.flag
# 需要MD5生成的配置校验文件
configMD5=mysqlconfig.${date}.flag
# 远程登录用户名
remoteName=root
# 远程登录用户密码
remotePasswd=Remote@123..
# 要存放脚本报错的文件
error=/tmp/error.log
# **********这三个参数必须跟资源服务器中的配置文件同步*********
# data的存放路径
datadir=/Auto_MySQL_Data/mysql
# binlog的存放路径
binlogdir=/Auto_MySQL_Data/mysql_bin/
# slowlog的存放路径
slowlogdir=/Auto_MySQL_Data/mysql_slow/


#==========资源服务器参数==========
# 资源服务器用户名
sourceName=root
# 资源服务器密码
sourcePasswd=123456
# 资源服务器IP地址
sourceHost=192.168.217.200
# Mysql安装包的路径
mysqlPath=/tools/mysql/
# mysql安装包名称
mysqlRpm=mysql.tar.gz
# mysql配置文件名称
configName=mysqlconfig


#==========自定义函数==========
# 创建SSH密钥
createSSHKey() {
expect << eof
    spawn  ssh-keygen
    expect ".ssh/id_rsa):"
    send "\r"
    expect {
        # 如果没有密钥则创建密钥
        "no passphrase):"
        { send "\r" }
        # 如果有密钥则退出
        "Overwrite (y/n)? "
        { send "exit\r" }
    }
    expect "again:"
    send "\r"
expect eof
eof
}

# 与资源服务器建立SSH连接
createSSHLink() {
expect << eof
    spawn  ssh-copy-id -i /${name}/.ssh/id_rsa.pub ${sourceName}@${sourceHost}
    expect "connecting (yes/no)? "
    send "yes\r"
    expect "'s password: "
    send "${sourcePasswd}\r"
expect eof
eof
}


# 对目录进行检测
checkDir() {
    # 检测Mysql的数据存储目录
    if [[ -d $datadir} ]]
        then
            action "${datadir}已经被使用了" /bin/false
            echo "error code: 0 --> ${datadir} has been used" >> ${error}
            exit 127
    fi
    action "${datadir}可以使用" /bin/true 
    
    # 检测Mysql的binlog存储目录
    if [[ -d $binlogdir} ]]
        then
            action "${binlogdir}已经被使用了" /bin/false
            echo "error code: 0 --> ${binlogdir} has been used" >> ${error}
            exit 127
    fi
    action "${binlogdir}可以使用" /bin/true 
    
    # 检测Mysql的slowlog存储目录
    if [[ -d $slowlogdir} ]]
        then
            action "${slowlogdir}已经被使用了" /bin/false
            echo "error code: 0 --> ${slowlogdir} has been used" >> ${error}
            exit 127
    fi
    action "${slowlogdir}可以使用" /bin/true 
}

# 对环境进行检测
checkEnvironment() {
    # 判断是否有expect
    line=$(rpm -qa | grep expect | wc -l)
    if [[ ${line} -eq 0 ]]
        then
            # 下载expect
            yum install expect -y && action "安装expect成功" /bin/true || (action "安装expect失败" /bin/false; echo "error code: 1 --> can not download expect" >> ${error}; exit 127)
    fi
    
    # 创建SSH密钥
    createSSHKey >> /dev/null 2>&1
    
    # 测试SSH连接
    while [ ${count} -lt 3 ]
    do
        timeout 5 ssh ${sourceName}@${sourceHost} "echo ''" >> /dev/null 2>&1
        if [[ $? -eq 0 ]]
            then
                action "可以连接到资源服务器" /bin/true
                break
            else
                # 创建SSH连接
                createSSHLink >> /dev/null 2>&1
                ((count++))
        fi
    done
    # 如果连接失败则报错
    if [[ ${count} -eq 3 ]]
        then
            action "建立SSH连接失败" /bin/false
            echo "error code: 1 --> can not create ssh connection" >> ${error}
            exit 127
    else
        action "建立SSH连接成功" /bin/true
    fi
    
    # 判断Mysql服务器上是否有与资源服务器一样的目录
    if [[ -d ${mysqlPath} ]]
        then
            action "${mysqlPath}已经被使用了" /bin/false
            echo "error code: 1 --> ${mysqlPath} has been used" >> ${error}
            exit 127
    fi
    # 如果不存在该目录则创建
    mkdir -p ${mysqlPath}
    if [[ $? -ne 0 ]]
        then
            action "创建${mysqlPath}失败" /bin/false
            echo "error code: 1 --> create ${mysqlPath} fail" >> ${error}
            exit 127
    fi
    action "创建${mysqlPath}成功" /bin/true
}

# 下载Mysql安装包,并进行校验
downloadMysql() {
    # 从资源服务器上将mysql安装包拉取下来
    count=0
    while [ ${count} -lt 3 ]
    do
        rsync -a ${sourceName}@${sourceHost}:${mysqlPath}/${mysqlRpm} ${mysqlPath}
        if [[ $? -eq 0 ]]
            then
                break;
        else
            ((count++))
        fi
    done
    # 判断是否成功拉取文件
    if [[ ${count} -eq 3 ]]
        then
            action "从资源服务器拉取mysql安装包失败" /bin/false
            echo "error code: 2 --> download mysql fail" >> ${error}
            exit 127
    else
        action "从资源服务器拉取mysql安装包成功" /bin/true
    fi
    
    # 从资源服务器上将mysqlMD5校验文件拉取下来
    count=0
    while [ ${count} -lt 3 ]
    do
        rsync -a ${sourceName}@${sourceHost}:${mysqlPath}/${mysqlMD5} ${mysqlPath}
        if [[ $? -eq 0 ]]
            then
                break;
        else
            ((count++))
        fi
    done
    # 判断是否成功拉取文件
    if [[ ${count} -eq 3 ]]
        then
            action "从资源服务器拉取mysql校验文件失败" /bin/false
            echo "error code: 2 --> download mysqlconfig fail" >> ${error}
            exit 127
    else
        action "从资源服务器拉取mysql校验文件成功" /bin/true
    fi
    
    # 跳转到Mysql安装包路径
    cd ${mysqlPath}
    
    # 校验安装包
    result=$(md5sum -c ${mysqlMD5} | grep "${mysqlRpm}: OK" | wc -l)
    if [[ ${result} -ne 1 ]]
        then
            action "mysql安装文件已损失" /bin/false
            echo "error code: 2 --> mysql is corrupted" >> ${error}
            exit 127
    else
        action "mysql安装文件完整" /bin/true  
    fi
}

# 解压Mysql安装包并安装Mysql
installMysql() {
    # 解压安装包
    if [[ -f ${mysqlRpm} ]]
        then
            tar -zxf ${mysqlRpm} -C ./
            if [[ $? -ne 0 ]]
                then
                    action "mysql安装包解压失败" /bin/false
                    echo "error code: 3 --> unzip mysql.tar.gz" >> ${error}
                    exit 127
            fi
            action "mysql安装包解压成功" /bin/true
    fi
    
    # 安装mysql
    # 卸载mariadb
    rpm -e --nodeps mariadb-libs && action "卸载mariadb成功" /bin/true ||  (action "卸载mariadb失败" /bin/false; echo "error code: 3 --> uninstall mariadb fail" >> ${error}; exit 127)
    # 安装ncurses-devel libaio-devel
    yum install ncurses-devel libaio-devel -y && action "安装ncurses-devel libaio-devel成功" /bin/true || (action "安装ncurses-devel libaio-devel失败" /bin/false; echo "error code: 3 --> install ncurses-devel libaio-devel fail" >> ${error}; exit 127)
    # 安装mysql-community-common
    rpm -ivh mysql-community-common-5.7.38-1.el7.x86_64.rpm && action "安装mysql-community-common成功" /bin/true || (action "安装mysql-community-common失败" /bin/false; echo "error code: 3 --> install mysql-community-common fail" >> ${error}; exit 127)
    # 安装mysql-community-libs
    rpm -ivh mysql-community-libs-5.7.38-1.el7.x86_64.rpm && action "安装mysql-community-libs成功" /bin/true || (action "安装mysql-community-libs失败" /bin/false; echo "error code: 3 --> install mysql-community-libs fail" >> ${error}; exit 127)
    # 安装mysql-community-devel
    rpm -ivh mysql-community-devel-5.7.38-1.el7.x86_64.rpm && action "安装mysql-community-devel成功" /bin/true || (action "安装mysql-community-devel失败" /bin/false; echo "error code: 3 --> install mysql-community-devel fail" >> ${error}; exit 127)
    # 安装mysql-community-client
    rpm -ivh mysql-community-client-5.7.38-1.el7.x86_64.rpm && action "安装mysql-community-client成功" /bin/true || (action "安装mysql-community-client失败" /bin/false; echo "error code: 3 --> install mysql-community-client fail" >> ${error}; exit 127)
    # 安装mysql-community-server
    rpm -ivh mysql-community-server-5.7.38-1.el7.x86_64.rpm && action "安装mysql-community-server成功" /bin/true || (action "安装mysql-community-server失败" /bin/false; echo "error code: 3 --> install mysql-community-server fail" >> ${error}; exit 127)
}

# 下载Mysql配置文件并进行更改
changeMysqlConfig() {
    # 在资源服务器上为mysql配置文件生成校验文件
    count=0
    while [ ${count} -lt 3 ]
    do
        ssh ${sourceName}@${sourceHost} "cd ${mysqlPath} && md5sum ${configName} > ${configMD5}"
        if [[ $? -eq 0 ]]
            then
                break;
        else
            ((count++))
        fi
    done
    # 判断是否成功生成configMD5文件
    if [[ ${count} -eq 3 ]]
        then
            action "生成configMD5失败" /bin/false
            echo "error code: 4 --> create configMD5 fail" >> ${error}
            exit 127
    else
        action "生成configMD5成功" /bin/true
    fi
    
    # 从资源服务器上将mysql配置文件拉取下来
    count=0
    while [ ${count} -lt 3 ]
    do
        rsync -a ${sourceName}@${sourceHost}:${mysqlPath}/${mysqlconfig} ${mysqlPath}
        if [[ $? -eq 0 ]]
            then
                break;
        else
            ((count++))
        fi
    done
    # 判断是否成功拉取文件
    if [[ ${count} -eq 3 ]]
        then
            action "从资源服务器拉取mysql配置文件失败" /bin/false
            echo "error code: 4 --> download mysqlconfigMD5 fail" >> ${error}
            exit 127
    else
        action "从资源服务器拉取mysql校验配置成功" /bin/true
    fi
    
    # 配置文件拉取成功后更改资源服务器的配置文件
    id=$(cat ${mysqlPath}${configName} | grep 'server-id' | awk -F '=' '{print $2}')
    if [[ ${id} -gt 1000000 ]]
        then
            action "配置文件的server-id太大了,存在风险" /bin/false
            echo "error code: 4 --> server-id is so large, it is a dangerous operation" >> ${error}
            exit 127
    fi
    # 记录当前id数值
    oldid=${id}
    action "本次配置mysql使用的server-id为${oldid}"
    # id+1写回配置文件
    ((id++))
    action "为资源服务器的配置文件更新的server-id为${id}"
    count=0
    while [ ${count} -lt 3 ]
    do
        ssh ${sourceName}@${sourceHost} "sed -i "s/server-id=${oldid}/server-id=${id}/" ${mysqlPath}${configName}"
        if [[ $? -eq 0 ]]
            then
                break;
        else
            ((count++))
        fi
    done
    # 判断是否成功更改配置文件
    if [[ ${count} -eq 3 ]]
        then
            action "更新资源服务器的mysql配置文件失败" /bin/false
            echo "error code: 4 --> update mysqlconfig fail" >> ${error}
            exit 127
    fi
    action "更新资源服务器的mysql配置文件成功" /bin/true
    
    # 从资源服务器上将configMD5文件拉取下来
    count=0
    while [ ${count} -lt 3 ]
    do
        rsync -a ${sourceName}@${sourceHost}:${mysqlPath}/${configMD5} ${mysqlPath}
        if [[ $? -eq 0 ]]
            then
                break;
        else
            ((count++))
        fi
    done
    # 判断是否成功拉取文件
    if [[ ${count} -eq 3 ]]
        then
            action "从资源服务器拉取mysqlMD5文件失败" /bin/false
            echo "error code: 4 --> download configMD5 fail" >> ${error}
            exit 127
    else
        action "从资源服务器拉取mysqlMD5文件成功" /bin/true
    fi
    
    # 校验配置文件
    result=$(md5sum -c ${configMD5} | grep "${configName}: OK" | wc -l)
    if [[ ${result} -ne 1 ]]
        then
            action "mysql配置文件已损失" /bin/false
            echo "error code: 4 --> mysqlconfig is corrupted" >> ${error}
            exit 127
    else
        action "mysql配置文件完整" /bin/true  
    fi
    
    # 校验成功后将configMD5校验文件删除
    count=0
    while [ ${count} -lt 3 ]
    do
        ssh ${sourceName}@${sourceHost} "cd ${mysqlPath} && rm -f ${configMD5}"
        if [[ $? -eq 0 ]]
            then
                break;
        else
            ((count++))
        fi
    done
    # 判断是否成功删除文件
    if [[ ${count} -eq 3 ]]
        then
            action "无法删除config校验文件:${configMD5}" /bin/false
            echo "waring code: 4 --> delete mysqlconfigMD5 fail" >> ${error}
    else
        action "成功删除config校验文件:${configMD5}" /bin/true
    fi
    
    # 删除原有的配置文件
    rm -rf /etc/my.cnf
    # 替换拉取的配置文件
    mv ${mysqlPath}${configName} /etc/my.cnf
}

# 创建Mysql的文件目录
createDir() {
    # 根据配置文件创建目录
    # 创建data存放路径
    mkdir -p ${datadir}
    if [[ $? -ne 0 ]]
        then
            action "不能创建目录:${datadir}" /bin/false
            # 将错误结果输出到文件中
            echo "error code: 5 --> can not create ${datadir}" >> ${error}
            exit 127
    else
        cd ${datadir}
        chown -R mysql:mysql ..
        action "可以创建目录:${datadir}" /bin/true
    fi
    
    # 创建binlog存放路径
    mkdir -p ${binlogdir}
    if [[ $? -ne 0 ]]
        then
            action "不能创建目录:${binlogdir}" /bin/false
            # 将错误结果输出到文件中
            echo "error code: 5 --> can not create ${binlogdir}" >> ${error}
            exit 127
    else
        cd ${binlogdir}
        chown -R mysql:mysql ..
        action "可以创建目录:${binlogdir}" /bin/true
    fi
    
    # 创建slowlog的存放路径
    mkdir -p ${slowlogdir}
    if [[ $? -ne 0 ]]
        then
            action "不能创建目录:${slowlogdir}" /bin/false
            # 将错误结果输出到文件中
            echo "error code: 5 --> can not create ${slowlogdir}" >> ${error}
            exit 127
    else
        cd ${slowlogdir}
        chown -R mysql:mysql ..
        action "可以创建目录:${slowlogdir}" /bin/true
    fi
}

# 启动Mysql,并配置Mysql自启动
startMysql() {
    # 启动Mysql
    systemctl start mysqld
    if [[ $? -ne 0 ]]
        then
            action "启动Mysql失败" /bin/false
            echo "error code: 6 --> start mysql fail" >> ${error}
            exit 127
    fi
    action "启动Mysql成功" /bin/true
    
    # 设置Mysql自启动
    systemctl enable mysqld
    if [[ $? -ne 0 ]]
        then
            action "不能设置Mysql自启动" /bin/false
            echo "error code: 6 --> set mysql enable fail" >> ${error}
            exit 127
    fi
    action "设置Mysql自启动成功" /bin/true
}

# 对Mysql进行初始化配置,并创建远程用户
initMysql() {    
    # 获取mysql的初始密码
    startPasswd=$(cat /var/log/mysqld.log | grep root@localhost: | awk -F ': ' '{print $2}')
    # 登录mysql,并重置密码
    mysql -u"${mysqlName}" -p"${startPasswd}" --connect-expired-password -e "alter user '${mysqlName}'@'localhost' identified by '${mysqlPasswd}';grant all privileges on *.* to '${mysqlName}'@'localhost';flush privileges;" >> /dev/null 2>&1
    if [[ $? -ne 0 ]]
        then
            action "无法重置初始密码" /bin/false
            echo "error code: 7 --> can not reset password" >> ${error}
            exit 127
    fi
    action "成功重置初始密码" /bin/true
    
    # 创建远程登录
    mysql -u"${mysqlName}" -p"${mysqlPasswd}" -e "create user '${remoteName}'@'%' IDENTIFIED WITH mysql_native_password BY '${remotePasswd}';GRANT ALL ON *.* TO '${remoteName}'@'%' WITH GRANT OPTION;flush privileges;"  >> /dev/null 2>&1
    if [[ $? -ne 0 ]]
        then
            action "创建远程登录用户失败" /bin/false
            echo "error code: 7 --> create remote user fail" >> ${error}
            exit 127
    fi
    action "创建远程登录用户成功" /bin/true
    
    # 校验mysql的root用户
    mysql -u"${mysqlName}" -p"${mysqlPasswd}" -e "show databases\G;" >> /dev/null 2>&1
    if [[ $? -ne 0 ]]
        then
            action "mysql的root用户初始化失败" /bin/false
            echo "error code: 7 --> mysql root user init fail" >> ${error}
            exit 127
    fi
    action "mysql的root用户初始化成功" /bin/true
    
    # 校验mysql的远程用户
    mysql -h"${host}" -u"${remoteName}" -p"${remotePasswd}" -e "show databases\G;" >> /dev/null 2>&1
    if [[ $? -ne 0 ]]
        then
            action "mysql的远程用户初始化失败" /bin/false
            echo "error code: 7 --> mysql remote user init fail" >> ${error}
            exit 127
    fi
    action "mysql的远程用户初始化成功" /bin/true
}

#==========shell执行流程,case控制==========
# 使用变量接收用户输入,便于操作
single=$1

# whlie循环保证安装流程顺利执行
while true
do
    case ${single} in
        # 对Mysql的文件目录进行检测
        0)
            checkDir
            ((single++))
            ;;
        # 检查通信环境
        1)
            checkEnvironment
            ((single++))
            ;;
        # 下载Mysql安装包,并进行校验
        2)
            downloadMysql
            ((single++))
            ;;
        # 解压安装包并安装mysql
        3)
            installMysql
            ((single++))
            ;;
        # 下载Mysql配置文件并进行更改
        4)
            changeMysqlConfig
            ((single++))
            ;;
        # 创建Mysql的文件目录
        5)
            createDir
            ((single++))
            ;;
        # 启动Mysql,并配置Mysql自启动
        6)
            startMysql
            ((single++))
            ;;
        # 对Mysql进行初始化配置,并创建远程用户
        7)
            initMysql
            ((single++))
            ;;
        # 退出循环
        8)
            action "成功安装Mysql" /bin/true
            exit 0
            ;;
        # 用户传入错误参数
        *)
            action "请使用正确的参数进行安装,从头安装请使用0" /bin/false
            exit 127
    esac
done

 

posted on 2024-08-27 19:35  青成林语  阅读(9)  评论(0编辑  收藏  举报