ESC

开始输入,可搜索发票、服务、域名、工单,以及 更多...

搜索... Ctrl+K
Linux 服务器

Linux 服务器备份教程:rsync 异地备份、tar 定时备份、MySQL 数据库备份与 restic 备份到 S3

5 个步骤 12 分钟阅读 3 次阅读 0
本文目录

硬盘故障、误删文件、被入侵勒索都可能让数据瞬间丢失,可靠的 Linux 服务器备份是运维的底线。本文给出四种互相补充的方案:rsync 同步到另一台服务器、tar + cron 定时打包、MySQL/MariaDB 数据库自动备份与轮转、restic 加密备份到 S3 兼容对象存储,最后演示如何验证恢复。命令适用于 Debian/Ubuntu 与 Rocky Linux/AlmaLinux。

建议遵循 3-2-1 原则:至少 3 份数据、2 种介质、1 份在异地。只放在同一块磁盘上的备份无法防止硬盘损坏或整机被入侵。需要第二台服务器或更大的数据盘存放备份,可联系客服确认配置。

步骤 1:用 rsync 备份到另一台服务器

rsync 只传输变化的部分,适合网站目录、配置文件等的增量同步。先在备份机上创建普通用户 backup 和目录 /backup/web01,再在源服务器上生成专用 SSH 密钥(密钥登录可参考“SSH 密钥”教程)。--delete 会删除目标端多余的文件,第一次务必用 -n 预演。

# Install rsync on BOTH servers
apt install -y rsync        # Debian / Ubuntu
dnf install -y rsync        # Rocky Linux / AlmaLinux

# On the source server: dedicated key for backups
ssh-keygen -t ed25519 -f /root/.ssh/backup_key -N ""
ssh-copy-id -i /root/.ssh/backup_key.pub -p 22 [email protected]

# Preview first (-n = dry run), then run for real
rsync -aHn --delete -e "ssh -i /root/.ssh/backup_key -p 22" \
  /etc /var/www [email protected]:/backup/web01/
rsync -aH --delete -e "ssh -i /root/.ssh/backup_key -p 22" \
  /etc /var/www [email protected]:/backup/web01/

步骤 2:tar + cron 定时打包备份

rsync 是“镜像”,源端误删后同步一次备份端也会被删除;因此再配合 tar 每天生成带日期的压缩包,保留最近 7 天。脚本用 find -mtime 自动清理旧文件,然后写入 crontab 每天凌晨执行。

cat > /usr/local/bin/backup-files.sh <<'EOF'
#!/bin/bash
set -euo pipefail
DEST=/backup/files
KEEP_DAYS=7
mkdir -p "$DEST"
# tar exit code 1 = "file changed while reading", which is acceptable
tar -czpf "$DEST/files-$(date +%F).tar.gz" /etc /var/www /root || [ $? -eq 1 ]
find "$DEST" -name 'files-*.tar.gz' -mtime +$KEEP_DAYS -delete
EOF
chmod 700 /usr/local/bin/backup-files.sh
/usr/local/bin/backup-files.sh && ls -lh /backup/files

# Schedule: crontab -e
10 3 * * * /usr/local/bin/backup-files.sh >> /var/log/backup.log 2>&1

步骤 3:MySQL/MariaDB 数据库自动备份与轮转

直接复制正在运行的数据库文件很可能得到损坏的备份,正确做法是用 mysqldump 或 mariadb-dump 导出。--single-transaction 对 InnoDB 表做一致性快照且不锁表;脚本会逐个库导出并 gzip 压缩,保留 14 天。密码写在权限 600 的 /root/.my.cnf 中,避免出现在命令行与进程列表里。

# Credentials (skip if root can log in to MariaDB/MySQL via unix_socket)
cat > /root/.my.cnf <<'EOF'
[client]
user=root
password=YourDatabaseRootPassword
EOF
chmod 600 /root/.my.cnf

cat > /usr/local/bin/backup-db.sh <<'EOF'
#!/bin/bash
set -euo pipefail
DEST=/backup/mysql
KEEP_DAYS=14
mkdir -p "$DEST"
CLIENT=$(command -v mariadb || command -v mysql)
DUMP=$(command -v mariadb-dump || command -v mysqldump)
for DB in $("$CLIENT" -N -e "SHOW DATABASES" | grep -Ev '^(information_schema|performance_schema|sys)$'); do
  "$DUMP" --single-transaction --routines --triggers --events "$DB" \
    | gzip > "$DEST/$DB-$(date +%F_%H%M).sql.gz"
done
find "$DEST" -name '*.sql.gz' -mtime +$KEEP_DAYS -delete
EOF
chmod 700 /usr/local/bin/backup-db.sh

# Schedule: crontab -e
20 2 * * * /usr/local/bin/backup-db.sh >> /var/log/backup.log 2>&1

步骤 4:用 restic 加密备份到 S3 兼容存储

restic 支持去重、加密和快照,可备份到 AWS S3、Cloudflare R2、MinIO 等任意 S3 兼容存储。上一步生成的数据库备份目录也一并上传,即可实现异地保存。forget --prune 按日/周/月策略保留快照并释放空间。

# Install restic
apt install -y restic                                   # Debian / Ubuntu
dnf install -y epel-release && dnf install -y restic    # Rocky / AlmaLinux

# Repository settings for an S3-compatible bucket
cat > /root/.restic.env <<'EOF'
export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY
export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
export RESTIC_REPOSITORY=s3:https://s3.example.com/my-backup-bucket/web01
export RESTIC_PASSWORD_FILE=/root/.restic.pass
EOF
openssl rand -base64 32 > /root/.restic.pass
chmod 600 /root/.restic.env /root/.restic.pass

. /root/.restic.env
restic init
restic backup /etc /var/www /backup/mysql
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic snapshots

# Schedule: crontab -e
40 3 * * * { . /root/.restic.env && restic backup -q /etc /var/www /backup/mysql && restic forget -q --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune; } >> /var/log/restic.log 2>&1
restic 仓库密码丢失后数据无法恢复,请把 /root/.restic.pass 和 S3 密钥另外保存在安全的地方(例如密码管理器),不要只存在被备份的服务器上。

步骤 5:定期测试备份恢复

没有验证过的备份不能算备份。建议每月至少做一次恢复演练:解压文件到临时目录、把数据库导入测试库核对数据量、用 restic check 检查仓库完整性。也可以在一台新服务器上完整恢复一次,记录所需时间。

# Files: list an archive and extract one directory to a temp folder
tar -tzf /backup/files/files-2026-10-01.tar.gz | head
mkdir -p /tmp/restore
tar -xzf /backup/files/files-2026-10-01.tar.gz -C /tmp/restore etc/nginx

# Database: import into a throw-away database and compare
mysql -e "CREATE DATABASE restore_test"
gunzip -c /backup/mysql/shop-2026-10-01_0220.sql.gz | mysql restore_test
mysql -e "SELECT COUNT(*) FROM restore_test.orders"
mysql -e "DROP DATABASE restore_test"

# restic: verify the repository and restore the latest snapshot
. /root/.restic.env
restic check
restic restore latest --target /tmp/restic-restore --include /etc/nginx

常见问题

备份占满了磁盘怎么办?

调小 KEEP_DAYS,排除缓存、日志等无需备份的目录(tar 用 --exclude),并尽量把备份转移到另一台服务器或对象存储。磁盘清理方法见“磁盘空间不足”教程。

cron 任务没有执行?

检查 /var/log/backup.log 和 journalctl -u cron(Rocky 为 crond)。cron 的 PATH 很短,脚本中请使用完整路径,并确认脚本有执行权限。

数据库很大,导出时会影响网站吗?

InnoDB 加 --single-transaction 不会锁表,但会占用磁盘 I/O,建议放在访问低峰执行;超大库可考虑 mariadb-backup 或 Percona XtraBackup 做物理热备。

如果按以上步骤操作后问题仍未解决,请提交工单联系 IMIDC 7×24 技术支持,并附上服务器 IP、系统版本、执行过的命令和完整报错信息,方便工程师快速定位。

这篇文章有帮助吗?

相关教程