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
相关推荐
倔强的石头_1 天前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
阿巴斯甜1 天前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab2 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android