Shell腳本實現(xiàn)自動備份網(wǎng)站和數(shù)據(jù)庫并上傳到云存儲
1. 備份方案概述
在本教程中,我們將創(chuàng)建一個完整的自動化備份系統(tǒng),用于備份網(wǎng)站文件和數(shù)據(jù)庫,并將備份文件上傳到云存儲。該系統(tǒng)包含錯誤處理、日志記錄和通知功能,適合生產(chǎn)環(huán)境使用。

2. 環(huán)境準備和依賴安裝
2.1 系統(tǒng)要求檢查
首先創(chuàng)建環(huán)境檢查腳本:
#!/bin/bash
# check_environment.sh
echo "檢查系統(tǒng)環(huán)境..."
# 檢查操作系統(tǒng)
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$NAME
VER=$VERSION_ID
echo "操作系統(tǒng): $OS $VER"
else
echo "警告: 無法檢測操作系統(tǒng)版本"
fi
# 檢查磁盤空間
echo "磁盤空間信息:"
df -h / /tmp /var
# 檢查必要的工具
required_tools=("tar" "gzip" "mysql" "pg_dump" "curl")
for tool in "${required_tools[@]}"; do
if command -v $tool &> /dev/null; then
echo "? $tool 已安裝"
else
echo "? $tool 未安裝"
fi
done
# 檢查云存儲工具
cloud_tools=("aws" "gsutil" "ossutil")
for tool in "${cloud_tools[@]}"; do
if command -v $tool &> /dev/null; then
echo "? $tool 已安裝"
else
echo "? $tool 未安裝 (可選)"
fi
done
2.2 安裝必要的軟件包
根據(jù)不同的Linux發(fā)行版安裝所需軟件:
#!/bin/bash
# install_dependencies.sh
echo "安裝備份所需的軟件包..."
# 檢測發(fā)行版
if [ -f /etc/redhat-release ]; then
# CentOS/RHEL
sudo yum update -y
sudo yum install -y tar gzip mysql-server postgresql curl python3-pip
elif [ -f /etc/debian_version ]; then
# Ubuntu/Debian
sudo apt update
sudo apt install -y tar gzip mysql-client postgresql-client curl python3-pip
else
echo "不支持的Linux發(fā)行版"
exit 1
fi
# 安裝云存儲CLI工具
echo "安裝AWS CLI..."
pip3 install awscli --upgrade --user
echo "安裝Google Cloud SDK..."
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
echo "安裝阿里云OSS工具..."
wget -O ossutil64 https://gosspublic.alicdn.com/ossutil/1.7.14/ossutil64
chmod 755 ossutil64
sudo mv ossutil64 /usr/local/bin/ossutil
3. 配置文件設(shè)置
創(chuàng)建主配置文件:
#!/bin/bash
# config/backup.conf
# 備份配置
BACKUP_DIR="/opt/backups"
LOG_DIR="/var/log/backups"
RETENTION_DAYS=30
COMPRESSION_LEVEL=6
# 網(wǎng)站文件配置
WEB_ROOT="/var/www/html"
EXCLUDE_PATTERNS=("*.log" "*.tmp" "cache/*" "tmp/*")
# 數(shù)據(jù)庫配置
# MySQL
MYSQL_HOST="localhost"
MYSQL_PORT="3306"
MYSQL_USER="backup_user"
MYSQL_PASSWORD="your_secure_password"
MYSQL_DATABASES=("wordpress" "mydatabase" "application_db")
# PostgreSQL
PG_HOST="localhost"
PG_PORT="5432"
PG_USER="backup_user"
PG_PASSWORD="your_secure_password"
PG_DATABASES=("app_production" "analytics_db")
# 云存儲配置
# AWS S3
AWS_BUCKET="my-backup-bucket"
AWS_REGION="us-east-1"
# Google Cloud Storage
GCS_BUCKET="my-backup-bucket"
# 阿里云OSS
OSS_BUCKET="my-backup-bucket"
OSS_ENDPOINT="oss-cn-hangzhou.aliyuncs.com"
# 通知配置
EMAIL_RECIPIENT="admin@example.com"
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/your/webhook/url"
創(chuàng)建數(shù)據(jù)庫用戶配置腳本:
#!/bin/bash # setup_database_users.sh echo "設(shè)置數(shù)據(jù)庫備份用戶..." # MySQL備份用戶設(shè)置 mysql -u root -p <<EOF -- 創(chuàng)建備份用戶 CREATE USER IF NOT EXISTS 'backup_user'@'localhost' IDENTIFIED BY 'your_secure_password'; -- 授予必要權(quán)限 GRANT SELECT, LOCK TABLES, SHOW VIEW, PROCESS ON *.* TO 'backup_user'@'localhost'; -- 刷新權(quán)限 FLUSH PRIVILEGES; -- 顯示用戶權(quán)限 SHOW GRANTS FOR 'backup_user'@'localhost'; EOF # PostgreSQL備份用戶設(shè)置 sudo -u postgres psql <<EOF -- 創(chuàng)建備份用戶 CREATE USER backup_user WITH PASSWORD 'your_secure_password'; -- 授予必要權(quán)限 ALTER USER backup_user WITH SUPERUSER; -- 顯示用戶信息 \du backup_user EOF echo "數(shù)據(jù)庫備份用戶設(shè)置完成"
4. 核心備份腳本
創(chuàng)建主備份腳本:
#!/bin/bash
# website_backup.sh
# 加載配置
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/config/backup.conf"
# 設(shè)置變量
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="backup_${TIMESTAMP}"
BACKUP_PATH="${BACKUP_DIR}/${BACKUP_NAME}"
LOG_FILE="${LOG_DIR}/backup_${TIMESTAMP}.log"
# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函數(shù)
log() {
local level=$1
local message=$2
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo -e "${timestamp} [${level}] ${message}" | tee -a "$LOG_FILE"
}
log_info() {
log "INFO" "${BLUE}$1${NC}"
}
log_success() {
log "SUCCESS" "${GREEN}$1${NC}"
}
log_warning() {
log "WARNING" "${YELLOW}$1${NC}"
}
log_error() {
log "ERROR" "${RED}$1${NC}"
}
# 錯誤處理函數(shù)
error_exit() {
log_error "$1"
send_notification "備份失敗" "$1"
exit 1
}
# 通知函數(shù)
send_notification() {
local subject=$1
local message=$2
# 郵件通知
if command -v mail &> /dev/null && [ -n "$EMAIL_RECIPIENT" ]; then
echo "$message" | mail -s "Backup Alert: $subject" "$EMAIL_RECIPIENT"
fi
# Slack通知
if command -v curl &> /dev/null && [ -n "$SLACK_WEBHOOK_URL" ]; then
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"*Backup Alert*: $subject\n$message\"}" \
"$SLACK_WEBHOOK_URL" > /dev/null 2>&1
fi
}
# 初始化備份環(huán)境
init_backup() {
log_info "初始化備份環(huán)境..."
# 創(chuàng)建目錄
mkdir -p "$BACKUP_DIR" "$LOG_DIR" "$BACKUP_PATH"
# 檢查目錄權(quán)限
if [ ! -w "$BACKUP_DIR" ]; then
error_exit "備份目錄不可寫: $BACKUP_DIR"
fi
if [ ! -r "$WEB_ROOT" ]; then
error_exit "網(wǎng)站目錄不可讀: $WEB_ROOT"
fi
log_success "備份環(huán)境初始化完成"
}
# 備份網(wǎng)站文件
backup_website_files() {
log_info "開始備份網(wǎng)站文件..."
local exclude_args=()
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
exclude_args+=(--exclude="$pattern")
done
cd "$WEB_ROOT" || error_exit "無法進入網(wǎng)站目錄: $WEB_ROOT"
# 創(chuàng)建文件列表
find . -type f > "${BACKUP_PATH}/file_list.txt"
# 打包網(wǎng)站文件
if tar czf "${BACKUP_PATH}/website_files.tar.gz" \
"${exclude_args[@]}" \
. > /dev/null 2>&1; then
local size=$(du -h "${BACKUP_PATH}/website_files.tar.gz" | cut -f1)
log_success "網(wǎng)站文件備份完成: ${size}"
else
error_exit "網(wǎng)站文件備份失敗"
fi
}
# 備份MySQL數(shù)據(jù)庫
backup_mysql_databases() {
log_info "開始備份MySQL數(shù)據(jù)庫..."
# 測試MySQL連接
if ! mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "SELECT 1" > /dev/null 2>&1; then
log_warning "MySQL連接失敗,跳過MySQL備份"
return 1
fi
# 獲取數(shù)據(jù)庫列表
local databases
databases=$(mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql|sys)")
local success_count=0
local total_count=0
for db in $databases; do
# 檢查數(shù)據(jù)庫是否在配置列表中
if [[ " ${MYSQL_DATABASES[@]} " =~ " ${db} " ]] || [ ${#MYSQL_DATABASES[@]} -eq 0 ]; then
((total_count++))
log_info "備份MySQL數(shù)據(jù)庫: $db"
if mysqldump -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" \
--single-transaction \
--routines \
--triggers \
"$db" > "${BACKUP_PATH}/mysql_${db}.sql" 2>> "$LOG_FILE"; then
# 壓縮備份文件
gzip "${BACKUP_PATH}/mysql_${db}.sql"
((success_count++))
log_success "MySQL數(shù)據(jù)庫備份完成: $db"
else
log_error "MySQL數(shù)據(jù)庫備份失敗: $db"
fi
fi
done
log_success "MySQL備份完成: ${success_count}/${total_count} 個數(shù)據(jù)庫"
}
# 備份PostgreSQL數(shù)據(jù)庫
backup_postgresql_databases() {
log_info "開始備份PostgreSQL數(shù)據(jù)庫..."
# 設(shè)置密碼
export PGPASSWORD="$PG_PASSWORD"
# 測試PostgreSQL連接
if ! psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -d postgres -c "SELECT 1" > /dev/null 2>&1; then
log_warning "PostgreSQL連接失敗,跳過PostgreSQL備份"
return 1
fi
local success_count=0
local total_count=0
for db in "${PG_DATABASES[@]}"; do
((total_count++))
log_info "備份PostgreSQL數(shù)據(jù)庫: $db"
if pg_dump -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" \
--verbose \
--no-password \
"$db" > "${BACKUP_PATH}/pgsql_${db}.sql" 2>> "$LOG_FILE"; then
# 壓縮備份文件
gzip "${BACKUP_PATH}/pgsql_${db}.sql"
((success_count++))
log_success "PostgreSQL數(shù)據(jù)庫備份完成: $db"
else
log_error "PostgreSQL數(shù)據(jù)庫備份失敗: $db"
fi
done
log_success "PostgreSQL備份完成: ${success_count}/${total_count} 個數(shù)據(jù)庫"
}
# 創(chuàng)建備份清單
create_backup_manifest() {
log_info "創(chuàng)建備份清單..."
cat > "${BACKUP_PATH}/manifest.json" << EOF
{
"backup_name": "${BACKUP_NAME}",
"timestamp": "${TIMESTAMP}",
"created_at": "$(date -Iseconds)",
"components": {
"website_files": "$(if [ -f "${BACKUP_PATH}/website_files.tar.gz" ]; then echo "true"; else echo "false"; fi)",
"mysql_databases": "$(ls "${BACKUP_PATH}"/mysql_*.sql.gz 2>/dev/null | wc -l)",
"postgresql_databases": "$(ls "${BACKUP_PATH}"/pgsql_*.sql.gz 2>/dev/null | wc -l)"
},
"system_info": {
"hostname": "$(hostname)",
"disk_usage": "$(df -h / | awk 'NR==2 {print $5}')"
}
}
EOF
log_success "備份清單創(chuàng)建完成"
}
# 壓縮備份文件
compress_backup() {
log_info "壓縮備份文件..."
cd "$BACKUP_DIR" || error_exit "無法進入備份目錄"
if tar czf "${BACKUP_NAME}.tar.gz" "$BACKUP_NAME" > /dev/null 2>&1; then
local final_size=$(du -h "${BACKUP_NAME}.tar.gz" | cut -f1)
log_success "備份文件壓縮完成: ${final_size}"
# 清理臨時文件
rm -rf "$BACKUP_PATH"
else
error_exit "備份文件壓縮失敗"
fi
}
# 上傳到云存儲
upload_to_cloud() {
log_info "開始上傳到云存儲..."
local backup_file="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
# 上傳到AWS S3
if command -v aws &> /dev/null && [ -n "$AWS_BUCKET" ]; then
log_info "上傳到AWS S3..."
if aws s3 cp "$backup_file" "s3://${AWS_BUCKET}/${BACKUP_NAME}.tar.gz" --region "$AWS_REGION" >> "$LOG_FILE" 2>&1; then
log_success "上傳到AWS S3完成"
else
log_error "上傳到AWS S3失敗"
fi
fi
# 上傳到Google Cloud Storage
if command -v gsutil &> /dev/null && [ -n "$GCS_BUCKET" ]; then
log_info "上傳到Google Cloud Storage..."
if gsutil cp "$backup_file" "gs://${GCS_BUCKET}/${BACKUP_NAME}.tar.gz" >> "$LOG_FILE" 2>&1; then
log_success "上傳到Google Cloud Storage完成"
else
log_error "上傳到Google Cloud Storage失敗"
fi
fi
# 上傳到阿里云OSS
if command -v ossutil &> /dev/null && [ -n "$OSS_BUCKET" ]; then
log_info "上傳到阿里云OSS..."
if ossutil cp "$backup_file" "oss://${OSS_BUCKET}/${BACKUP_NAME}.tar.gz" -e "$OSS_ENDPOINT" >> "$LOG_FILE" 2>&1; then
log_success "上傳到阿里云OSS完成"
else
log_error "上傳到阿里云OSS失敗"
fi
fi
}
# 清理舊備份
cleanup_old_backups() {
log_info "清理舊備份文件..."
local local_count=0
local cloud_count=0
# 清理本地備份
find "$BACKUP_DIR" -name "backup_*.tar.gz" -type f -mtime +$RETENTION_DAYS | while read -r file; do
rm -f "$file"
((local_count++))
done
# 清理云存儲備份 (AWS S3示例)
if command -v aws &> /dev/null && [ -n "$AWS_BUCKET" ]; then
aws s3 ls "s3://${AWS_BUCKET}/" | grep "backup_" | while read -r date time size file; do
local backup_date=$(echo "$file" | cut -d'_' -f2)
local current_ts=$(date +%s)
local backup_ts=$(date -d "${backup_date:0:8} ${backup_date:9:2}:${backup_date:11:2}:${backup_date:13:2}" +%s 2>/dev/null || echo 0)
local age_days=$(( (current_ts - backup_ts) / 86400 ))
if [ $age_days -gt $RETENTION_DAYS ]; then
aws s3 rm "s3://${AWS_BUCKET}/$file"
((cloud_count++))
fi
done
fi
log_success "清理完成: 本地${local_count}個, 云存儲${cloud_count}個備份文件"
}
# 生成備份報告
generate_report() {
local end_time=$(date +%s)
local duration=$((end_time - ${START_TIME}))
cat > "${BACKUP_DIR}/backup_report_${TIMESTAMP}.txt" << EOF
備份報告
========
備份名稱: ${BACKUP_NAME}
開始時間: $(date -d @${START_TIME} '+%Y-%m-%d %H:%M:%S')
結(jié)束時間: $(date -d @${end_time} '+%Y-%m-%d %H:%M:%S')
持續(xù)時間: ${duration} 秒
備份組件:
- 網(wǎng)站文件: $(if [ -f "${BACKUP_DIR}/${BACKUP_NAME}.tar.gz" ]; then echo "成功"; else echo "失敗"; fi)
- MySQL數(shù)據(jù)庫: $(ls "${BACKUP_DIR}" | grep "mysql_.*\.sql.gz" | wc -l) 個
- PostgreSQL數(shù)據(jù)庫: $(ls "${BACKUP_DIR}" | grep "pgsql_.*\.sql.gz" | wc -l) 個
存儲信息:
- 本地備份: ${BACKUP_DIR}/${BACKUP_NAME}.tar.gz
- 云存儲: $(if [ -n "$AWS_BUCKET" ] || [ -n "$GCS_BUCKET" ] || [ -n "$OSS_BUCKET" ]; then echo "已上傳"; else echo "未配置"; fi)
錯誤日志: $LOG_FILE
EOF
}
# 主函數(shù)
main() {
START_TIME=$(date +%s)
log_info "=== 開始備份任務(wù) ==="
# 執(zhí)行備份流程
init_backup
backup_website_files
backup_mysql_databases
backup_postgresql_databases
create_backup_manifest
compress_backup
upload_to_cloud
cleanup_old_backups
# 生成報告
generate_report
local end_time=$(date +%s)
local duration=$((end_time - START_TIME))
log_success "=== 備份任務(wù)完成 ==="
log_success "總耗時: ${duration} 秒"
# 發(fā)送成功通知
send_notification "備份完成" "備份任務(wù) ${BACKUP_NAME} 已完成,耗時 ${duration} 秒"
}
# 信號處理
trap 'log_error "備份被用戶中斷"; exit 1' INT TERM
# 執(zhí)行主函數(shù)
main "$@"
5. 自動化部署腳本
創(chuàng)建安裝和部署腳本:
#!/bin/bash
# deploy_backup_system.sh
set -e
echo "開始部署自動化備份系統(tǒng)..."
# 創(chuàng)建目錄結(jié)構(gòu)
echo "創(chuàng)建目錄結(jié)構(gòu)..."
sudo mkdir -p /opt/backups/{config,scripts,logs}
sudo mkdir -p /var/log/backups
# 復(fù)制腳本文件
echo "復(fù)制腳本文件..."
sudo cp website_backup.sh /opt/backups/scripts/
sudo cp config/backup.conf /opt/backups/config/
sudo cp check_environment.sh /opt/backups/scripts/
# 設(shè)置權(quán)限
echo "設(shè)置權(quán)限..."
sudo chmod +x /opt/backups/scripts/*.sh
sudo chmod 600 /opt/backups/config/backup.conf
# 設(shè)置配置文件權(quán)限
sudo chown root:root /opt/backups/config/backup.conf
sudo chmod 400 /opt/backups/config/backup.conf
# 創(chuàng)建備份用戶
echo "創(chuàng)建備份用戶..."
if ! id "backupuser" &>/dev/null; then
sudo useradd -r -s /bin/bash -d /opt/backups backupuser
fi
# 設(shè)置目錄所有權(quán)
sudo chown -R backupuser:backupuser /opt/backups
sudo chown -R backupuser:backupuser /var/log/backups
# 配置日志輪轉(zhuǎn)
echo "配置日志輪轉(zhuǎn)..."
sudo tee /etc/logrotate.d/backups > /dev/null <<EOF
/var/log/backups/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 backupuser backupuser
}
EOF
echo "部署完成!"
6. 定時任務(wù)配置
創(chuàng)建crontab配置:
#!/bin/bash # setup_cron.sh echo "配置定時任務(wù)..." # 備份crontab sudo cp /etc/crontab /etc/crontab.backup.$(date +%Y%m%d) # 添加每日備份任務(wù) (凌晨2點) echo "0 2 * * * backupuser /opt/backups/scripts/website_backup.sh >> /var/log/backups/cron.log 2>&1" | sudo tee -a /etc/crontab # 添加每周完整備份 (周日凌晨1點) echo "0 1 * * 0 backupuser /opt/backups/scripts/website_backup.sh >> /var/log/backups/cron.log 2>&1" | sudo tee -a /etc/crontab # 添加監(jiān)控檢查 (每小時) echo "0 * * * * backupuser /opt/backups/scripts/check_environment.sh >> /var/log/backups/monitor.log 2>&1" | sudo tee -a /etc/crontab # 重新加載cron sudo systemctl reload crond echo "定時任務(wù)配置完成" echo "當(dāng)前crontab配置:" sudo crontab -l
7. 監(jiān)控和驗證腳本
創(chuàng)建備份驗證腳本:
#!/bin/bash
# verify_backup.sh
source /opt/backups/config/backup.conf
echo "開始驗證備份完整性..."
# 檢查最新備份文件
latest_backup=$(ls -t ${BACKUP_DIR}/backup_*.tar.gz 2>/dev/null | head -1)
if [ -z "$latest_backup" ]; then
echo "錯誤: 未找到備份文件"
exit 1
fi
echo "驗證備份文件: $latest_backup"
# 檢查文件大小
file_size=$(du -h "$latest_backup" | cut -f1)
echo "備份文件大小: $file_size"
# 檢查文件完整性
if tar tzf "$latest_backup" > /dev/null 2>&1; then
echo "? 備份文件完整性檢查通過"
else
echo "? 備份文件損壞"
exit 1
fi
# 檢查備份內(nèi)容
echo "備份內(nèi)容:"
tar tzf "$latest_backup" | head -10
# 檢查云存儲備份
if command -v aws &> /dev/null && [ -n "$AWS_BUCKET" ]; then
if aws s3 ls "s3://${AWS_BUCKET}/" | grep -q "$(basename $latest_backup)"; then
echo "? 云存儲備份驗證通過"
else
echo "? 云存儲備份不存在"
fi
fi
echo "備份驗證完成"
8. 恢復(fù)腳本
創(chuàng)建數(shù)據(jù)恢復(fù)腳本:
#!/bin/bash
# restore_backup.sh
source /opt/backups/config/backup.conf
show_usage() {
echo "使用方法: $0 [選項]"
echo "選項:"
echo " -f, --file FILE 指定備份文件"
echo " -d, --date DATE 按日期恢復(fù) (格式: YYYYMMDD_HHMMSS)"
echo " -l, --list 列出可用備份"
echo " -w, --website 恢復(fù)網(wǎng)站文件"
echo " -m, --mysql 恢復(fù)MySQL數(shù)據(jù)庫"
echo " -p, --postgresql 恢復(fù)PostgreSQL數(shù)據(jù)庫"
echo " -a, --all 恢復(fù)所有內(nèi)容"
}
list_backups() {
echo "可用的備份文件:"
ls -la ${BACKUP_DIR}/backup_*.tar.gz 2>/dev/null | while read file; do
local size=$(du -h "$file" | cut -f1)
local date=$(basename "$file" | sed 's/backup_\(.*\)\.tar\.gz/\1/')
echo " $date - $size - $file"
done
}
restore_website() {
local extract_dir="$1"
echo "恢復(fù)網(wǎng)站文件..."
if [ -f "${extract_dir}/website_files.tar.gz" ]; then
sudo tar xzf "${extract_dir}/website_files.tar.gz" -C /tmp/website_restore
echo "網(wǎng)站文件已提取到 /tmp/website_restore"
echo "請手動將文件復(fù)制到目標目錄"
else
echo "警告: 未找到網(wǎng)站文件備份"
fi
}
restore_mysql() {
local extract_dir="$1"
echo "恢復(fù)MySQL數(shù)據(jù)庫..."
for sql_file in "${extract_dir}"/mysql_*.sql.gz; do
if [ -f "$sql_file" ]; then
local db_name=$(basename "$sql_file" | sed 's/mysql_\(.*\)\.sql\.gz/\1/')
echo "恢復(fù)數(shù)據(jù)庫: $db_name"
gunzip -c "$sql_file" | mysql -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD"
if [ $? -eq 0 ]; then
echo "? 數(shù)據(jù)庫恢復(fù)成功: $db_name"
else
echo "? 數(shù)據(jù)庫恢復(fù)失敗: $db_name"
fi
fi
done
}
main() {
local backup_file=""
local restore_website=false
local restore_mysql=false
local restore_postgresql=false
while [[ $# -gt 0 ]]; do
case $1 in
-f|--file)
backup_file="$2"
shift 2
;;
-d|--date)
local date="$2"
backup_file="${BACKUP_DIR}/backup_${date}.tar.gz"
shift 2
;;
-l|--list)
list_backups
exit 0
;;
-w|--website)
restore_website=true
shift
;;
-m|--mysql)
restore_mysql=true
shift
;;
-p|--postgresql)
restore_postgresql=true
shift
;;
-a|--all)
restore_website=true
restore_mysql=true
restore_postgresql=true
shift
;;
*)
echo "未知選項: $1"
show_usage
exit 1
;;
esac
done
if [ -z "$backup_file" ]; then
echo "錯誤: 必須指定備份文件"
show_usage
exit 1
fi
if [ ! -f "$backup_file" ]; then
echo "錯誤: 備份文件不存在: $backup_file"
exit 1
fi
# 創(chuàng)建臨時解壓目錄
local temp_dir=$(mktemp -d)
echo "解壓備份文件到: $temp_dir"
tar xzf "$backup_file" -C "$temp_dir"
# 執(zhí)行恢復(fù)操作
if [ "$restore_website" = true ]; then
restore_website "$temp_dir"
fi
if [ "$restore_mysql" = true ]; then
restore_mysql "$temp_dir"
fi
# 清理臨時文件
rm -rf "$temp_dir"
echo "恢復(fù)操作完成"
}
main "$@"
9. 使用說明和測試
創(chuàng)建測試腳本驗證整個系統(tǒng):
#!/bin/bash
# test_backup_system.sh
echo "開始測試備份系統(tǒng)..."
# 測試配置文件
if [ -f "/opt/backups/config/backup.conf" ]; then
echo "? 配置文件存在"
else
echo "? 配置文件缺失"
exit 1
fi
# 測試主腳本
if [ -x "/opt/backups/scripts/website_backup.sh" ]; then
echo "? 主腳本可執(zhí)行"
else
echo "? 主腳本不可執(zhí)行"
exit 1
fi
# 測試數(shù)據(jù)庫連接
echo "測試數(shù)據(jù)庫連接..."
if mysql -h localhost -u backup_user -p'your_secure_password' -e "SELECT 1" > /dev/null 2>&1; then
echo "? MySQL連接正常"
else
echo "? MySQL連接失敗"
fi
# 執(zhí)行測試備份
echo "執(zhí)行測試備份..."
sudo -u backupuser /opt/backups/scripts/website_backup.sh
# 檢查備份結(jié)果
if [ $? -eq 0 ]; then
echo "? 備份測試成功"
else
echo "? 備份測試失敗"
exit 1
fi
echo "備份系統(tǒng)測試完成"
10. 總結(jié)
本教程提供了一個完整的企業(yè)級網(wǎng)站和數(shù)據(jù)庫備份解決方案,具有以下特點:
- 全面性:支持網(wǎng)站文件、MySQL、PostgreSQL數(shù)據(jù)庫備份
- 可靠性:包含完整的錯誤處理和日志記錄
- 自動化:支持定時任務(wù)和自動清理
- 多云支持:支持AWS S3、Google Cloud Storage、阿里云OSS
- 安全性:配置文件權(quán)限控制和敏感信息保護
- 可維護性:模塊化設(shè)計和詳細文檔
通過按照本教程逐步實施,您可以建立一個生產(chǎn)級別的自動化備份系統(tǒng),確保網(wǎng)站數(shù)據(jù)的安全性和可恢復(fù)性。
到此這篇關(guān)于Shell腳本實現(xiàn)自動備份網(wǎng)站和數(shù)據(jù)庫并上傳到云存儲的文章就介紹到這了,更多相關(guān)Shell腳本自動備份網(wǎng)站和數(shù)據(jù)庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
shell腳本結(jié)合iptables防端口掃描的實現(xiàn)
這篇文章主要介紹了shell腳本結(jié)合iptables防端口掃描的實現(xiàn),中間使用了inotify-tools工具,需要的朋友可以參考下2014-05-05
shell腳本實現(xiàn)本地文件與服務(wù)器文件同步
這篇文章主要介紹了本地文件與服務(wù)器文件同步shell腳本的方法,然后在文章給大家補充介紹了shell腳本備份本地服務(wù)器的文件到遠程服務(wù)器的實例代碼,需要的朋友可以參考下2017-11-11
CentOS7運行.sh腳本提示syntax error: unexpected end of file的解決方法
這篇文章主要介紹了解決執(zhí)行腳本報syntax error: unexpected end of file或syntax error near unexpected token fi錯誤的問題,需要的朋友可以參考下2020-02-02
關(guān)于Linux反空閑設(shè)置的兩種方法總結(jié)
下面小編就為大家?guī)硪黄P(guān)于Linux反空閑設(shè)置的兩種方法總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03

