本文目录导读:

是的,我写过类似的脚本,这是一个常见的运维需求,下面是一个完整的 Bash 脚本示例,实现自动备份 MySQL 数据库并上传到 FTP 服务器。
完整脚本示例
#!/bin/bash
# MySQL 备份脚本 - 自动备份并上传到 FTP
# ====== 配置参数 ======
# MySQL 连接信息
MYSQL_USER="root"
MYSQL_PASSWORD="your_password"
MYSQL_HOST="localhost"
MYSQL_PORT=3306
# 备份文件配置
BACKUP_DIR="/tmp/mysql_backup" # 临时备份目录
DATE=$(date +%Y%m%d_%H%M%S) # 时间戳
KEEP_DAYS=7 # 本地保留天数
# FTP 配置
FTP_HOST="ftp.example.com"
FTP_USER="ftp_user"
FTP_PASSWORD="ftp_password"
FTP_DIR="/backup/mysql" # FTP 上的目录
# ====== 初始化 ======
# 创建临时备份目录
mkdir -p "$BACKUP_DIR"
# 获取所有数据库列表(排除系统数据库)
DATABASES=$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -P"$MYSQL_PORT" \
-e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql|sys)")
# ====== 备份函数 ======
backup_database() {
local db_name="$1"
local backup_file="${BACKUP_DIR}/${db_name}_${DATE}.sql.gz"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始备份数据库: $db_name"
# 使用 mysqldump 备份并压缩
if mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -P"$MYSQL_PORT" \
--single-transaction --routines --triggers --events "$db_name" | gzip > "$backup_file"; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 数据库 $db_name 备份完成"
echo "$backup_file"
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 数据库 $db_name 备份失败" >&2
return 1
fi
}
# ====== FTP 上传函数 ======
upload_to_ftp() {
local local_file="$1"
local ftp_file=$(basename "$local_file")
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始上传到 FTP: $ftp_file"
# 使用 ftp 命令上传(需要安装 ftp 客户端)
ftp -inv "$FTP_HOST" <<EOF
user $FTP_USER $FTP_PASSWORD
binary
cd $FTP_DIR
put $local_file $ftp_file
bye
EOF
if [ $? -eq 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] FTP 上传成功: $ftp_file"
return 0
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] FTP 上传失败: $ftp_file" >&2
return 1
fi
}
# ====== 清理本地旧文件 ======
cleanup_local() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 清理 $KEEP_DAYS 天前的本地备份文件"
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$KEEP_DAYS -delete
local deleted_count=$(find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$KEEP_DAYS | wc -l)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 清理完成,删除 $deleted_count 个文件"
}
# ====== 主程序 ======
main() {
echo "=========================================="
echo "MySQL 自动备份开始于 $(date '+%Y-%m-%d %H:%M:%S')"
echo "=========================================="
# 备份所有数据库
backup_files=()
for db in $DATABASES; do
if file_path=$(backup_database "$db"); then
backup_files+=("$file_path")
else
echo "[ERROR] 备份 $db 失败" >&2
fi
done
# 上传到 FTP
if [ ${#backup_files[@]} -gt 0 ]; then
echo ""
echo "准备上传 ${#backup_files[@]} 个备份文件到 FTP..."
for file in "${backup_files[@]}"; do
if upload_to_ftp "$file"; then
echo "上传成功: $(basename $file)"
else
echo "[ERROR] 上传失败: $(basename $file)" >&2
fi
done
else
echo "[WARNING] 没有备份文件需要上传" >&2
fi
# 清理本地旧文件
cleanup_local
echo "=========================================="
echo "备份任务完成于 $(date '+%Y-%m-%d %H:%M:%S')"
echo "=========================================="
}
# 执行主程序
main
使用方法
配置脚本
修改脚本开头的配置参数:
- MySQL 连接信息
- FTP 服务器信息
- 备份目录和保留天数
设置执行权限
chmod +x mysql_backup.sh
测试运行
./mysql_backup.sh
设置定时任务(使用 crontab)
# 每天凌晨2点执行备份 0 2 * * * /path/to/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1
脚本特性
- 自动备份所有非系统数据库
- 使用 gzip 压缩减少文件体积
- 支持 FTP 上传
- 自动清理本地旧文件
- 详细的日志输出
- 错误处理
注意事项
- 安全性:建议将密码存储在环境变量或配置文件中,而不是直接写在脚本里
- 网络问题:FTP 上传可能因网络问题失败,可以考虑添加重试机制
- 权限:MySQL 用户需要拥有足够的权限(SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER 等)
- FTP 目录:确保 FTP 目录存在且有写入权限
如果你需要更高级的功能(如增量备份、加密备份、多线程上传等),我可以提供优化版本。