标签搜索

目 录CONTENT

文章目录

🛡️Linux 服务器数据备份指南:rsync + cron 自动化增量备份教程

yyzq
2026-08-05 / 0 评论 / 1 点赞 / 52 阅读 / 2,200 字
广告 广告

📌 前言

服务器数据无价,无论是网站、数据库还是 Docker 容器数据,一旦丢失后果不堪设想。本文介绍最经典的 Linux 服务器间数据备份方案——rsync + cron,实现增量自动备份到远程服务器。

🔍 rsync 是什么?

rsync(remote synchronize)是 Linux 下最强大的数据同步工具,核心优势:

  • 增量传输:只传输变化的部分,大幅节省带宽
  • 支持压缩:传输过程压缩数据,速度更快
  • 保持属性:保留文件权限、时间戳、软链接等
  • 支持排除:可排除指定文件/目录
  • SSH 加密:通过 SSH 传输,安全可靠

📐 环境准备

角色 说明 示例
源服务器 A 需要备份数据的机器 192.168.1.100
目标服务器 B 存放备份的机器 192.168.1.200

两台机器都需要安装 rsync,大多数 Linux 发行版已预装。

准备2台服务器

我们使用莱卡云VPS来演示
需要vps的可以看以下信息,
莱卡云官网

🎯 总结流程

linux-backup-demo-1785936563619

源服务器A ──── rsync over SSH ────→ 目标服务器B
/data/app/                          /backup/app/
     │                                   │
     └──── cron 定时触发 ────────────────┘
步骤 操作
1 安装 rsync
2 配置 SSH 免密登录
3 编写备份脚本
4 设置 cron 定时任务
5 定期检查日志和验证备份

💡 核心优势:rsync 增量传输只同步变化部分,对带宽和网络压力极小,适合长期稳定运行。

安装 rsync

# Debian/Ubuntu
apt update && apt install -y rsync

# CentOS/RHEL/AlmaLinux
yum install -y rsync

# Arch Linux
pacman -S rsync

验证安装

rsync --version
# rsync  version 3.2.7  protocol version 31

🔑 配置 SSH 免密登录

备份是自动化任务,不能每次都手动输密码,所以先配好 SSH 密钥认证。

1. 在源服务器 A 上生成密钥

# 如果已有密钥可跳过
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519

2. 推送公钥到目标服务器 B

# 默认22端口
ssh-copy-id root@192.168.1.200

# 自定义端口(如7722)
ssh-copy-id -p 7722 root@192.168.1.200

3. 验证免密登录

# 应该直接登录成功,不需要输入密码
ssh root@192.168.1.200 "echo connected"

# 自定义端口
ssh -p 7722 root@192.168.1.200 "echo connected"

⚠️ 如果使用了自定义端口,后续所有 rsync 命令都需要加 -e "ssh -p 端口" 参数。

📂 在目标服务器创建备份目录

# 在服务器 B 上执行
mkdir -p /backup/app
mkdir -p /backup/mysql
mkdir -p /backup/docker

🚀 rsync 基础用法

命令格式

rsync [选项] 源路径 目标路径

常用选项

选项 说明
-a 归档模式(保留权限、时间戳、软链接等)
-v 显示详细输出
-z 传输时压缩数据
-P 显示进度+支持断点续传
--delete 删除目标中源端已不存在的文件(完全镜像)
--exclude 排除指定文件/目录
-e 指定远程shell(如自定义SSH端口)

最常用的备份命令

# 把服务器A的 /data/app 目录同步到服务器B的 /backup/app
rsync -avz --delete /data/app/ root@192.168.1.200:/backup/app/

🔔 注意尾随斜杠

  • /data/app/(有斜杠)= 同步 app 目录里的内容
  • /data/app(无斜杠)= 同步 app 目录本身

备份场景建议加尾随斜杠。

自定义 SSH 端口

rsync -avz --delete -e "ssh -p 7722" /data/app/ root@192.168.1.200:/backup/app/

排除特定文件

# 排除日志和临时文件
rsync -avz --delete \
  --exclude='*.log' \
  --exclude='tmp/' \
  --exclude='.cache/' \
  /data/app/ root@192.168.1.200:/backup/app/

排除文件列表(大量排除规则时)

# 创建排除规则文件
cat > /etc/rsync-exclude.txt << 'EOF'
*.log
*.tmp
tmp/
.cache/
node_modules/
*.pid
EOF

# 使用 --exclude-from 引用
rsync -avz --delete --exclude-from='/etc/rsync-exclude.txt' \
  /data/app/ root@192.168.1.200:/backup/app/

🔄 实战场景

场景一:备份网站数据

rsync -avz --delete \
  --exclude='*.log' \
  --exclude='.git/' \
  /www/wwwroot/mysite/ \
  root@192.168.1.200:/backup/mysite/

场景二:备份 Docker 数据

rsync -avz --delete \
  --exclude='*.log' \
  /var/lib/docker/volumes/ \
  root@192.168.1.200:/backup/docker-volumes/

场景三:备份前先导出数据库

# 先导出MySQL数据库
mysqldump -u root -p'你的密码' --all-databases > /tmp/all_db.sql

# 再同步到远程
rsync -avz /tmp/all_db.sql root@192.168.1.200:/backup/mysql/

场景四:SQLite 数据库备份

# 先用SQLite的.backup命令安全备份(比直接复制更安全)
sqlite3 /data/app/onenav.db3 ".backup '/tmp/onenav_backup.db3'"

# 同步到远程
rsync -avz /tmp/onenav_backup.db3 root@192.168.1.200:/backup/db/

⏰ 配置 cron 自动定时备份

编写备份脚本

cat > /root/backup.sh << 'BACKUP_EOF'
#!/bin/bash
# ===== 配置区域 =====
REMOTE_IP="192.168.1.200"
REMOTE_PORT="22"
REMOTE_USER="root"
BACKUP_DIR="/backup"

# 备份任务列表(源路径:目标子目录名)
TASKS=(
    "/www/wwwroot/mysite/:mysite"
    "/data/docker/:docker"
    "/root/scripts/:scripts"
)

# 日志文件
LOG_FILE="/var/log/backup.log"

# ===== 执行区域 =====
echo "========================================" >> $LOG_FILE
echo "备份开始: $(date '+%Y-%m-%d %H:%M:%S')" >> $LOG_FILE

for TASK in "${TASKS[@]}"; do
    SRC="${TASK%%:*}"
    DST="${TASK##*:}"
    
    echo ">>> 同步 $SRC -> $REMOTE_IP:$BACKUP_DIR/$DST" >> $LOG_FILE
    
    rsync -avz --delete \
        --exclude='*.log' \
        --exclude='.git/' \
        --exclude='*.tmp' \
        --exclude='.cache/' \
        -e "ssh -p $REMOTE_PORT" \
        "$SRC" "$REMOTE_USER@$REMOTE_IP:$BACKUP_DIR/$DST/" >> $LOG_FILE 2>&1
    
    if [ $? -eq 0 ]; then
        echo "✅ $DST 备份成功" >> $LOG_FILE
    else
        echo "❌ $DST 备份失败" >> $LOG_FILE
    fi
done

echo "备份结束: $(date '+%Y-%m-%d %H:%M:%S')" >> $LOG_FILE
echo "" >> $LOG_FILE
BACKUP_EOF
chmod +x /root/backup.sh

设置定时任务

crontab -e

添加以下内容:

# 每天凌晨3点执行备份
0 3 * * * /root/backup.sh

# 如果想每12小时备份一次
0 */12 * * * /root/backup.sh

# 如果想每小时备份一次(高频场景)
0 * * * * /root/backup.sh

查看定时任务

crontab -l

📋 cron 时间表达式速查

┌──────── 分钟 (0-59)
│ ┌────── 小时 (0-23)
│ │ ┌──── 日 (1-31)
│ │ │ ┌── 月 (1-12)
│ │ │ │ ┌ 星期 (0-7, 0和7都是周日)
│ │ │ │ │
* * * * * 命令
表达式 说明
0 3 * * * 每天凌晨3点
0 */6 * * * 每6小时
0 3 * * 1 每周一凌晨3点
0 0 1 * * 每月1号零点
*/30 * * * * 每30分钟

📊 日志与监控

查看备份日志

tail -50 /var/log/backup.log

日志自动轮转

cat > /etc/logrotate.d/backup << 'EOF'
/var/log/backup.log {
    weekly
    rotate 4
    compress
    missingok
    notifempty
    create
}
EOF

备份结果通知(可选)

backup.sh 末尾加上通知,通过 Telegram Bot 推送:

# 在 backup.sh 的末尾添加
SUCCESS_COUNT=$(grep "✅" $LOG_FILE | tail -${#TASKS[@]} | wc -l)
FAIL_COUNT=$(grep "❌" $LOG_FILE | tail -${#TASKS[@]} | wc -l)

MESSAGE="📋 备份报告
时间: $(date '+%Y-%m-%d %H:%M:%S')
成功: ${SUCCESS_COUNT} / ${#TASKS[@]}
失败: ${FAIL_COUNT} / ${#TASKS[@]}"

# Telegram推送(替换为你的Bot Token和Chat ID)
curl -s -X POST "https://api.telegram.org/bot你的TOKEN/sendMessage" \
  -d "chat_id=你的CHAT_ID" \
  -d "text=$MESSAGE"

🔐 服务器安全建议

限制 SSH 权限

如果只为 rsync 使用,可以在服务器 B 的 ~/.ssh/authorized_keys 中限制来源 IP 和命令:

# 编辑服务器B的 authorized_keys
from="192.168.1.100",command="rsync --server" ssh-ed25519 AAAA...公钥内容...

这样即使密钥泄露,也只能从指定 IP 执行 rsync 命令。

防火墙限制

# 服务器B只允许服务器A的SSH连接
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.100 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

🔁 恢复数据

备份的意义在于能恢复。从目标服务器 B 恢复数据到源服务器 A:

# 反向同步(从B拉取到A)
rsync -avz root@192.168.1.200:/backup/app/ /data/app/

# 或者在服务器B上推送(推送到A)
rsync -avz /backup/app/ root@192.168.1.100:/data/app/

⚠️ 恢复时不要加 --delete,除非你确定要完全覆盖。

✅ 验证备份有效性

定期验证备份是否能用:

# 在服务器B上检查备份文件
ls -la /backup/app/
du -sh /backup/app/
find /backup/app/ -type f | wc -l

# 对比文件数量
find /data/app/ -type f | wc -l
1
广告 广告

评论区