0
点赞
收藏
分享

微信扫一扫

shell脚本--xtrabackup热备

皮皮球场 2022-02-10 阅读 157


#!/bin/bash
# Author:寂寞行走Penguin

# 颜色
ColorStart="\033["                            #${ColorStart}#
ColorEnd="\033[0m"                            #${ColorEnd}#
ColorBlack="\033[30;1m"         #黑色#        #${ColorBlack}#
ColorRed="\033[31;1m"           #红色#        #${ColorRed}#
ColorGreen="\033[32;1m"         #绿色#        #${ColorGreen}#
ColorYellow="\033[33;1m"        #黄色#        #${ColorYellow}#
ColorBlue="\033[34;1m"          #蓝色#        #${ColorBlue}#
ColorPink="\033[35;1m"          #粉色#        #${ColorPink}#
ColorCyan="\033[36;1m"          #青色#        #${ColorCyan}#
ColorWhite="\033[37;1m"         #白色#        #${ColorWhite}#

# 时间相关参数
Date=$(date +%F)
Time=$(date +%F_%T)

# 本机IP(任选一种方法即可)
#Ip=$(hostname -i)
Ip=$(hostname -I | awk '{print $2}')
#Ip=$(ip a | grep "scope global" | sed -n 2p | awk '{print $2 | "xargs dirname"}')

DevNull=">/dev/null 2>&1"

# 备份命令
XbkCmd=$(which innobackupex)
# 配置文件
# 如果一台服务器上起了多个mysql实例,那么可以按照端口号或者实例的具体用途来定义多个my.cnf的参数,视实际情况决定即可
MyCnf="/etc/my.cnf"
# mysql备份用户
XbkUser='xbk'
# mysql用户mima
XbkPass='xbkpw'

# 谁的备份
# 练习的时候不确定性高,用传参的方式来定义比较方便;用于业务线上的时候必然可以固定下来,直接写死即可
Domain=$1
# 全备和增备数据存放位置
XbkDir="/data/xtrabackup/${Domain}/${Ip}/${Date}"
# 全备数据存放位置
XbkAllDir=${XbkDir}/all
# tar包存放位置
SqlTarDir="/data/xtrabackup/RsyncPackage/${Domain}/${Ip}"

# 日志相关参数
# log文件存放位置
XbkLogDir="/data/logs/xtrabackup/"
# log文件名
LogFile="xtrabackup_${Domain}_${Ip}_${Date}.log"

function REPORT
{
    echo -e "${ColorStart}${ColorYellow}[${Time}]${ColorEnd} $1"
}

# Extension of REPORT,提示信息
function REPORT_INFO
{
    REPORT "[INFO] ${ColorStart}${ColorGreen}$1${ColorEnd}"
}

# Extension of REPORT,报错 & 退出
function REPORT_WARN
{
    REPORT "[WARNING] ${ColorStart}${ColorRed}$1${ColorEnd}" && exit 3
}

# 检查存放日志的目录及文件是否存在,若不存在则创建
# This function is used to check if the XbkLogDir and LogFile already exist.
function CHECK_LOG_DIR_FILE
{
    REPORT_INFO "Check XbkLogDir and LogFile."
    if [ ! -d ${XbkLogDir} ]
    then
        REPORT_INFO "XbkLogDir doesn't exist, create XbkLogDir and LogFile."
        mkdir -p ${XbkLogDir} && touch ${XbkLogDir}${LogFile}
    elif [[ -d ${XbkLogDir} && ! -f ${XbkLogDir}${LogFile} ]]
    then
        REPORT_INFO "XbkLogDir exists, LogFile doesn't exist, create LogFile only."
        touch ${XbkLogDir}${LogFile}
    else
        REPORT_INFO "XbkLogDir and LogFile all exist, anything needn't to do."
    fi
    [[ ! -d ${XbkLogDir} || ! -f ${XbkLogDir}${LogFile} ]] && REPORT_WARN "Something was wrong when 'CHECK_LOG_DIR_FILE', please check."
    sleep 1
}

# 检查存放压缩数据的目录是否存在,若不存在则创建
# This function is used to check if the SqlTarDir already exists.
function CHECK_SQL_TAR_DIR
{
    REPORT_INFO "Check Sql_Tar_Dir."
    #[ ! -d ${SqlTarDir} ] && mkdir -p ${SqlTarDir}
    #[ -d ${SqlTarDir} ] || REPORT_WARN "Something was wrong when create ${SqlTarDir}, please check."

    # if [ -d ${SqlTarDir} ] 
    # then
    #   REPORT_INFO "SqlTarDir exists, go on."
    # else
    #   mkdir -p ${SqlTarDir} && [ $? -ne 0 ] && REPORT_INFO "SqlTarDir exists, go on." || REPORT_WARN "Something was wrong when create ${SqlTarDir}, please check."
    # fi

    if [ -d ${SqlTarDir} ] 
    then
        REPORT_INFO "SqlTarDir exists, go on."
    else
        mkdir -p ${SqlTarDir}
    fi
    [ -d ${SqlTarDir} ] && REPORT_INFO "SqlTarDir exists, go on." || REPORT_WARN "Something was wrong when 'CHECK_SQL_TAR_DIR', please check."
}

# 检查innobackupex命令是否存在,若不存在则报错并退出
# This function is used to check if the innobackupex commond already exists.
function CHECK_CMD
{
    REPORT_INFO "Check commond innobackupex."
    #${XbkCmd} -v 2>/dev/null 1>/dev/null
    ${XbkCmd} -v ${DevNull}
    if [ $? -ne 0 ]
    then
        REPORT_WARN "Commond innobackupex doesn't exist, please check."
    else
        REPORT_INFO "Commond innobackupex exists, go on."
    fi
    sleep 1
}

# 传输tar包到存储服务上的函数,需要提前在存储服务器上部署好rsync服务的守护进程模式
# This function is used to rsync data_sql to storage server.
function RSYNC
{
    RsyncFile=$1
    RsyncPath=$2
    RsyncServer="存储服务器的IP或域名"
    SleepTime=`expr $(/usr/bin/hexdump -n4 -e\"%u\" /dev/urandom) % 900`
    sleep ${SleepTime}

    rsync -avr ${RsyncFile} ${RsyncServer}::${RsyncPath}/${Domain}

    # 检查check
    if [[ $? -ne 0 ]]
    then
        REPORT_WARN "Rsync Failed, please check."
    else
        REPORT_INFO "Rsync Success, congratulation."
    fi
}

# 全备的函数
# This function is used for backup all data.
function BACKUP_ALL
{
    cat /dev/null > ${XbkLogDir}${LogFile}

    # 因为是按天创建目录,所以存放备份数据的目录一定是不存在的,故无需检查直接创建即可。
    # create directory for xtrabackup.
    REPORT_INFO "Create directory for xtrabackup."
    mkdir -p ${XbkDir}
    sleep 3

    # 执行全备
    # start full backup
    REPORT_INFO "Start to back up ${Domain}/${Ip} all data."
    ${XbkCmd} --defaults-file=${MyCnf} --user=${XbkUser} --password=${XbkPass} --no-timestamp ${XbkAllDir} ${DevNull}
    sleep 5

    # 检查check
    if [ $? -ne 0 ]
    then
        REPORT_WARN "Failed to back up ${Domain}/${Ip} all data, please check."
    else
        REPORT_INFO "Successfully backed up ${Domain}/${Ip} all data."
    fi

    # 压缩数据,打tar包
    REPORT_INFO "Start to package ${Domain}/${Ip} all backup data."
    cd ${XbkAllDir}
    if [ `pwd` = ${XbkAllDir} ]
    then
        tar -zcf ${SqlTarDir}/${Domain}_xbk_all_${Date}.sql.tar.gz *
    else
        REPORT_WARN "Something was wrong when TAR ${Domain}/${Ip} all backup data, please check."
    fi
    sleep 3

    # 检查check
    if [ $? -ne 0 ]
    then
        REPORT_WARN "Failed to package ${Domain}/${Ip} all backup data, please check."
    else
        REPORT_INFO "Successfully ${Domain}/${Ip} packageed all backup data."
    fi

    # 传输tar包到存储服务上,调用RSYNC函数
    # 需要2个参数,第1个参数是要传输的数据,第2个参数是想要使用的存储服务器上配置的rsync守护进程模式的模块名字
    REPORT_INFO "Start to sync ${Domain}/${Ip} all backup data."
    RSYNC ${SqlTarDir}/../ "backup_data"
    sleep 3

    # 传输完毕后删除tar包,释放本机磁盘空间
    REPORT_INFO "End rsync, delete ${SqlTarDir}/${Domain}_xbk_all_${Date}.sql.tar.gz"
    rm -f ${SqlTarDir}/${Domain}_xbk_all_${Date}.sql.tar.gz
    sleep 3
}

# 增备的函数
# This function is used for backup incremental data.
function BACKUP_INC
{
    cd ${XbkDir}
    local LastPath=$(ls -drt inc* all | tail -1)
    #local LastPath=$(ls -drt * | tail -1)

    if [[ ${LastPath} == "all" ]] 2>/dev/null 1>/dev/null
    then
        local num=1
    else
        local num=$(expr $(echo ${LastPath} | grep -o "[0-9][0-9]*$") + 1 )
    fi

    # 执行增备
    # start inc backup
    REPORT_INFO "Start to back up ${Domain}/${Ip} inc_$num data."
    ${XbkCmd} --defaults-file=${MyCnf} --user=${XbkUser} --password=${XbkPass} --no-timestamp --incremental --incremental-basedir=${XbkAllDir} ${XbkDir}/inc_$num ${DevNull}
    sleep 5

    # 检查check
    if [ $? -ne 0 ]
    then
        REPORT_WARN "Failed to back up ${Domain}/${Ip} inc_$num data, please check."
    else
        REPORT_INFO "Successfully backed up ${Domain}/${Ip} inc_$num data."
    fi

    # 压缩数据,打tar包
    REPORT_INFO "Start to package ${Domain}/${Ip} inc_$num backup data."
    cd ${XbkDir}/inc_$num
    if [ `pwd` = ${XbkDir}/inc_$num ]
    then
        tar -zhcf ${SqlTarDir}/${Domain}_xbk_inc_${num}_${Date}.sql.tar.gz *
    else
        REPORT_WARN "Something was wrong when TAR ${Domain}/${Ip} inc_$num backup data, please check."
    fi
    sleep 3

    # 检查check
    if [ $? -ne 0 ]
    then
        REPORT_WARN "Failed to package ${Domain}/${Ip} inc_$num backup data, please check."
    else
        REPORT_INFO "Successfully packaged ${Domain}/${Ip} inc_$num backup data."
    fi

    # 传输tar包到存储服务上,调用RSYNC函数
    # 需要2个参数,第1个参数是要传输的数据,第2个参数是想要使用的存储服务器上配置的rsync守护进程模式的模块名字
    REPORT_INFO "Start to sync ${Domain}/${Ip} inc_$num backup data."
    RSYNC ${SqlTarDir}/../ "backup_data"
    sleep 3

    # 传输完毕后删除tar包,释放本机磁盘空间
    REPORT_INFO "End rsync, delete ${SqlTarDir}/${Domain}_xbk_inc_${num}_${Date}.sql.tar.gz"
    rm -f ${SqlTarDir}/${Domain}_xbk_inc_${num}_${Date}.sql.tar.gz
    sleep 3
}

# 主函数
# When the incremental backup doesn't exist, the full backup fonction is called.
function MAIN
{
    CHECK_SQL_TAR_DIR
    CHECK_CMD
    sleep 3

    if [ ! -d ${XbkDir}/all ]
    then
        BACKUP_ALL
    else
        BACKUP_INC
    fi
    echo -e "==================================================\n"
}

#####脚本入口#####
CHECK_LOG_DIR_FILE
MAIN $1 | tee -a ${XbkLogDir}${LogFile}
举报

相关推荐

0 条评论