[TOC]
`

  1. 增量备份(每日):利用 MySQL 的 binlog(事务日志)。
  2. 全量备份(每周日):使用 mysqldump 进行全量备份。

1. 增量备份脚本

增量备份脚本会使用 mysqlbinlog 工具来备份 binlog 文件,并将其归档到备份目录中。

增量备份脚本 (daily_incremental_backup.sh)

#!/bin/bash

# 配置部分
MYSQL_USER="your_username"
MYSQL_PASSWORD="your_password"
MYSQL_HOST="localhost"
BACKUP_DIR="/path/to/backup/directory/incremental"
DATE=$(date +%F_%H-%M-%S)

# 创建备份目录(如果不存在的话)
mkdir -p "$BACKUP_DIR"

# 获取当前 binlog 文件和位置
CURRENT_BINLOG=$(mysql --user="$MYSQL_USER" --password="$MYSQL_PASSWORD" --host="$MYSQL_HOST" -e "SHOW MASTER STATUS\G" | grep 'File:' | awk '{print $2}')
CURRENT_POSITION=$(mysql --user="$MYSQL_USER" --password="$MYSQL_PASSWORD" --host="$MYSQL_HOST" -e "SHOW MASTER STATUS\G" | grep 'Position:' | awk '{print $2}')

# 创建增量备份
mysqlbinlog --start-position=0 --stop-never "$CURRENT_BINLOG" > "$BACKUP_DIR/incremental_$DATE.sql"

# 删除超过 7 天的增量备份
find "$BACKUP_DIR" -type f -name "*.sql" -mtime +7 -exec rm {} \;

# 记录备份日志
echo "Incremental backup completed at $DATE" >> "$BACKUP_DIR/backup_log.txt"

2. 全量备份脚本

全量备份脚本使用 mysqldump 工具进行全量备份,并保留最新的 7 份全量备份。

全量备份脚本 (weekly_full_backup.sh)

#!/bin/bash

# 配置部分
MYSQL_USER="your_username"
MYSQL_PASSWORD="your_password"
MYSQL_HOST="localhost"
BACKUP_DIR="/path/to/backup/directory/full"
DATE=$(date +%F_%H-%M-%S)

# 创建备份目录(如果不存在的话)
mkdir -p "$BACKUP_DIR"

# 执行全量备份
mysqldump --user="$MYSQL_USER" --password="$MYSQL_PASSWORD" --host="$MYSQL_HOST" --all-databases --single-transaction --quick --lock-tables=false > "$BACKUP_DIR/full_backup_$DATE.sql"

# 删除超过 7 份的全量备份
ls -t "$BACKUP_DIR/full_backup_"* | sed -e '1,7d' | xargs -d '\n' rm -f

# 记录备份日志
echo "Full backup completed at $DATE" >> "$BACKUP_DIR/backup_log.txt"

3. 配置 cron 任务

设置增量备份任务

每天凌晨 2 点运行增量备份脚本:

crontab -e

添加以下行:

0 2 * * * /bin/bash /path/to/backup/directory/incremental/daily_incremental_backup.sh

设置全量备份任务

每周日凌晨 2 点运行全量备份脚本:

crontab -e

添加以下行:

0 2 * * 0 /bin/bash /path/to/backup/directory/full/weekly_full_backup.sh

总结

  1. 增量备份脚本 (daily_incremental_backup.sh):

    • 使用 mysqlbinlog 工具备份 binlog 文件。
    • 每天执行,保留最新的 7 天增量备份。
  2. 全量备份脚本 (weekly_full_backup.sh):

    • 使用 mysqldump 工具备份所有数据库。
    • 每周日执行,保留最新的 7 份全量备份。
  3. cron 配置:

    • 增量备份:每天凌晨 2 点。
    • 全量备份:每周日凌晨 2 点。

为了实现数据库的恢复功能,你需要创建一个脚本,能够根据提供的日期和备份类型(全量备份或增量备份)恢复数据库。这涉及到从备份中恢复数据,并根据需要应用增量备份。

1. 假设的备份策略

  • 全量备份: 每周日(星期天)进行全量备份,备份文件命名为 full_backup_YYYY-MM-DD.sql.gz
  • 增量备份: 每天进行增量备份,备份文件命名为 incremental_backup_YYYY-MM-DD.sql.gz
  • 增量备份的恢复: 在恢复全量备份之后,需要按时间顺序应用增量备份。

2. 恢复脚本

以下是一个示例恢复脚本 restore_database.sh,假设你使用 mysqlgzip 工具进行备份和恢复:

#!/bin/bash

# 配置部分
DB_USER="root"
DB_PASSWORD="password"
DB_NAME="your_database"
BACKUP_DIR="/path/to/backup"
RESTORE_DATE="$1"

if [ -z "$RESTORE_DATE" ]; then
    echo "Usage: $0 <restore_date>"
    exit 1
fi

# Check if the date is in the correct format (YYYY-MM-DD)
if ! [[ "$RESTORE_DATE" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
    echo "Invalid date format. Please use YYYY-MM-DD."
    exit 1
fi

# Determine if it's a Sunday or a regular day
DAY_OF_WEEK=$(date -d "$RESTORE_DATE" +%u) # %u: Day of week (1=Monday, 7=Sunday)

if [ "$DAY_OF_WEEK" -eq 7 ]; then
    # Sunday: Restore full backup
    FULL_BACKUP_FILE="$BACKUP_DIR/full_backup_$RESTORE_DATE.sql.gz"

    if [ ! -f "$FULL_BACKUP_FILE" ]; then
        echo "Full backup file not found: $FULL_BACKUP_FILE"
        exit 1
    fi

    echo "Restoring full backup: $FULL_BACKUP_FILE"
    gunzip < "$FULL_BACKUP_FILE" | mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME"

    # Apply all incremental backups up to the specified date
    for BACKUP in $(ls $BACKUP_DIR/incremental_backup_*.sql.gz | sort); do
        BACKUP_DATE=$(echo $BACKUP | grep -oP '\d{4}-\d{2}-\d{2}')
        if [[ "$BACKUP_DATE" < "$RESTORE_DATE" ]]; then
            echo "Applying incremental backup: $BACKUP"
            gunzip < "$BACKUP" | mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME"
        fi
    done

else
    # Other days: Restore the latest full backup and apply all incremental backups up to the specified date
    LATEST_FULL_BACKUP=$(ls $BACKUP_DIR/full_backup_*.sql.gz | sort | tail -n 1)

    if [ ! -f "$LATEST_FULL_BACKUP" ]; then
        echo "No full backup found"
        exit 1
    fi

    echo "Restoring latest full backup: $LATEST_FULL_BACKUP"
    gunzip < "$LATEST_FULL_BACKUP" | mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME"

    # Apply all incremental backups up to the specified date
    for BACKUP in $(ls $BACKUP_DIR/incremental_backup_*.sql.gz | sort); do
        BACKUP_DATE=$(echo $BACKUP | grep -oP '\d{4}-\d{2}-\d{2}')
        if [[ "$BACKUP_DATE" <= "$RESTORE_DATE" ]]; then
            echo "Applying incremental backup: $BACKUP"
            gunzip < "$BACKUP" | mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME"
        fi
    done
fi

echo "Database restore process completed."

脚本说明

  1. 配置部分: 设置数据库用户名、密码、数据库名、备份文件目录和恢复日期。
  2. 日期检查: 验证恢复日期的格式是否正确。
  3. 恢复全量备份:
    • 如果恢复日期是周日(DAY_OF_WEEK 为 7),则使用当日的全量备份。
    • 否则,恢复最新的全量备份。
  4. 应用增量备份:
    • 在恢复全量备份后,应用所有早于或等于指定日期的增量备份。
  5. 执行恢复: 使用 gunzip 解压备份文件,并将其恢复到 MySQL 数据库中。

使用示例

  • 恢复到某一天(例如 2024-08-20):
    ./restore_database.sh 2024-08-20

注意事项

  • 备份文件的存放路径: 确保备份文件在指定的目录中,并按照约定的命名规则进行存放。
  • 增量备份的顺序: 增量备份的应用顺序要正确,以确保数据一致性。
  • 错误处理: 在生产环境中使用时,可以添加更多的错误处理逻辑,以应对各种异常情况。

通过这个脚本,你可以根据日期恢复到相应的备份版本,同时保证全量和增量备份的正确应用。

作者:严锋  创建时间:2024-08-23 09:41
最后编辑:严锋  更新时间:2025-05-09 15:48