mysql 8.4.2 备份脚本

一、创建备份专用账户

复制代码
# 创建备份账户
> create user `bkup_user`@'localhost' identified by 'StBxxxxxxx';

# 授予备份所需要的权限
> grant select,reload,lock tables,replication client,process,event,trigger,show view,execute,alter routine on *.* to `bkup_user`@'localhost';

# 刷新权限
> flush privileges;

# 验证权限
> show grants for `bkup_user`@'localhost';

二、创建备份配置文件

复制代码
# 创建MySQL备份配置文件
sudo mkdir -p /work/mysql/backup
sudo tee /work/mysql/backup/backup.cnf > /dev/null <<EOF
[client]
user=bkup_user
password=StBuxxxxxxx
host=localhost
port=3306
socket=/work/mysql842/mysql/sock/mysql.sock  #根据实际情况,ps -ef|grep mysqld
EOF

# 设置文件权限
sudo chmod 600 /work/mysql/backup/backup.cnf
sudo chown root:root /work/mysql/backup/backup.cnf

三、使用备份账户的备份脚本

复制代码
# cat mysql/scripts/mysql_backup.sh
#!/bin/bash

# MySQL每日备份脚本(使用备份专用账户)
# 备份保留7天

# 配置参数
BACKUP_CNF="/work/mysql/backup/backup.cnf"  # 备份配置文件
BACKUP_DIR="/work/mysql/mysql_backup"                 # 备份目录
DATE_FORMAT=$(date +%Y%m%d_%H%M%S)        # 时间格式
LOG_FILE="/work/mysql/mysql_backup.log"      # 日志文件
RETENTION_DAYS=7                          # 保留天数
COMPRESS_LEVEL=6                          # 压缩级别(1-9)

# 创建必要的目录
mkdir -p ${BACKUP_DIR}
mkdir -p $(dirname ${LOG_FILE})

# 日志函数
log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG_FILE}
}

# 错误处理函数
error_exit() {
    log "错误: $1"
    exit 1
}

# 检查MySQL连接和权限
check_mysql_connection() {
    log "检查MySQL连接和备份权限..."
    
    if ! mysql --defaults-file=${BACKUP_CNF} -e "SHOW DATABASES;" >/dev/null 2>&1; then
        error_exit "无法连接到MySQL服务器,请检查备份配置文件"
    fi
    
    # 检查必要的权限
    local permissions=$(mysql --defaults-file=${BACKUP_CNF} -e "SHOW GRANTS FOR CURRENT_USER()" 2>/dev/null | grep -i -E "(SELECT|RELOAD|LOCK TABLES|PROCESS)")
    
    if [[ -z "$permissions" ]]; then
        log "警告: 备份账户可能缺少某些权限"
    else
        log "MySQL连接和权限检查通过"
    fi
}

# 获取数据库列表(排除系统数据库)
get_database_list() {
    mysql --defaults-file=${BACKUP_CNF} -N -e "SHOW DATABASES;" | \
    grep -v -E "(information_schema|performance_schema|sys|mysql)"
}

# 执行完整备份
perform_backup() {
    local backup_file="${BACKUP_DIR}/full_backup_${DATE_FORMAT}.sql"
    local compress_file="${backup_file}.gz"
    
    log "开始MySQL完整备份..."
    log "备份文件: ${compress_file}"
    
    # 获取数据库列表
    local databases=$(get_database_list)
    if [[ -z "$databases" ]]; then
        error_exit "未找到可备份的数据库"
    fi
    
    log "备份数据库: $databases"
    
    # 使用mysqldump进行完整备份
    if mysqldump --defaults-file=${BACKUP_CNF} \
        --databases $databases \
        --single-transaction \
        --routines \
        --events \
        --triggers \
        --master-data=2 \
        --flush-logs \
        --add-drop-database \
        --complete-insert \
        --hex-blob \
        --max-allowed-packet=1G \
        > ${backup_file} 2>>${LOG_FILE}; then
        
        # 检查备份文件大小
        local file_size=$(du -h ${backup_file} | cut -f1)
        log "备份文件大小: ${file_size}"
        
        # 压缩备份文件
        log "压缩备份文件 (级别: ${COMPRESS_LEVEL})..."
        if gzip -${COMPRESS_LEVEL} ${backup_file} 2>>${LOG_FILE}; then
            local compressed_size=$(du -h ${compress_file} | cut -f1)
            log "压缩完成: ${compressed_size}"
            echo ${compress_file}
            return 0
        else
            error_exit "备份文件压缩失败"
        fi
    else
        error_exit "MySQL备份失败"
    fi
}

# 清理旧备份
cleanup_old_backups() {
    log "清理${RETENTION_DAYS}天前的备份文件..."
    
    local old_backups=$(find ${BACKUP_DIR} -name "full_backup_*.sql.gz" -mtime +${RETENTION_DAYS})
    
    if [[ -n "$old_backups" ]]; then
        echo "$old_backups" | while read backup; do
            log "删除旧备份: $(basename $backup)"
            rm -f "$backup"
        done
        log "已清理 $(echo "$old_backups" | wc -l) 个旧备份文件"
    else
        log "没有需要清理的旧备份"
    fi
}

# 备份验证
verify_backup() {
    local backup_file=$1
    
    if [[ ! -f "$backup_file" ]]; then
        error_exit "备份文件不存在: $backup_file"
    fi
    
    log "验证备份文件完整性..."
    
    # 检查gzip文件完整性
    if ! gzip -t ${backup_file} 2>>${LOG_FILE}; then
        error_exit "备份文件损坏: $backup_file"
    fi
    
    # 检查文件大小
    local file_size=$(du -h ${backup_file} | cut -f1)
    log "备份文件验证通过 - 大小: ${file_size}"
    
    # 尝试列出备份中的数据库(可选,需要解压部分内容)
    log "备份内容预览:"
    zcat ${backup_file} | head -50 | grep -E "(Database:|CREATE DATABASE)" | head -10 >> ${LOG_FILE}
}

# 磁盘空间检查
check_disk_space() {
    local backup_dir=$1
    local required_space=1024  # 假设至少需要1GB空间
    
    local available_space=$(df ${backup_dir} | awk 'NR==2 {print $4}')
    available_space=$((available_space/1024))  # 转换为MB
    
    if [[ $available_space -lt $required_space ]]; then
        log "警告: 磁盘空间不足 - 可用: ${available_space}MB, 建议至少: ${required_space}MB"
        return 1
    else
        log "磁盘空间充足: ${available_space}MB 可用"
        return 0
    fi
}

# 生成备份报告
generate_report() {
    local status=$1
    local backup_file=$2
    
    local report_file="${BACKUP_DIR}/backup_report_${DATE_FORMAT}.txt"
    
    {
        echo "=== MySQL备份报告 ==="
        echo "时间: $(date)"
        echo "状态: $status"
        echo "备份文件: $(basename $backup_file 2>/dev/null || echo '无')"
        echo "文件大小: $(du -h $backup_file 2>/dev/null | cut -f1 || echo 'N/A')"
        echo "保留策略: ${RETENTION_DAYS}天"
        echo "日志文件: ${LOG_FILE}"
        echo "=== 报告结束 ==="
    } > ${report_file}
    
    log "备份报告已生成: ${report_file}"
}

# 主函数
main() {
    local backup_file=""
    
    log "=== MySQL备份任务开始 ==="
    
    # 检查磁盘空间
    check_disk_space ${BACKUP_DIR}
    
    # 检查MySQL连接
    check_mysql_connection
    
    # 执行备份
    if backup_file=$(perform_backup); then
        # 验证备份
        verify_backup "$backup_file"
        # 生成报告
        generate_report "成功" "$backup_file"
    else
        generate_report "失败" ""
        error_exit "备份过程失败"
    fi
    
    # 清理旧备份
    cleanup_old_backups
    
    log "备份任务完成: $(basename $backup_file)"
    log "=== MySQL备份任务结束 ===\n"
}

# 信号处理
trap 'log "备份被用户中断"; exit 1' INT TERM

# 执行主函数
main

四、设置脚本权限和定时任务

复制代码
# chmod +x /work/mysql/scripts/mysql_backup.sh
# chown root:root /work/mysql/scripts/mysql_backup.sh


创建日志目录
# mkdir -p /work/mysql
# touch /work/mysql/mysql_backup.log
# chmod 644 /work/mysql/mysql_backup.log


创建备份目录
# mkdir -p /work/mysql/mysql_backup
# chmod 755 /work/mysql/mysql_backup


添加定时任务
0 2 * * * /usr/bin/sh /work/mysql/scripts/mysql_backup.sh

五、备份账户权限说明

  • SELECT 读取数据
  • RELOAD 执行flush操作
  • LOCK TABLES 锁定表用于一致性备份
  • REPLICATION CLIENT 获取binlog位置
  • PROCESS 查看运行进程
  • EVENT 备份事件
  • TRIGGER 备份触发器

六、手动测试备份

复制代码
测试脚本
# /usr/bin/sh /work/mysql/scripts/mysql_backup.sh

查看备份文件
# ls /work/mysql/mysql_backup

查看日志
# cat /work/mysql/mysql_backup.log
相关推荐
铜峰叠翠2 小时前
Redis安装配置
数据库·redis·缓存
William_cl2 小时前
【连载1】《假装自己是个小白 —— 重新认识 MySQL》实践指南
android·mysql·oracle
脚踏实地,坚持不懈!2 小时前
Android,jetpack compose实现俄罗斯方块,简单案例♦️
android
Lbwnb丶3 小时前
JUnit 4 + Spring Boot 测试依赖
数据库·spring boot·junit
大筒木老辈子3 小时前
MySQL笔记---表的约束
数据库·笔记·mysql
涤生大数据3 小时前
从MR迁移到Spark3:数据倾斜与膨胀问题的实战优化
数据库·数据仓库·spark·mapreduce·大数据开发·数据倾斜·spark3
一直向钱3 小时前
android 字符串工具类(兼容 Android 16+ / API 16,无报错版)
android
加洛斯4 小时前
MySQL 函数篇(3):常用的时间日期函数
数据库·mysql