保存文件:mysql_backup_centos7.sh
执行:chmod +x mysql_backup_centos7.sh
手动执行:./mysql_backup_centos7.sh
下面的数据库密码是随机密码,请重新填写测试
通过定时任务触发脚本进行执行如:每5分钟执行一次
编辑:crontab -e
输入:*/5 * * * * /usr/shell/mysql_backup_centos7.sh
查看:crontab -l
查看日志:cat /var/log/cron
bash
#!/bin/bash
# mysql_backup_centos7.sh
# 功能:备份MySQL所有数据
# 使用:chmod +x mysql_backup_centos7.sh && ./mysql_backup_centos7.sh
# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 配置部分
MYSQL_USER="root"
MYSQL_PASSWORD="5mX2TtjmHOQWNpewXGOktA=="
BACKUP_DIR="/backup/mysql"
DATE_TAG=$(date +%Y%m%d)
BACKUP_TIME=$(date +%H%M%S)
RETENTION_DAYS=7
LOG_FILE="/var/log/mysql_backup_$(date +%Y%m%d_%H%M%S).log"
# 函数:记录日志
log_message() {
local level=$1
local message=$2
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo -e "${timestamp} [${level}] ${message}" | tee -a "$LOG_FILE"
}
# 函数:检查命令
check_command() {
if ! command -v $1 &> /dev/null; then
log_message "ERROR" "命令 $1 不存在"
return 1
fi
return 0
}
# 函数:检查MySQL连接
check_mysql_connection() {
log_message "INFO" "检查MySQL连接..."
# 如果密码为空,提示输入
if [ -z "$MYSQL_PASSWORD" ]; then
echo -e "${YELLOW}请输入MySQL root密码: ${NC}"
read -s MYSQL_PASSWORD
echo
fi
# 测试连接
if mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "SELECT 1;" &>/dev/null; then
log_message "SUCCESS" "MySQL连接成功"
return 0
else
log_message "ERROR" "MySQL连接失败"
return 1
fi
}
# 函数:创建备份目录
create_backup_dir() {
TODAY_BACKUP_DIR="${BACKUP_DIR}/${DATE_TAG}"
if [ ! -d "$BACKUP_DIR" ]; then
mkdir -p "$BACKUP_DIR" || {
log_message "ERROR" "创建备份目录失败: $BACKUP_DIR"
return 1
}
log_message "INFO" "创建备份目录: $BACKUP_DIR"
fi
if [ ! -d "$TODAY_BACKUP_DIR" ]; then
mkdir -p "$TODAY_BACKUP_DIR" || {
log_message "ERROR" "创建当天备份目录失败: $TODAY_BACKUP_DIR"
return 1
}
log_message "INFO" "创建当天备份目录: $TODAY_BACKUP_DIR"
fi
echo "$TODAY_BACKUP_DIR"
}
# 函数:备份数据库结构
backup_database_structure() {
local backup_dir=$1
log_message "INFO" "备份数据库结构..."
mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" --all-databases --no-data \
> "${backup_dir}/01_all_databases_structure_${BACKUP_TIME}.sql" 2>>"$LOG_FILE"
if [ $? -eq 0 ]; then
log_message "SUCCESS" "数据库结构备份完成"
return 0
else
log_message "ERROR" "数据库结构备份失败"
return 1
fi
}
# 函数:完整备份所有数据库
backup_all_databases() {
local backup_dir=$1
log_message "INFO" "完整备份所有数据库..."
mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" \
--all-databases \
--single-transaction \
--routines \
--triggers \
--events \
--add-drop-database \
> "${backup_dir}/02_all_databases_full_${BACKUP_TIME}.sql" 2>>"$LOG_FILE"
if [ $? -eq 0 ]; then
# 压缩备份文件
gzip "${backup_dir}/02_all_databases_full_${BACKUP_TIME}.sql"
log_message "SUCCESS" "完整数据库备份完成并已压缩"
return 0
else
log_message "ERROR" "完整数据库备份失败"
return 1
fi
}
# 函数:单独备份每个数据库
backup_each_database() {
local backup_dir=$1
log_message "INFO" "单独备份每个数据库..."
# 获取数据库列表(排除系统数据库)
DATABASES=$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "SHOW DATABASES;" 2>/dev/null | \
grep -Ev "(Database|information_schema|performance_schema|mysql|sys)")
if [ -z "$DATABASES" ]; then
log_message "WARNING" "没有找到用户数据库"
return 1
fi
local success_count=0
local fail_count=0
for DB in $DATABASES; do
log_message "INFO" "备份数据库: $DB"
# 备份单个数据库
mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" \
--databases "$DB" \
--single-transaction \
--routines \
--triggers \
> "${backup_dir}/03_${DB}_${BACKUP_TIME}.sql" 2>>"$LOG_FILE"
if [ $? -eq 0 ]; then
# 压缩备份文件
gzip "${backup_dir}/03_${DB}_${BACKUP_TIME}.sql"
log_message "SUCCESS" "数据库 $DB 备份完成"
success_count=$((success_count + 1))
else
log_message "ERROR" "数据库 $DB 备份失败"
fail_count=$((fail_count + 1))
fi
done
log_message "INFO" "数据库备份统计: 成功 $success_count 个, 失败 $fail_count 个"
return $fail_count
}
# 函数:备份用户权限
backup_user_grants() {
local backup_dir=$1
log_message "INFO" "备份MySQL用户权限..."
mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" --skip-column-names -A \
-e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user NOT IN ('mysql.sys','mysql.session','mysql.infoschema')" 2>/dev/null | \
mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" --skip-column-names -A 2>/dev/null | \
sed 's/$/;/g' > "${backup_dir}/04_mysql_grants_${BACKUP_TIME}.sql" 2>>"$LOG_FILE"
if [ $? -eq 0 ]; then
log_message "SUCCESS" "用户权限备份完成"
return 0
else
log_message "ERROR" "用户权限备份失败"
return 1
fi
}
# 函数:备份配置文件
backup_config_files() {
local backup_dir=$1
log_message "INFO" "备份MySQL配置文件..."
# 创建配置文件目录
CONFIG_DIR="${backup_dir}/config"
mkdir -p "$CONFIG_DIR"
local backed_up=0
# 备份主配置文件
if [ -f "/etc/my.cnf" ]; then
cp /etc/my.cnf "${CONFIG_DIR}/my.cnf"
log_message "INFO" "已备份: /etc/my.cnf"
backed_up=$((backed_up + 1))
fi
# 备份配置目录
if [ -d "/etc/my.cnf.d" ]; then
cp -r /etc/my.cnf.d "${CONFIG_DIR}/"
log_message "INFO" "已备份: /etc/my.cnf.d"
backed_up=$((backed_up + 1))
fi
# 备份日志文件(可选)
if [ -f "/var/log/mysqld.log" ]; then
cp /var/log/mysqld.log "${CONFIG_DIR}/mysqld.log"
log_message "INFO" "已备份: /var/log/mysqld.log"
backed_up=$((backed_up + 1))
fi
if [ $backed_up -gt 0 ]; then
log_message "SUCCESS" "配置文件备份完成 (共 $backed_up 个文件)"
return 0
else
log_message "WARNING" "未找到配置文件"
return 1
fi
}
# 函数:创建恢复脚本
create_restore_script() {
local backup_dir=$1
local backup_time=$2
cat > "${backup_dir}/restore_mysql.sh" << 'EOF'
#!/bin/bash
# MySQL恢复脚本
set -e
BACKUP_DIR=$(cd "$(dirname "$0")" && pwd)
echo "备份目录: $BACKUP_DIR"
# 显示备份文件
echo "可用的备份文件:"
echo "----------------------------------------"
ls -1 "$BACKUP_DIR"/*.gz 2>/dev/null | while read -r file; do
filename=$(basename "$file")
size=$(du -h "$file" | cut -f1)
echo " $filename ($size)"
done
echo "----------------------------------------"
# 选择备份文件
if [ $# -eq 1 ]; then
BACKUP_FILE="$1"
else
read -p "请输入要恢复的备份文件名: " BACKUP_FILE
fi
# 检查文件是否存在
if [ ! -f "${BACKUP_DIR}/${BACKUP_FILE}" ] && [ ! -f "$BACKUP_FILE" ]; then
echo "错误: 备份文件不存在"
exit 1
fi
if [ ! -f "$BACKUP_FILE" ]; then
BACKUP_FILE="${BACKUP_DIR}/${BACKUP_FILE}"
fi
echo "准备恢复数据库..."
echo "备份文件: $BACKUP_FILE"
# 获取MySQL信息
read -p "MySQL主机 (默认: localhost): " MYSQL_HOST
MYSQL_HOST=${MYSQL_HOST:-localhost}
read -p "MySQL端口 (默认: 3306): " MYSQL_PORT
MYSQL_PORT=${MYSQL_PORT:-3306}
read -p "MySQL用户名 (默认: root): " MYSQL_USER
MYSQL_USER=${MYSQL_USER:-root}
read -s -p "MySQL密码: " MYSQL_PASSWORD
echo
# 测试连接
echo "测试数据库连接..."
if ! mysql -h"$MYSQL_HOST" -P"$MYSQL_PORT" -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "SELECT 1;" &>/dev/null; then
echo "错误: 数据库连接失败"
exit 1
fi
# 确认恢复
echo -e "\n警告: 此操作将覆盖现有数据库数据!"
read -p "确认要恢复吗?(输入 'YES' 继续): " CONFIRM
if [ "$CONFIRM" != "YES" ]; then
echo "操作已取消"
exit 0
fi
# 执行恢复
echo "正在恢复数据库..."
start_time=$(date +%s)
gunzip -c "$BACKUP_FILE" | mysql -h"$MYSQL_HOST" -P"$MYSQL_PORT" -u"$MYSQL_USER" -p"$MYSQL_PASSWORD"
end_time=$(date +%s)
duration=$((end_time - start_time))
if [ $? -eq 0 ]; then
echo -e "\n✅ 数据库恢复成功!"
echo " 耗时: ${duration}秒"
echo " 备份文件: $(basename "$BACKUP_FILE")"
else
echo -e "\n❌ 数据库恢复失败!"
exit 1
fi
EOF
chmod +x "${backup_dir}/restore_mysql.sh"
log_message "INFO" "恢复脚本已创建: ${backup_dir}/restore_mysql.sh"
}
# 函数:清理旧备份
cleanup_old_backups() {
log_message "INFO" "清理 $RETENTION_DAYS 天前的旧备份..."
if [ -d "$BACKUP_DIR" ]; then
local deleted_count=0
find "$BACKUP_DIR" -maxdepth 1 -type d -name "2*" -mtime +$RETENTION_DAYS 2>/dev/null | while read -r old_dir; do
log_message "INFO" "删除旧备份: $old_dir"
rm -rf "$old_dir"
deleted_count=$((deleted_count + 1))
done
if [ $deleted_count -gt 0 ]; then
log_message "SUCCESS" "已清理 $deleted_count 个旧备份"
else
log_message "INFO" "没有需要清理的旧备份"
fi
fi
}
# 函数:显示备份报告
show_backup_report() {
local backup_dir=$1
local start_time=$2
local end_time=$(date +%s)
local duration=$((end_time - start_time))
# 计算备份大小
local backup_size=$(du -sh "$backup_dir" 2>/dev/null | awk '{print $1}')
local backup_count=$(find "$backup_dir" -name "*.gz" -o -name "*.sql" 2>/dev/null | wc -l)
echo -e "\n${GREEN}=== 备份完成报告 ===${NC}"
echo -e "${BLUE}备份目录:${NC} $backup_dir"
echo -e "${BLUE}备份时间:${NC} $(date '+%Y-%m-%d %H:%M:%S')"
echo -e "${BLUE}耗时:${NC} ${duration}秒"
echo -e "${BLUE}备份大小:${NC} ${backup_size:-0}"
echo -e "${BLUE}文件数量:${NC} ${backup_count}个"
echo -e "${BLUE}日志文件:${NC} $LOG_FILE"
# 显示备份文件列表
echo -e "\n${BLUE}备份文件列表:${NC}"
find "$backup_dir" -type f \( -name "*.gz" -o -name "*.sql" \) 2>/dev/null | sort | while read -r file; do
local size=$(du -h "$file" 2>/dev/null | cut -f1)
echo " $(basename "$file") (${size})"
done
echo -e "\n${GREEN}✅ 备份完成!${NC}"
}
# 主函数
main() {
echo -e "${GREEN}=== MySQL备份脚本 ===${NC}"
echo -e "开始时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo -e "备份目录: $BACKUP_DIR"
echo
local start_time=$(date +%s)
# 检查是否为root用户
if [ "$(id -u)" != "0" ]; then
echo -e "${RED}错误: 此脚本需要root权限${NC}"
exit 1
fi
# 检查mysqldump命令
if ! check_command "mysqldump"; then
echo -e "${RED}错误: mysqldump命令不存在,请先安装MySQL客户端${NC}"
exit 1
fi
# 检查MySQL连接
if ! check_mysql_connection; then
echo -e "${RED}错误: 无法连接到MySQL,请检查配置${NC}"
exit 1
fi
# 创建备份目录
TODAY_BACKUP_DIR=$(create_backup_dir)
if [ $? -ne 0 ]; then
exit 1
fi
# 执行备份
log_message "INFO" "开始备份MySQL数据..."
# 1. 备份数据库结构
backup_database_structure "$TODAY_BACKUP_DIR"
# 2. 完整备份所有数据库
backup_all_databases "$TODAY_BACKUP_DIR"
# 3. 单独备份每个数据库
backup_each_database "$TODAY_BACKUP_DIR"
# 4. 备份用户权限
backup_user_grants "$TODAY_BACKUP_DIR"
# 5. 备份配置文件
backup_config_files "$TODAY_BACKUP_DIR"
# 6. 创建恢复脚本
create_restore_script "$TODAY_BACKUP_DIR" "$BACKUP_TIME"
# 7. 清理旧备份
cleanup_old_backups
# 显示报告
show_backup_report "$TODAY_BACKUP_DIR" "$start_time"
return 0
}
# 执行主函数
main