下面是一个专为生产环境设计的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