Linux dump命令

功能说明:dump命令用于备份ext2、ext3、ext4文件系统,支持全量备份和增量备份。它能够创建文件系统的完整备份或只备份自上次备份以来修改过的文件,是Linux系统的重要备份工具。
权限要求:dump命令需要root权限才能读取文件系统的原始数据。备份操作必须在文件系统未挂载或只读状态下进行,以确保数据一致性。
主要功能
  • 创建文件系统的完整备份(level 0)
  • 执行增量备份(level 1-9)
  • 支持磁带设备和文件备份
  • 备份时跳过特定文件
  • 多卷备份支持
  • 备份进度显示
使用前提
  • 需要root权限
  • 文件系统必须是ext2/3/4
  • 备份时文件系统应卸载或只读
  • 需要足够的磁盘空间
  • 了解备份级别概念
  • 配合restore命令恢复

命令语法

语法格式
dump [选项] [-等级] [-f 备份文件] [要备份的文件或目录]
dump [选项] [-等级] [-f 备份文件] [文件系统]

命令参数

参数 说明
-0 到 -9 备份级别(0=完全备份,1-9=增量备份)
-B records 指定每个备份卷包含的记录数
-b blocksize 指定块大小(默认10KB)
-d density 设置磁带密度(BPI)
-f file 指定备份文件或设备
-h level 不备份指定级别之后创建的文件
-j compression_level 使用bzip2压缩(1-9)
-L label 为备份添加卷标
-M 启用多卷模式
-n 备份完成后通知所有操作员
-s feet 指定磁带长度(英尺)
-T date 指定备份日期(而非今天)
-u 更新备份记录文件/etc/dumpdates
-W 显示需要备份的文件系统
-w 显示需要备份的文件(同-W但详细)
-z compression_level 使用gzip压缩(1-9)

备份级别详解

级别 备份类型 备份内容 依赖级别 典型使用场景
0 完全备份 备份所有文件 首次备份,每月备份
1 1级增量 自0级备份以来修改的文件 0 每日增量备份
2 2级增量 自1级备份以来修改的文件 1 更频繁的增量
3 3级增量 自2级备份以来修改的文件 2 小时级备份
4-9 多级增量 自上一级备份以来的修改 上一级 特殊需求备份
备份级别示例说明
# 示例备份策略:
# 周日:级别0(完全备份)
# 周一:级别1(备份自周日以来的修改)
# 周二:级别2(备份自周一以来的修改)
# 周三:级别1(备份自周日以来的修改)
# 周四:级别2(备份自周三以来的修改)
# 周五:级别2(备份自周四以来的修改)
# 周六:级别2(备份自周五以来的修改)

# 恢复时需要按顺序恢复:
# 周日0级 → 周一1级 → 周二2级 → 周三1级 → 周四2级 → 周五2级 → 周六2级
# 注意:恢复1级备份会覆盖之前的2级备份数据

使用示例

1. 基本备份操作 常用
示例
# 创建文件系统的完全备份(level 0)
dump -0u -f /backup/root_backup.dump /dev/sda1

# 创建增量备份(level 1,备份自上次0级以来的修改)
dump -1u -f /backup/root_inc1.dump /dev/sda1

# 备份到磁带设备
dump -0u -f /dev/st0 /dev/sda1

# 备份到远程服务器
dump -0u -f - /dev/sda1 | ssh user@backup-server "dd of=/backup/remote.dump"

# 使用gzip压缩备份
dump -0u -z 6 -f /backup/root_backup.dump.gz /dev/sda1

# 使用bzip2压缩备份
dump -0u -j 6 -f /backup/root_backup.dump.bz2 /dev/sda1

# 显示备份进度
dump -0u -f /backup/root_backup.dump /dev/sda1
# 输出示例:
# DUMP: Date of this level 0 dump: Mon Jan 10 10:30:00 2025
# DUMP: Dumping /dev/sda1 (/ (dir /)) to /backup/root_backup.dump
# DUMP: Label: none
# DUMP: Writing 10 Kilobyte records
# DUMP: mapping (Pass I) [regular files]
# DUMP: mapping (Pass II) [directories]
# DUMP: estimated 9560 blocks.
# DUMP: Volume 1 started with block 1 at: Mon Jan 10 10:30:01 2025
# DUMP: dumping (Pass III) [directories]
# DUMP: dumping (Pass IV) [regular files]
# DUMP: Closing /backup/root_backup.dump
# DUMP: Volume 1 completed at: Mon Jan 10 10:35:23 2025
# DUMP: Volume 1 9560 blocks (9.34MB)
# DUMP: Volume 1 took 0:05:22
# DUMP: Volume 1 transfer rate: 29 kB/s
# DUMP: 9560 blocks (9.34MB) on 1 volume(s)
# DUMP: finished in 322 seconds, throughput 29 kB/s
# DUMP: Date of this level 0 dump: Mon Jan 10 10:30:00 2025
# DUMP: Date this dump completed:  Mon Jan 10 10:35:23 2025
# DUMP: Average transfer rate: 29 kB/s
# DUMP: DUMP IS DONE
2. 查看备份需求和记录
# 查看需要备份的文件系统
dump -W
# 输出示例:
# Last dump(s) done (Dump '>' file systems):
# > /dev/sda1	(     /) Last dump: never
# > /dev/sda2	( /home) Last dump: level 0, date Mon Jan 10 10:30:00 2025

# 查看需要备份的详细信息
dump -w
# 输出更详细的信息,包括哪些文件需要备份

# 查看备份记录文件
cat /etc/dumpdates
# 输出示例:
# /dev/sda1 0 Mon Jan 10 10:30:00 2025
# /dev/sda2 1 Tue Jan 11 22:00:00 2025

# 检查特定文件系统是否需要备份
dump -W | grep "/dev/sda1"

# 查看备份策略执行情况
echo "=== 备份历史 ==="
cat /etc/dumpdates | while read device level date time; do
    echo "设备: $device, 级别: $level, 时间: $date $time"
done
3. 多卷备份操作
# 启用多卷模式(适合大备份分割)
dump -0u -M -f /dev/st0 /dev/sda1
# 当第一盘磁带满时,会提示插入下一盘

# 指定磁带长度(英尺)
dump -0u -s 1200 -f /dev/st0 /dev/sda1

# 指定磁带密度
dump -0u -d 6250 -f /dev/st0 /dev/sda1

# 多卷备份到文件
dump -0u -M -f "/backup/part%d.dump" /dev/sda1
# 生成 part1.dump, part2.dump, part3.dump 等

# 多卷恢复时使用restore的-M参数
restore -r -M -f "/backup/part%d.dump"
4. 备份排除和过滤
# 不备份指定级别后创建的文件
dump -0u -h 0 -f /backup/root_backup.dump /dev/sda1
# 不备份0级备份后创建的任何文件

# 通过find过滤要备份的文件
find /important -type f -mtime -7 | dump -0u -f /backup/recent.dump -

# 备份特定目录
dump -0u -f /backup/etc.dump /etc

# 排除临时文件(需要结合其他工具)
find / -path /tmp -prune -o -path /proc -prune -o -print | \
    dump -0u -f /backup/system_no_tmp.dump -

# 备份时跳过特定文件类型
find /home -type f ! -name "*.tmp" ! -name "*.log" | \
    dump -0u -f /backup/home_clean.dump -
5. 增量备份策略示例
#!/bin/bash
# 完整的增量备份策略脚本

BACKUP_DIR="/backup"
DEVICE="/dev/sda1"
MOUNT_POINT="/"
TODAY_LEVEL=$1  # 从命令行参数获取备份级别

# 检查参数
if [ -z "$TODAY_LEVEL" ]; then
    echo "用法: $0 [备份级别 0-9]"
    echo "示例: $0 0  # 完全备份"
    exit 1
fi

# 创建备份目录
mkdir -p "$BACKUP_DIR"

# 根据日期生成备份文件名
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_${MOUNT_POINT##*/}_level${TODAY_LEVEL}_${DATE}.dump"

echo "=== 开始备份 ==="
echo "设备: $DEVICE"
echo "挂载点: $MOUNT_POINT"
echo "备份级别: $TODAY_LEVEL"
echo "备份文件: $BACKUP_FILE"
echo "开始时间: $(date)"

# 执行备份
if dump -${TODAY_LEVEL}u -f "$BACKUP_FILE" "$DEVICE"; then
    echo "✓ 备份成功完成"

    # 更新备份记录
    echo "备份记录:"
    grep "$DEVICE" /etc/dumpdates 2>/dev/null || echo "无记录"

    # 显示备份文件信息
    echo -e "\n备份文件信息:"
    ls -lh "$BACKUP_FILE"

    # 计算备份大小
    BACKUP_SIZE=$(stat -c%s "$BACKUP_FILE")
    echo "备份大小: $(numfmt --to=iec $BACKUP_SIZE)"
else
    echo "✗ 备份失败"
    exit 1
fi

echo -e "\n=== 备份完成 ==="
echo "完成时间: $(date)"
6. 备份验证和测试
# 测试备份文件完整性
restore -t -f /backup/root_backup.dump
# 如果无错误输出,表示备份文件完整

# 模拟恢复测试
restore -i -f /backup/root_backup.dump
# 进入交互模式,检查文件列表

# 比较备份和实际文件
restore -t -f /backup/root_backup.dump | head -20
ls -la / | head -20

# 检查备份文件格式
file /backup/root_backup.dump
# 输出:/backup/root_backup.dump: new-fs dump file (little endian), ...

# 查看备份文件详细信息
restore -s 0 -f /backup/root_backup.dump
# 显示备份会话信息

# 验证压缩备份
gzip -t /backup/root_backup.dump.gz 2>/dev/null && echo "压缩文件完整" || echo "压缩文件损坏"
7. 高级备份场景
# 场景1:数据库服务器备份
#!/bin/bash
# 数据库备份前先锁定表
mysqldump -u root -p --all-databases > /tmp/db_backup.sql
# 备份数据库和文件系统
dump -0u -f /backup/db_server.dump /dev/sda1
# 同时备份数据库导出文件
cp /tmp/db_backup.sql /backup/
rm -f /tmp/db_backup.sql

# 场景2:LVM快照备份
#!/bin/bash
# 创建LVM快照
lvcreate -L 10G -s -n root_snap /dev/vg00/root
# 挂载快照
mount /dev/vg00/root_snap /mnt/snapshot
# 备份快照
dump -0u -f /backup/lvm_snapshot.dump /dev/vg00/root_snap
# 卸载并删除快照
umount /mnt/snapshot
lvremove -f /dev/vg00/root_snap

# 场景3:网络备份
#!/bin/bash
# 将备份流式传输到远程服务器
dump -0u -f - /dev/sda1 | \
    ssh backup@192.168.1.100 "dd of=/backup/remote_backup.dump"

# 场景4:加密备份
#!/bin/bash
# 使用openssl加密备份
dump -0u -f - /dev/sda1 | \
    openssl enc -aes-256-cbc -salt -pass pass:MySecretPassword | \
    dd of=/backup/encrypted_backup.dump

# 场景5:自动清理旧备份
#!/bin/bash
BACKUP_DIR="/backup"
RETENTION_DAYS=30

echo "清理超过${RETENTION_DAYS}天的备份..."
find "$BACKUP_DIR" -name "*.dump" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.dump.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.dump.bz2" -mtime +$RETENTION_DAYS -delete
echo "清理完成"

与tar命令对比

特性 dump tar
主要用途 文件系统备份 文件归档
备份类型 支持增量备份 仅完全备份
文件系统 仅ext2/3/4 所有文件系统
备份粒度 块级别 文件级别
权限要求 需要root 普通用户
稀疏文件 高效处理 可能膨胀
硬链接 正确保存 可能重复
设备文件 支持 支持
压缩支持 有限(-j/-z) 多种格式
恢复工具 restore tar
选择建议
# 使用dump的场景:
# 1. 需要增量备份
# 2. 备份ext2/3/4文件系统
# 3. 需要块级备份
# 4. 备份整个文件系统
# 5. 需要记录备份历史

dump -0u -f /backup/full.dump /dev/sda1
dump -1u -f /backup/incremental.dump /dev/sda1

# 使用tar的场景:
# 1. 跨文件系统备份
# 2. 普通用户备份
# 3. 只需要完全备份
# 4. 需要灵活压缩
# 5. 备份特定目录

tar -czf /backup/home.tar.gz /home
tar -cjf /backup/etc.tar.bz2 /etc

使用restore恢复备份

dump创建的备份需要使用restore命令恢复:

恢复操作示例
# 查看备份内容
restore -t -f /backup/root_backup.dump

# 交互式恢复(选择要恢复的文件)
restore -i -f /backup/root_backup.dump
# 进入交互模式后可用命令:
#   ls          列出目录
#   cd          切换目录
#   pwd         显示当前目录
#   add         添加文件/目录到恢复列表
#   delete      从恢复列表删除
#   extract     执行恢复
#   quit        退出

# 完全恢复备份
restore -r -f /backup/root_backup.dump

# 恢复特定文件
restore -x -f /backup/root_backup.dump /etc/passwd /etc/shadow

# 恢复特定目录
restore -x -f /backup/root_backup.dump /home/user1

# 恢复到不同目录
mkdir /tmp/restored
cd /tmp/restored
restore -r -f /backup/root_backup.dump

# 恢复增量备份链
# 先恢复0级备份
restore -r -f sunday_level0.dump
# 再按顺序恢复增量备份
restore -r -f monday_level1.dump
restore -r -f tuesday_level2.dump
# 注意:恢复顺序必须正确

# 验证恢复的文件
restore -C -f /backup/root_backup.dump
# 比较备份和磁盘文件,报告差异

实际应用脚本

脚本1:自动增量备份系统
#!/bin/bash
# 自动增量备份系统

# 配置
CONFIG_FILE="/etc/backup_config"
LOG_FILE="/var/log/backup.log"
STATUS_FILE="/var/run/backup.status"
BACKUP_ROOT="/backup"

# 加载配置
if [ -f "$CONFIG_FILE" ]; then
    source "$CONFIG_FILE"
else
    # 默认配置
    BACKUP_DEVICES=("/dev/sda1" "/dev/sda2")
    BACKUP_LEVEL=0
    COMPRESSION="gzip"
    RETENTION_DAYS=30
fi

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 错误处理
error_exit() {
    log "错误: $1"
    echo "FAILED" > "$STATUS_FILE"
    exit 1
}

# 检查依赖
check_dependencies() {
    for cmd in dump restore; do
        if ! command -v $cmd >/dev/null 2>&1; then
            error_exit "未找到命令: $cmd"
        fi
    done
}

# 确定备份级别
determine_level() {
    local device=$1
    local today=$(date +%u)  # 1-7, 1=周一

    # 周日做完全备份
    if [ "$today" -eq 7 ]; then
        echo 0
    else
        # 检查上次备份级别
        local last_level=$(grep "^$device" /etc/dumpdates 2>/dev/null | tail -1 | awk '{print $2}')
        if [ -z "$last_level" ]; then
            echo 0  # 从未备份过,做完全备份
        elif [ "$last_level" -eq 0 ]; then
            echo 1  # 上次是完全备份,这次做1级增量
        else
            echo 2  # 上次是增量,继续增量
        fi
    fi
}

# 执行备份
perform_backup() {
    local device=$1
    local mount_point=$(findmnt -n -o TARGET "$device" 2>/dev/null || echo "unknown")
    local level=$(determine_level "$device")
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local backup_name="backup_${device##*/}_level${level}_${timestamp}.dump"
    local backup_path="$BACKUP_ROOT/$backup_name"

    log "开始备份: $device ($mount_point)"
    log "备份级别: $level"
    log "备份文件: $backup_path"

    # 创建备份
    if [ "$COMPRESSION" = "gzip" ]; then
        if ! dump -${level}u -z 6 -f "$backup_path.gz" "$device"; then
            error_exit "备份失败: $device"
        fi
    elif [ "$COMPRESSION" = "bzip2" ]; then
        if ! dump -${level}u -j 6 -f "$backup_path.bz2" "$device"; then
            error_exit "备份失败: $device"
        fi
    else
        if ! dump -${level}u -f "$backup_path" "$device"; then
            error_exit "备份失败: $device"
        fi
    fi

    log "备份完成: $device"
}

# 验证备份
verify_backup() {
    local backup_file=$1

    log "验证备份: $backup_file"

    if [[ "$backup_file" == *.gz ]]; then
        if ! gzip -t "$backup_file" 2>/dev/null; then
            error_exit "备份文件损坏: $backup_file"
        fi
        local temp_file=$(mktemp)
        gzip -dc "$backup_file" > "$temp_file"
        if ! restore -t -f "$temp_file" >/dev/null 2>&1; then
            rm -f "$temp_file"
            error_exit "备份内容损坏: $backup_file"
        fi
        rm -f "$temp_file"
    elif [[ "$backup_file" == *.bz2 ]]; then
        if ! bzip2 -t "$backup_file" 2>/dev/null; then
            error_exit "备份文件损坏: $backup_file"
        fi
    else
        if ! restore -t -f "$backup_file" >/dev/null 2>&1; then
            error_exit "备份内容损坏: $backup_file"
        fi
    fi

    log "验证通过: $backup_file"
}

# 清理旧备份
cleanup_old_backups() {
    log "清理超过${RETENTION_DAYS}天的旧备份..."

    local deleted_count=0
    find "$BACKUP_ROOT" -name "backup_*.dump" -mtime +$RETENTION_DAYS | while read file; do
        log "删除旧备份: $(basename "$file")"
        rm -f "$file"
        deleted_count=$((deleted_count + 1))
    done

    find "$BACKUP_ROOT" -name "backup_*.dump.gz" -mtime +$RETENTION_DAYS | while read file; do
        log "删除旧备份: $(basename "$file")"
        rm -f "$file"
        deleted_count=$((deleted_count + 1))
    done

    find "$BACKUP_ROOT" -name "backup_*.dump.bz2" -mtime +$RETENTION_DAYS | while read file; do
        log "删除旧备份: $(basename "$file")"
        rm -f "$file"
        deleted_count=$((deleted_count + 1))
    done

    log "清理完成,删除 $deleted_count 个文件"
}

# 生成报告
generate_report() {
    local report_file="$BACKUP_ROOT/backup_report_$(date +%Y%m%d).txt"

    {
        echo "=== 备份报告 ==="
        echo "生成时间: $(date)"
        echo "备份目录: $BACKUP_ROOT"
        echo ""
        echo "=== 备份记录 (/etc/dumpdates) ==="
        cat /etc/dumpdates 2>/dev/null || echo "无备份记录"
        echo ""
        echo "=== 当前备份文件 ==="
        find "$BACKUP_ROOT" -name "backup_*.dump*" -type f -exec ls -lh {} \; | sort
        echo ""
        echo "=== 磁盘使用情况 ==="
        df -h "$BACKUP_ROOT"
    } > "$report_file"

    log "报告生成: $report_file"
}

# 主程序
main() {
    log "=== 开始备份任务 ==="
    echo "RUNNING" > "$STATUS_FILE"

    # 检查依赖
    check_dependencies

    # 确保备份目录存在
    mkdir -p "$BACKUP_ROOT"

    # 备份每个设备
    for device in "${BACKUP_DEVICES[@]}"; do
        if [ -b "$device" ]; then
            perform_backup "$device"
        else
            log "警告: 设备不存在 - $device"
        fi
    done

    # 验证最新备份
    latest_backup=$(find "$BACKUP_ROOT" -name "backup_*.dump*" -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
    if [ -n "$latest_backup" ]; then
        verify_backup "$latest_backup"
    fi

    # 清理旧备份
    cleanup_old_backups

    # 生成报告
    generate_report

    log "=== 备份任务完成 ==="
    echo "SUCCESS" > "$STATUS_FILE"
}

# 执行主程序
main 2>&1 | tee -a "$LOG_FILE"
脚本2:灾难恢复准备脚本
#!/bin/bash
# 灾难恢复准备脚本

RECOVERY_DIR="/recovery"
BACKUP_DIR="/backup"
RESCUE_IMAGE="/boot/rescue.img"
GRUB_CONFIG="/boot/grub/grub.cfg"

echo "=== 灾难恢复准备工具 ==="
echo "恢复目录: $RECOVERY_DIR"
echo "备份目录: $BACKUP_DIR"
echo ""

# 创建恢复目录
mkdir -p "$RECOVERY_DIR"
cd "$RECOVERY_DIR"

# 1. 收集系统信息
echo "1. 收集系统信息..."
{
    echo "=== 系统信息 ==="
    echo "收集时间: $(date)"
    echo ""
    echo "=== 主机信息 ==="
    hostnamectl
    echo ""
    echo "=== 磁盘信息 ==="
    fdisk -l
    echo ""
    echo "=== 挂载信息 ==="
    mount
    echo ""
    echo "=== 网络信息 ==="
    ip addr
    echo ""
    echo "=== 内核信息 ==="
    uname -a
    lsmod | head -20
} > system_info.txt
echo "系统信息已保存: $RECOVERY_DIR/system_info.txt"

# 2. 备份关键配置文件
echo "2. 备份关键配置文件..."
mkdir -p etc_backup
important_files=(
    /etc/fstab
    /etc/passwd
    /etc/group
    /etc/shadow
    /etc/gshadow
    /etc/hosts
    /etc/resolv.conf
    /etc/ssh/sshd_config
    /etc/network/interfaces
    /etc/sysconfig/network-scripts/ifcfg-*
)

for file in "${important_files[@]}"; do
    if [ -e "$file" ]; then
        cp -a --parents "$file" etc_backup/ 2>/dev/null || true
    fi
done
echo "配置文件已备份: $RECOVERY_DIR/etc_backup/"

# 3. 备份分区表
echo "3. 备份分区表..."
fdisk -l > partition_table.txt
for device in /dev/sd? /dev/vd? /dev/xvd?; do
    if [ -b "$device" ]; then
        sfdisk -d "$device" > "partition_${device##*/}.txt" 2>/dev/null || true
    fi
done
echo "分区表已备份"

# 4. 备份GRUB配置
echo "4. 备份GRUB配置..."
if [ -f "$GRUB_CONFIG" ]; then
    cp "$GRUB_CONFIG" grub_backup.cfg
    echo "GRUB配置已备份"
fi

# 5. 创建恢复脚本
echo "5. 创建恢复脚本..."
cat > recovery_script.sh << 'EOF'
#!/bin/bash
# 灾难恢复脚本

echo "=== 灾难恢复脚本 ==="
echo "警告: 此脚本将覆盖现有数据!"
echo "请确保已备份重要数据"
echo ""
read -p "是否继续? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
    echo "取消恢复"
    exit 1
fi

# 恢复分区表
echo "恢复分区表..."
for part_file in partition_*.txt; do
    if [ -f "$part_file" ]; then
        device="/dev/${part_file#partition_}"
        device="${device%.txt}"
        echo "恢复分区表: $device"
        sfdisk "$device" < "$part_file"
    fi
done

# 恢复文件系统
echo "恢复文件系统..."
if [ -f /backup/full_backup.dump ]; then
    echo "恢复完全备份..."
    restore -r -f /backup/full_backup.dump
fi

# 恢复增量备份
for inc_backup in /backup/incremental_*.dump; do
    if [ -f "$inc_backup" ]; then
        echo "恢复增量备份: $inc_backup"
        restore -r -f "$inc_backup"
    fi
done

# 恢复配置文件
echo "恢复配置文件..."
cp -r etc_backup/* / 2>/dev/null || true

echo "恢复完成,请重启系统"
EOF

chmod +x recovery_script.sh
echo "恢复脚本已创建: $RECOVERY_DIR/recovery_script.sh"

# 6. 创建恢复指南
echo "6. 创建恢复指南..."
cat > RECOVERY_GUIDE.txt << 'EOF'
                   灾难恢复指南
===================================================

1. 准备工作
   - 准备Linux安装介质或救援镜像
   - 准备备份文件
   - 记录原系统配置信息

2. 启动救援系统
   - 从安装介质启动
   - 选择救援模式
   - 挂载原系统分区

3. 恢复步骤
   a) 恢复分区表
      # sfdisk /dev/sda < partition_sda.txt

   b) 创建文件系统
      # mkfs.ext4 /dev/sda1
      # mkfs.ext4 /dev/sda2

   c) 挂载文件系统
      # mount /dev/sda1 /mnt
      # mount /dev/sda2 /mnt/home

   d) 恢复备份
      # cd /mnt
      # restore -r -f /backup/full_backup.dump

   e) 恢复增量备份(按顺序)
      # restore -r -f /backup/incremental_1.dump
      # restore -r -f /backup/incremental_2.dump

   f) 恢复配置文件
      # cp -r etc_backup/* /mnt/

   g) 重新安装GRUB
      # chroot /mnt
      # grub-install /dev/sda
      # update-grub

   h) 退出重启
      # exit
      # umount -R /mnt
      # reboot

4. 验证恢复
   - 检查系统能否正常启动
   - 验证关键服务运行
   - 检查数据完整性

5. 联系方式
   - 系统管理员: admin@example.com
   - 技术支持: 400-123-4567

===================================================
EOF

echo "恢复指南已创建: $RECOVERY_DIR/RECOVERY_GUIDE.txt"

# 7. 打包恢复工具
echo "7. 打包恢复工具..."
tar -czf recovery_kit_$(date +%Y%m%d).tar.gz \
    system_info.txt \
    etc_backup/ \
    partition_*.txt \
    grub_backup.cfg 2>/dev/null \
    recovery_script.sh \
    RECOVERY_GUIDE.txt

echo "恢复工具包: $RECOVERY_DIR/recovery_kit_$(date +%Y%m%d).tar.gz"

echo ""
echo "=== 灾难恢复准备完成 ==="
echo "请将恢复工具包复制到安全位置(如外部存储)"
echo "定期测试恢复流程以确保其有效性"
脚本3:备份监控和报警系统
#!/bin/bash
# 备份监控和报警系统

CONFIG_FILE="/etc/backup_monitor.conf"
LOG_FILE="/var/log/backup_monitor.log"
ALERT_EMAIL="admin@example.com"
ALERT_THRESHOLD_DAYS=2  # 超过2天无备份报警
MIN_FREE_SPACE=10       # 最小剩余空间百分比

# 加载配置
[ -f "$CONFIG_FILE" ] && source "$CONFIG_FILE"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}

# 发送邮件报警
send_alert() {
    local subject=$1
    local message=$2

    echo "$message" | mail -s "$subject" "$ALERT_EMAIL"
    log "报警邮件已发送: $subject"
}

# 检查备份状态
check_backup_status() {
    local issues=0

    echo "=== 备份系统健康检查 ==="
    echo "检查时间: $(date)"
    echo ""

    # 检查dumpdates文件
    if [ ! -f /etc/dumpdates ]; then
        echo "✗ 备份记录文件不存在: /etc/dumpdates"
        send_alert "备份监控报警: 无备份记录" "系统从未执行过备份。"
        issues=$((issues + 1))
    else
        echo "✓ 备份记录文件存在"

        # 检查最近备份时间
        while IFS= read -r line; do
            local device=$(echo "$line" | awk '{print $1}')
            local level=$(echo "$line" | awk '{print $2}')
            local date_str=$(echo "$line" | awk '{print $3, $4, $5, $6}')

            # 转换为时间戳
            local backup_time=$(date -d "$date_str" +%s 2>/dev/null || echo 0)
            local current_time=$(date +%s)
            local diff_days=$(( (current_time - backup_time) / 86400 ))

            if [ "$diff_days" -gt "$ALERT_THRESHOLD_DAYS" ]; then
                echo "✗ 设备 $device 超过 ${diff_days} 天未备份(级别 $level)"
                send_alert "备份监控报警: 备份过期" "设备 $device 超过 ${diff_days} 天未备份。"
                issues=$((issues + 1))
            else
                echo "✓ 设备 $device 最近 ${diff_days} 天内有备份(级别 $level)"
            fi
        done < /etc/dumpdates
    fi

    # 检查备份目录
    local backup_dirs=("/backup" "/var/backup")
    for dir in "${backup_dirs[@]}"; do
        if [ -d "$dir" ]; then
            echo "✓ 备份目录存在: $dir"

            # 检查磁盘空间
            local free_space=$(df "$dir" | awk 'NR==2 {print $5}' | sed 's/%//')
            local used_percent=$((100 - free_space))

            if [ "$free_space" -lt "$MIN_FREE_SPACE" ]; then
                echo "✗ 备份目录空间不足: $dir (剩余 ${free_space}%,低于 ${MIN_FREE_SPACE}%)"
                send_alert "备份监控报警: 磁盘空间不足" "备份目录 $dir 空间不足,剩余 ${free_space}%。"
                issues=$((issues + 1))
            else
                echo "✓ 备份目录空间充足: $dir (剩余 ${free_space}%)"
            fi

            # 检查最新备份文件
            local latest_backup=$(find "$dir" -name "*.dump*" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -d' ' -f2-)
            if [ -n "$latest_backup" ]; then
                local backup_age=$(($(date +%s) - $(stat -c %Y "$latest_backup")))
                local backup_age_days=$((backup_age / 86400))

                if [ "$backup_age_days" -gt "$ALERT_THRESHOLD_DAYS" ]; then
                    echo "✗ 最新备份文件过旧: $(basename "$latest_backup") (${backup_age_days} 天前)"
                    issues=$((issues + 1))
                else
                    echo "✓ 找到有效备份文件: $(basename "$latest_backup") (${backup_age_days} 天前)"
                fi
            else
                echo "⚠ 备份目录中未找到备份文件: $dir"
            fi
        else
            echo "⚠ 备份目录不存在: $dir"
        fi
    done

    # 检查dump命令
    if command -v dump >/dev/null 2>&1; then
        echo "✓ dump命令可用"
    else
        echo "✗ dump命令不可用"
        send_alert "备份监控报警: dump命令缺失" "系统未安装dump备份工具。"
        issues=$((issues + 1))
    fi

    # 检查restore命令
    if command -v restore >/dev/null 2>&1; then
        echo "✓ restore命令可用"
    else
        echo "✗ restore命令不可用"
        issues=$((issues + 1))
    fi

    # 生成报告
    echo ""
    echo "=== 检查完成 ==="
    echo "发现的问题: $issues 个"

    if [ "$issues" -eq 0 ]; then
        echo "✓ 备份系统状态: 健康"
    elif [ "$issues" -le 2 ]; then
        echo "⚠ 备份系统状态: 警告(${issues}个问题)"
    else
        echo "✗ 备份系统状态: 危险(${issues}个问题)"
        send_alert "备份监控报警: 系统危险" "备份系统发现 ${issues} 个严重问题,请立即检查。"
    fi

    return $issues
}

# 备份验证测试
test_backup_integrity() {
    echo ""
    echo "=== 备份文件完整性测试 ==="

    local backup_files=$(find /backup -name "*.dump" -type f | head -3)
    local tested=0
    local passed=0

    for backup in $backup_files; do
        tested=$((tested + 1))
        echo -n "测试 $(basename "$backup")... "

        if restore -t -f "$backup" >/dev/null 2>&1; then
            echo "✓ 通过"
            passed=$((passed + 1))
        else
            echo "✗ 失败"
            send_alert "备份监控报警: 备份文件损坏" "备份文件 $(basename "$backup") 可能已损坏。"
        fi
    done

    if [ "$tested" -gt 0 ]; then
        echo "完整性测试: $passed/$tested 通过"
    else
        echo "未找到可测试的备份文件"
    fi
}

# 性能检查
check_performance() {
    echo ""
    echo "=== 备份性能统计 ==="

    # 检查最近备份的统计信息
    if [ -f /etc/dumpdates ]; then
        echo "最近备份统计:"
        tail -5 /etc/dumpdates | while read line; do
            echo "  $line"
        done
    fi

    # 检查备份目录大小
    if [ -d /backup ]; then
        local total_size=$(du -sh /backup 2>/dev/null | cut -f1)
        local file_count=$(find /backup -name "*.dump*" -type f 2>/dev/null | wc -l)
        echo "备份目录统计:"
        echo "  总大小: $total_size"
        echo "  文件数: $file_count"
    fi
}

# 主程序
main() {
    log "开始备份系统检查"

    echo "备份监控系统 v1.0"
    echo "======================"

    check_backup_status
    test_backup_integrity
    check_performance

    log "备份系统检查完成"

    echo ""
    echo "详细信息请查看日志: $LOG_FILE"
    echo "报警邮件发送到: $ALERT_EMAIL"
}

# 执行
main 2>&1 | tee -a "$LOG_FILE"

注意事项

重要注意事项:
  • root权限:dump需要root权限访问原始块设备,普通用户无法使用
  • 文件系统类型:只支持ext2、ext3、ext4文件系统,不支持XFS、Btrfs等其他文件系统
  • 备份时状态:备份时文件系统应卸载或以只读方式挂载,否则可能导致数据不一致
  • 增量备份依赖:增量备份依赖于之前的备份,丢失任一备份会导致恢复失败
  • 备份记录文件:/etc/dumpdates记录备份历史,删除或损坏会影响增量备份
  • 恢复顺序:恢复时必须按正确顺序:0级 → 1级 → 2级 → ...
  • 磁盘空间:确保有足够空间存放备份文件,全盘备份需要接近原大小的空间
  • 定期测试:定期测试备份文件的恢复能力,确保备份有效
  • 加密注意:如果使用加密备份,必须安全保管密钥,否则无法恢复

常见问题

A: dump和dd都是备份工具,但工作方式不同:
对比项 dump dd
备份对象 文件系统(ext2/3/4) 块设备(任何类型)
备份级别 文件级,支持增量 块级,完全复制
空间效率 高(只备份使用块) 低(备份整个分区)
恢复灵活性 可选择文件恢复 必须全盘恢复
跨平台 有限(仅Linux) 广泛
使用建议:
# 使用dump的场景:
# 备份ext文件系统,需要增量备份,节省空间
dump -0u -f /backup/system.dump /dev/sda1

# 使用dd的场景:
# 备份整个磁盘(包括分区表),克隆系统,备份非ext文件系统
dd if=/dev/sda of=/backup/disk.img bs=4M
dd if=/dev/sda1 of=/backup/partition.img bs=4M

# 特殊场景:使用dd备份MBR
dd if=/dev/sda of=/backup/mbr.bak bs=512 count=1

# 特殊场景:使用dump备份/home目录
dump -0u -f /backup/home.dump /dev/sda2

A: dump不支持XFS和Btrfs,需要使用其他工具:
  • XFS文件系统:使用xfsdumpxfsrestore
  • Btrfs文件系统:使用btrfs sendbtrfs receive
  • 通用方案:使用tarrsync
示例:
# XFS文件系统备份
xfsdump -l 0 -f /backup/xfs_backup.dump /dev/sdb1
xfsrestore -f /backup/xfs_backup.dump /mnt/restore

# Btrfs文件系统备份
# 创建只读快照
btrfs subvolume snapshot -r /data /data/snapshot
# 发送快照到文件
btrfs send /data/snapshot | gzip > /backup/btrfs_backup.img.gz
# 恢复
gzip -dc /backup/btrfs_backup.img.gz | btrfs receive /mnt/restore

# 使用tar备份任意文件系统
tar -czf /backup/data.tar.gz /data
tar -xzf /backup/data.tar.gz -C /mnt/restore

# 使用rsync增量备份
rsync -av --delete /source/ /backup/destination/
# 恢复
rsync -av /backup/destination/ /mnt/restore/

# 如果必须使用dump,可以先转换文件系统
# 警告:这会丢失所有数据!
umount /dev/sdb1
mkfs.ext4 /dev/sdb1
# 现在可以使用dump备份

建议:选择与文件系统匹配的备份工具以获得最佳效果。

A: 可以通过cron定时任务自动化dump备份:
  • 创建备份脚本:编写包含所有备份逻辑的shell脚本
  • 配置cron:使用crontab设置定时执行
  • 日志管理:记录备份日志便于排查问题
  • 监控报警:设置失败报警机制
完整自动化示例:
# 1. 创建备份脚本 /usr/local/bin/backup.sh
#!/bin/bash
# 自动备份脚本

BACKUP_DIR="/backup"
LOG_FILE="/var/log/backup.log"

# 记录开始时间
echo "=== 备份开始: $(date) ===" >> "$LOG_FILE"

# 执行完全备份(每周日)
if [ $(date +%u) -eq 7 ]; then
    echo "执行完全备份..." >> "$LOG_FILE"
    dump -0u -f "$BACKUP_DIR/full_$(date +%Y%m%d).dump" /dev/sda1 2>&1 >> "$LOG_FILE"
    status=$?
else
    # 执行增量备份
    level=1
    echo "执行增量备份(级别 $level)..." >> "$LOG_FILE"
    dump -${level}u -f "$BACKUP_DIR/inc_$(date +%Y%m%d).dump" /dev/sda1 2>&1 >> "$LOG_FILE"
    status=$?
fi

# 检查备份结果
if [ $status -eq 0 ]; then
    echo "✓ 备份成功: $(date)" >> "$LOG_FILE"
else
    echo "✗ 备份失败: $(date)" >> "$LOG_FILE"
    # 发送报警邮件
    echo "备份失败,请检查系统" | mail -s "备份失败报警" admin@example.com
fi

echo "=== 备份结束: $(date) ===" >> "$LOG_FILE"

# 2. 给脚本执行权限
chmod +x /usr/local/bin/backup.sh

# 3. 配置cron定时任务
# 编辑root的crontab:sudo crontab -e
# 添加以下行:
# 每天凌晨2点执行备份
# 0 2 * * * /usr/local/bin/backup.sh

# 4. 查看cron日志
# 查看备份是否执行
grep backup /var/log/cron.log
grep "备份开始" /var/log/backup.log

# 5. 可选:使用anacron处理关机时的错过任务
# 安装anacron
sudo apt install anacron
# 配置/etc/anacrontab
# 添加:1 5 backup /usr/local/bin/backup.sh

# 6. 监控脚本
# 创建监控脚本检查备份是否运行
#!/bin/bash
# 监控备份是否在24小时内执行过
LAST_BACKUP=$(grep "备份成功" /var/log/backup.log | tail -1 | cut -d: -f2-)
if [ -z "$LAST_BACKUP" ]; then
    echo "警告: 从未执行过备份" | mail -s "备份监控报警" admin@example.com
else
    LAST_TIME=$(date -d "$LAST_BACKUP" +%s 2>/dev/null || echo 0)
    CURRENT_TIME=$(date +%s)
    HOURS_DIFF=$(( (CURRENT_TIME - LAST_TIME) / 3600 ))

    if [ "$HOURS_DIFF" -gt 24 ]; then
        echo "警告: 超过24小时未备份" | mail -s "备份监控报警" admin@example.com
    fi
fi

建议:结合日志轮转和监控报警,构建完整的备份自动化系统。

相关命令

restore

恢复dump备份:

restore -r -f backup.dump
restore -i -f backup.dump
restore -t -f backup.dump
restore -x -f backup.dump /path/to/file
tar

通用归档工具:

tar -czf backup.tar.gz /data
tar -xzf backup.tar.gz
tar -tjf backup.tar.gz
tar -cvf backup.tar /data
rsync

增量同步工具:

rsync -av /source/ /backup/
rsync -av --delete /src/ /dst/
rsync -avz -e ssh /src/ user@host:/dst/
dd

块设备复制:

dd if=/dev/sda of=disk.img
dd if=disk.img of=/dev/sda
dd if=/dev/zero of=file bs=1M count=100