每天自动备份远程Mysql数据库脚本。

Ubuntu22.4操作系统

1、通过ssh远程连接,配合mysqldump备份数据库全部内容,备份脚本remotemysqlbak.sh(/root/mysql_bak/remotemysqlbak.sh),内容如下:

#!/bin/bash
#第一行为声明sh脚本

# 定义远程服务器信息变量
# 远程服务器地址
#remote_host="远程服务器地址"
remote_host="mysql.eu.org"
# 远程服务器用户名
#remote_user="远程服务器用户名"
remote_user="root"
# 远程服务器密码
#remote_password="远程服务器密码"
remote_password="A123456+"
# 远程服务器ssh端口
#remote_port="远程服务器SSH端口"
remote_port=22
# 指定备份文件路径
#backup_path="/指定的/备份/路径"
backup_path="/root/mysql_bak/${remote_host}"
#定义ssh登录秘钥的路径,如果采用这种登录方法的情况
private_key_path="/path/to/mpp.pem"
#备份到本地的文件的路径,生成当前日期作为备份文件名的一部分
current_date=$(date +"%Y%m%d")
backup_file="${backup_path}/backup_${current_date}.sql"
#获取服务器时间转换成+8区时间,用户log记录时间
current_time_with_timezone=$(date +"%s")
current_time_8plus=$(date -d "@$current_time_with_timezone" +"%H:%M:%S %z" -u --date='+8 hours' | sed 's/+0000/+0800/')

# MySQL 信息
# 数据库访问用户名
#db_user="MySQL用户名"
db_user="blogdbuser"
# 数据库访问对应的密码
#db_password="MySQL密码"
db_password="A123456+"
# 数据库名称
#db_name="数据库名"
db_name="blogdb"

# 定义一个执行远程备份的function
perform_backup() {
#密码登录方式
# sshpass -p $remote_password ssh -p $remote_port $remote_user@$remote_host "mysqldump -u $db_user -p$db_password $db_name" > $backup_file
#私钥登录方式
# 启动 ssh-agent 并添加私钥
echo "Before ssh-add"
eval "$(ssh-agent -s)"
ssh-add "$private_key_path"
echo "After ssh-add"
ssh -v -p $remote_port $remote_user@$remote_host "mysqldump -u $db_user -p$db_password $db_name" > $backup_file
}
# 关闭 ssh-agent
# 关闭 ssh-agent
kill $SSH_AGENT_PID

# 定义一个检查目录是否存在的function,不存在则创建
checkdir(){
# 检查备份目录是否存在,不存在则创建
if [ ! -d "$backup_path" ]; then
    mkdir -p "$backup_path"
fi
}

# 定义检查备份是否成功的function
check_bak_ok(){
if [ $? -eq 0 ]; then
    echo "远程备份成功!备份文件路径为: $backup_file 备份时间:$current_time_8plus ." | tee -a $backup_path/backup.log
else
    echo "远程备份失败,请检查错误信息, 备份时间:$current_time_8plus ." | tee -a $backup_path/backup.log
fi
}

# 执行备份操作
#检测目录是否存在
checkdir
#执行远程备份
perform_backup
#反馈备份结果
check_bak_ok

定义的变量一定要修改成自己的否则,不可能运行通的哦~另,我在调试过程中远程服务器用户使用非root用户时,ssh是不通的,貌似不给/root/.ssh/访问权限。另,私钥需要 提前 执行权限操作,太高太低就不给连:

chmod 400 /root/keys/mpp.pem

2、每天6点自动备份

#打开计划任务管理器配置文件
crontab -e
#把下面的命令行,输入进去,并保存退出
0 6 * * * bash /root/mysql_bak/remotemysqlbak.sh

3、后期查看

查询最近7天的log日志,并显示其中有多少条成功的数据,提示是否删除7天前的备份内容及log日志check_log.sh(/root/mysql_back/check_log.sh),内容如下:

#!/bin/bash

#变量定义区
# 指定日志文件路径
log_file="/root/mysql_bak/usql.eu.org/backup.log"
sql_dir="/root/mysql_bak/usql.eu.org/"
# 获取当前日期
current_date=$(date +"%Y%m%d")
#获取服务器时间转换成+8区时间,用户log记录时间
current_time_with_timezone=$(date +"%s")
current_time_8plus=$(date -d "@$current_time_with_timezone" +"%H:%M:%S %z" -u --date='+8 hours' | sed 's/+0000/+0800/')


#变量定义区结束

#函数定义区

check_logfile() {
#先检查日志文件是否存在,不存在,10s后直接退出脚本
if [ ! -f "$log_file" ]; then
    echo "日志文件不存在,请先运行一次备份脚本。"
    for i in {10..1}; do
        echo -ne "等待 $i 秒后退出脚本...\r"
        sleep 1
    done
    echo "Exiting."
    sleep 3
    exit 1
fi
}

check_log_null(){
# 如果日志文件为空,输出提示并退出
if [ ! -s "$log_file" ]; then
    echo "日志文件为空,无法进行操作。请先执行一次备份脚本!"
    for i in {10..1}; do
        echo -ne "等待 $i 秒后退出脚本...\r"
        sleep 1
    done
    echo "Exiting."
    sleep 3
    exit 1
fi
}

check_log_7d(){
# 如果成功的数量为0,提示并结束脚本
success_count=$(grep -c "远程备份成功" $log_file)
#echo $success_count
if [ "$success_count" -eq 0 ]; then
    echo "七天内未成功备份,请查找原因!"
    for i in {10..1}; do
        echo -ne "等待 $i 秒后退出脚本...\r"
        sleep 1
    done
    echo "Exiting."
    sleep 3
    exit 1
fi
}

show_op_7d_logs(){
        # 显示最近七天的日志内容
        echo "最近七天的日志内容:"
        grep "$(date -d '1 days ago' +"%Y%m%d")\|$(date -d '2 days ago' +"%Y%m%d")\|$(date -d '3 days ago' +"%Y%m%d")\|$(date -d '4 days ago' +"%Y%m%d")\|$(date -d '5 days ago' +"%Y%m%d")\|$(date -d '6 days ago' +"%Y%m%d")\|$(date +"%Y%m%d")" $log_file
        #grep "$(date -d '7 days ago' +"%Y%m%d")" $log_file 七天前

        # 统计所有及这七天内备份成功的日志条数
        success_count_all=$(grep -c "远程备份成功" $log_file)
        echo "全部备份成功的数量: $success_count_all"
        success_count_7d=$(grep -cE "$(date -d '1 days ago' +"%Y%m%d")|$(date -d '2 days ago' +"%Y%m%d")|$(date -d '3 days ago' +"%Y%m%d")|$(date -d '4 days ago' +"%Y%m%d")|$(date -d '5 days ago' +"%Y%m%d")|$(date -d '6 days ago' +"%Y%m%d")|$(date +"%Y%m%d")" $log_file)

        echo "最近七天备份成功的数量: $success_count_7d"


        # 提示是否删除七天之前的备份文件及日志内容
        read -p "是否删除七天之前的备份文件及日志内容? (y/n): " answer

        if [ "$answer" == "y" ]; then
            # 获取七天之前的日期
            seven_days_ago=$(date -d "7 days ago" +"%Y%m%d")
            # 执行find命令 删除目录下的修改时间在7天前的文件
            sudo find $sql_dir -name "backup_*" -type f -mtime +6 -exec rm -f {} \;

            # 在find命令之后显示消息
            echo "7天前的备份文件删除成功。"
            
            # 清空7天前日志内容 !!!
              #确认需要保留的字符串内容
              date_range=""
              for ((i = 1; i <7; i++)); do
                  date_range+="$(date -d "$i days ago" +"%Y%m%d")\|"
              done
              date_range="${date_range}$(date +"%Y%m%d")"
              #显示变量内容,用于确认值是否正确
              #echo $date_range
              #执行删除操作
              sudo sed -i "/$date_range/!d" $log_file
            #原始的逐个累加字符串方式
            #sudo sed -i "/$(date -d '1 days ago' +"%Y%m%d")\|$(date -d '2 days ago' +"%Y%m%d")\|$(date -d '3 days ago' +"%Y%m%d")\|$(date -d '4 days ago' +"%Y%m%d")\|$(date -d '5 days ago' +"%Y%m%d")\|$(date -d '6 days ago' +"%Y%m%d")\|$(date +"%Y%m%d")/!d" $log_file
            
            #只删除之前第七条的日志
            #sed -i "\#,/backup_$seven_days_ago.sql#d" $log_file

            echo "已删除七天之前的备份文件及清空日志内容。"
        else
            echo "未删除任何文件。"
        fi
}

#执行代码区:

#检查log文件是否存在
check_logfile
#检查log日志是否为空
check_log_null
#检查7天内是否存在备份成功的记录
check_log_7d
#查看和操作7天内的日志及备份数据
show_op_7d_logs

哈哈~~~断断续续,代码调试了接近6-7个小时,ChatGPT3.5都干冒烟了,对于我说的中文它理解几十次都不完全对,只好先看它给的代码的实际含义,理解了,然后用笨逻辑写出来代码,再让它给优化,再验证。中途差点放弃,还好功成,又学到了~~~