MySQL全实例备份脚本 (用于从库部署)

下面是一个专为生产环境设计的MySQL全实例备份脚本,可用于后续部署从库。此脚本包含了适合主从部署的关键参数、安全措施和自动化管理功能。

sql 复制代码
#!/bin/bash
# ===============================================
# MySQL生产环境全实例备份脚本 (用于从库部署)
# 版本: 2.0
# 功能: 全量备份所有数据库,包含复制配置信息
# ===============================================

# ------ 配置区域 (根据实际环境修改) ------
# MySQL连接配置 (推荐使用配置文件避免密码明文)
MYSQL_USER="backup_user"                     # 备份专用用户
MYSQL_CNF="/etc/mysql/backup.cnf"            # MySQL配置文件(存储认证信息)
MYSQL_HOST="localhost"                       # MySQL主机地址
MYSQL_PORT="3306"                            # MySQL端口

# 备份路径配置
BACKUP_BASE_DIR="/data/mysql_backup"         # 备份根目录
BACKUP_DIR="${BACKUP_BASE_DIR}/full_$(date +%Y%m%d_%H%M%S)"  # 本次备份目录

# 备份保留策略
RETENTION_DAYS=7                             # 备份保留天数

# 日志配置
LOG_FILE="${BACKUP_BASE_DIR}/backup.log"     # 日志文件路径

# ------ 函数定义 ------
# 记录日志功能
log_message() {
    local level=$1
    local message=$2
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] [$level] $message" | tee -a "${LOG_FILE}"
}

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

# 检查命令执行结果
check_result() {
    if [ $? -ne 0 ]; then
        error_exit "$1"
    fi
}

# 检查备份文件完整性
verify_backup() {
    local backup_file=$1
    log_message "INFO" "验证备份文件完整性: $backup_file"
    
    # 检查文件大小
    local file_size=$(stat -c%s "$backup_file" 2>/dev/null || stat -f%z "$backup_file")
    if [ "$file_size" -lt 1024 ]; then
        error_exit "备份文件过小,可能备份失败"
    fi
    
    # 检查文件是否包含正常的SQL结构
    if ! gzip -dc "$backup_file" | head -100 | grep -q "MySQL dump"; then
        error_exit "备份文件格式异常"
    fi
    log_message "INFO" "备份文件验证通过"
}

# 检查MySQL连接
check_mysql_connection() {
    log_message "INFO" "检查MySQL连接..."
    mysql --defaults-file="${MYSQL_CNF}" -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -e "SELECT 1;" >/dev/null 2>&1
    check_result "MySQL连接失败,请检查配置和网络连接"
    log_message "INFO" "MySQL连接成功"
}

# 创建备份目录
create_backup_dir() {
    log_message "INFO" "创建备份目录: ${BACKUP_DIR}"
    mkdir -p "${BACKUP_DIR}"
    check_result "无法创建备份目录"
    chmod 750 "${BACKUP_DIR}"
}

# 执行全量备份
perform_backup() {
    local backup_file="${BACKUP_DIR}/full_backup.sql.gz"
    log_message "INFO" "开始执行MySQL全实例备份..."
    
    # 关键备份参数说明:
    # --all-databases:      备份所有数据库
    # --single-transaction: 对InnoDB使用一致性快照(不锁表)
    # --master-data=2:      记录主库binlog位置(用于从库搭建)
    # --routines:           备份存储过程和函数
    # --events:             备份事件调度器
    # --triggers:           备份触发器
    # --flush-logs:         备份前刷新日志(便于增量管理)
    # --set-gtid-purged=OFF:控制GTID输出,部署从库时可能需要调整
    
    mysqldump --defaults-file="${MYSQL_CNF}" \
        --host="${MYSQL_HOST}" \
        --port="${MYSQL_PORT}" \
        --all-databases \
        --single-transaction \
        --master-data=2 \
        --routines \
        --events \
        --triggers \
        --flush-logs \
        --set-gtid-purged=OFF \
        --max-allowed-packet=1G \
        --hex-blob \
        --default-character-set=utf8mb4 | gzip > "$backup_file"
    
    check_result "mysqldump备份执行失败"
    log_message "INFO" "全量备份完成: ${backup_file}"
    echo "$backup_file"  # 返回备份文件路径
}

# 备份MySQL配置
backup_mysql_config() {
    log_message "INFO" "备份MySQL配置文件..."
    local config_files=(
        "/etc/my.cnf"
        "/etc/mysql/my.cnf"
        "/usr/etc/my.cnf"
        "~/.my.cnf"
    )
    
    for config in "${config_files[@]}"; do
        if [ -f "$config" ]; then
            cp "$config" "${BACKUP_DIR}/" 2>/dev/null && \
            log_message "INFO" "已备份配置: $config"
        fi
    done
}

# 记录复制位置信息
record_replication_info() {
    log_message "INFO" "记录复制位置信息..."
    mysql --defaults-file="${MYSQL_CNF}" -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -e "SHOW MASTER STATUS\G" > "${BACKUP_DIR}/master_status.txt" 2>/dev/null
    mysql --defaults-file="${MYSQL_CNF}" -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -e "SHOW VARIABLES LIKE 'gtid_mode'" > "${BACKUP_DIR}/gtid_info.txt" 2>/dev/null
}

# 清理旧备份
cleanup_old_backups() {
    log_message "INFO" "清理${RETENTION_DAYS}天前的旧备份..."
    find "${BACKUP_BASE_DIR}" -name "full_*" -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} \; 2>/dev/null
    local cleaned_count=$?
    if [ "$cleaned_count" -eq 0 ]; then
        log_message "INFO" "旧备份清理完成"
    else
        log_message "WARN" "旧备份清理过程中可能存在问题"
    fi
}

# 生成恢复指南
generate_recovery_guide() {
    cat > "${BACKUP_DIR}/RESTORE_GUIDE.md" << 'EOF'
# 从库部署恢复指南

## 1. 准备环境
- 确保目标MySQL版本与源库一致
- 清理目标实例数据

## 2. 恢复数据

gzip -d full_backup.sql.gz

导入数据

mysql -h <target_host> -u root -p < full_backup.sql

复制

3. 配置复制

备份文件中已包含主库binlog位置信息:

sql 复制代码
-- 查看binlog位置(在备份文件头部)

CHANGE MASTER TO

MASTER_HOST='source_host_ip',

MASTER_USER='repl_user',

MASTER_PASSWORD='repl_password',

MASTER_LOG_FILE='mysql-bin.XXXXXX',

MASTER_LOG_POS=XXX;

4. 启动复制

sql 复制代码
START SLAVE;

SHOW SLAVE STATUS\G

------ 主程序执行 ------

sql 复制代码
main() {
    log_message "INFO" "=== MySQL全实例备份开始 ==="
    
    # 前置检查
    check_mysql_connection
    create_backup_dir
    
    # 执行备份
    local backup_file
    backup_file=$(perform_backup)
    
    # 备份后操作
    verify_backup "$backup_file"
    backup_mysql_config
    record_replication_info
    generate_recovery_guide
    
    # 计算备份大小
    local backup_size
    backup_size=$(du -sh "${BACKUP_DIR}" | cut -f1)
    log_message "INFO" "备份完成! 大小: ${backup_size}, 位置: ${BACKUP_DIR}"
    
    # 清理旧备份
    cleanup_old_backups
    
    log_message "INFO" "=== MySQL全实例备份结束 ==="
}

# 异常处理
trap 'log_message "ERROR" "脚本执行被中断"; exit 2' INT TERM

执行主程序

配置与使用说明

前期准备

创建MySQL备份专用用户:

sql 复制代码
-- 创建备份专用用户并授权
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION CLIENT, SHOW VIEW, EVENT, TRIGGER ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;

创建MySQL配置文件(避免密码明文):

sql 复制代码
sudo mkdir -p /etc/mysql
sudo tee /etc/mysql/backup.cnf > /dev/null << EOF
[client]
user=backup_user
password=your_strong_password
host=localhost
port=3306
EOF
sudo chmod 600 /etc/mysql/backup.cnf

2. 脚本部署

保存脚本并赋予执行权限

sql 复制代码
chmod +x mysql_full_backup.sh
创建备份目录
sql 复制代码
mkdir -p /data/mysql_backup

测试运行

sql 复制代码
./mysql_full_backup.sh

3. 设置定时任务(每日凌晨2点执行)

sql 复制代码
# 编辑定时任务
crontab -e
sql 复制代码
# 添加以下行:
0 2 * * * /path/to/mysql_full_backup.sh >> /data/mysql_backup/backup.log 2>&1
相关推荐
大学生资源网2 小时前
基于springboot的南京特色美食小吃商城(源码+文档)
java·spring boot·后端·mysql·毕业设计·源码
半路_出家ren2 小时前
Python操作MySQL(详细版)
运维·开发语言·数据库·python·mysql·网络安全·wireshark
luoluoal2 小时前
基于python的机器学习的文本分类系统(源码+文档)
python·mysql·django·毕业设计·源码
共享家95272 小时前
MYSQL-内外连接
开发语言·数据库·mysql
sxlishaobin11 小时前
MySQL- explain
数据库·mysql
源代码•宸11 小时前
Leetcode—620. 有趣的电影&&Q3. 有趣的电影【简单】
数据库·后端·mysql·算法·leetcode·职场和发展
快乐肚皮12 小时前
MySQL递归CTE
java·数据库·mysql·递归表达式
中國移动丶移不动12 小时前
Python MySQL 数据库操作完整示例
数据库·python·mysql
zhcf17 小时前
【MySQL】聚簇索引与非聚簇索引
数据库·mysql