first build nexus
This commit is contained in:
347
Technical/Home Office/🟠Ubuntu服务器通过rsync实现日常增量备份.md
Normal file
347
Technical/Home Office/🟠Ubuntu服务器通过rsync实现日常增量备份.md
Normal file
@@ -0,0 +1,347 @@
|
||||
|
||||
#ubuntu #rsync #backup #nas
|
||||
|
||||
```table-of-contents
|
||||
```
|
||||
|
||||
既然你已经完成了 **Clonezilla** 的整机镜像备份,现在引入 **rsync** 实现日常的增量备份是构建“工作室级”数据保护体系的最后一步。
|
||||
|
||||
作为技术背景深厚且需要管理 TikTok 业务数据的用户,rsync 的优势在于它可以**不关机**运行,并且只传输**变化过**的文件。
|
||||
|
||||
### 1. 核心逻辑与准备
|
||||
|
||||
**目标**:将 Ubuntu 服务器的实时数据(代码、Docker 配置、业务数据)增量同步到已经挂载好的 NAS 目录(`/mnt/nas_backup`)。
|
||||
|
||||
**挂载检查**: 在开始前,请确保你的 NAS 已经挂载成功(你之前提到 Samba 挂载已经成功):
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
df -h | grep nas_backup
|
||||
```
|
||||
|
||||
_如果输出显示了 NAS 的 IP 和空间信息,则可以继续。_
|
||||
|
||||
### 2. 编写 Rsync 自动化脚本
|
||||
|
||||
不要直接在命令行输入长命令,建议创建一个专门的脚本。
|
||||
|
||||
**创建脚本文件**:
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo nano /usr/local/bin/rsync_backup.sh
|
||||
```
|
||||
|
||||
**粘贴以下内容(已根据你的 ZBook 环境优化)**:
|
||||
|
||||
|
||||
> [!NOTE] 此为最终可运行版本
|
||||
|
||||
``` bash
|
||||
#!/bin/bash
|
||||
|
||||
LOCKFILE="/tmp/rsync_backup.lock"
|
||||
if [ -e ${LOCKFILE} ] && kill -0 `cat ${LOCKFILE}`; then
|
||||
echo "备份任务已在运行中,跳过本次执行。"
|
||||
exit
|
||||
fi
|
||||
echo $$ > ${LOCKFILE}
|
||||
trap "rm -f ${LOCKFILE}" EXIT
|
||||
|
||||
# --- 配置区 ---
|
||||
MOUNT_POINT="/mnt/nas_backup"
|
||||
DATE=$(date +%Y-%m-%d)
|
||||
DEST="$MOUNT_POINT/docker_backups/$DATE"
|
||||
LOG="/var/log/rsync_backup.log"
|
||||
|
||||
# --- 1. 挂载检查 ---
|
||||
if ! mountpoint -q "$MOUNT_POINT"; then
|
||||
echo "$(date): [错误] NAS 未挂载" >> "$LOG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$DEST"
|
||||
|
||||
# --- 2. 执行精确备份 ---
|
||||
echo "--- 开始备份 Docker 数据: $(date) ---" >> "$LOG"
|
||||
|
||||
# 优化后的参数:
|
||||
# -v: 显示详情 (方便初次调试)
|
||||
# --exclude: 排除 Python 虚拟环境、__pycache__ 和 git 目录
|
||||
rsync -azR --delete \
|
||||
--exclude="venv/" \
|
||||
--exclude=".venv/" \
|
||||
--exclude="**/__pycache__/" \
|
||||
--exclude=".git/" \
|
||||
/var/lib/docker/volumes/ \
|
||||
/etc/docker/ \
|
||||
/home/shenwei/Docker/ \
|
||||
"$DEST/" >> "$LOG" 2>&1
|
||||
|
||||
# --- 3. 状态检查 ---
|
||||
# rsync 返回 23 表示部分文件由于权限或消失未传输,这在备份正在运行的系统时常见。
|
||||
# 我们重点看是否大部分数据已同步。
|
||||
if [ $? -eq 0 ] || [ $? -eq 23 ] || [ $? -eq 24 ]; then
|
||||
echo "--- 备份完成: $(date) ---" >> "$LOG"
|
||||
else
|
||||
echo "--- 备份异常中止,错误码: $? ---" >> "$LOG"
|
||||
fi
|
||||
```
|
||||
|
||||
**赋予执行权限**:
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo chmod +x /usr/local/bin/rsync_backup.sh
|
||||
```
|
||||
|
||||
### 3. 设置定时任务 (Crontab)
|
||||
|
||||
作为跨境电商业务,建议在凌晨 3 点(业务低峰期)执行自动备份。
|
||||
|
||||
1. **打开定时任务配置**:
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo crontab -e
|
||||
```
|
||||
|
||||
2. **在文件末尾添加一行**:
|
||||
|
||||
Plaintext
|
||||
|
||||
```
|
||||
0 3 * * * /usr/local/bin/rsync_backup.sh
|
||||
```
|
||||
|
||||
_这代表每天 03:00 自动运行备份脚本。_
|
||||
|
||||
### 4. 关键点:Docker 数据的备份
|
||||
|
||||
由于你使用了大量自动化技术支持 TikTok 业务,**Docker 卷(Volumes)** 是最核心的数据。
|
||||
|
||||
- **路径**:默认在 `/var/lib/docker/volumes`。
|
||||
|
||||
- **一致性**:如果备份的是数据库(如 MySQL),建议在脚本开头加入 `docker exec <容器名> mysqldump ...` 导出 SQL 文件,再由 rsync 同步。因为直接同步正在写入的二进制数据库文件可能导致恢复后无法启动。
|
||||
|
||||
### 5. 如何在灾难时还原?
|
||||
|
||||
- **单个文件丢失**:直接去 `/mnt/nas_backup/daily_sync` 下通过 `cp` 或 `rsync` 拷贝回来。
|
||||
- **系统崩溃但能进 SSH**:反向执行 rsync 命令:
|
||||
Bash
|
||||
```
|
||||
# 注意路径顺序颠倒
|
||||
sudo rsync -aAXz /mnt/nas_backup/daily_sync/ /
|
||||
```
|
||||
- **硬盘彻底坏了**:先用你之前的 **Clonezilla** 镜像恢复整个系统,然后用 **rsync** 将最新的增量数据同步回来,即可实现“时间点恢复”。
|
||||
### 💡 建议
|
||||
|
||||
鉴于你对技术细节的关注,你可以尝试运行一次手动备份来测试性能:
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo nohup /usr/local/bin/rsync_backup.sh > /dev/null 2>&1 &
|
||||
```
|
||||
|
||||
然后查看日志:`tail -f /var/log/rsync_backup.log`。
|
||||
|
||||
|
||||
### 5. 如何实现NFS永久挂载
|
||||
|
||||
在 Linux 系统中,手动执行的 `mount` 命令是**临时性**的,重启后内核会重置所有挂载状态。要实现开机自动挂载,必须将配置写入系统的文件系统表文件 `/etc/fstab`。
|
||||
|
||||
由于你使用的是 **NFS** 协议,且考虑到笔记本在启动时网络初始化可能略慢于磁盘挂载,我们需要加入一些特定的参数来确保稳定性。
|
||||
|
||||
#### 1. 准备凭据(可选但推荐)
|
||||
|
||||
NFS 通常基于 IP 授权,不需要账号密码。如果你之前确认过手动挂载 `sudo mount -t nfs 192.168.3.17:/volume2/backup /mnt/nas_backup` 成功且无需密码,可以跳过此步。
|
||||
|
||||
#### 2. 修改 /etc/fstab 实现永久挂载
|
||||
|
||||
1. **备份原文件**(作为资深管理者,备份配置是标准操作):
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo cp /etc/fstab /etc/fstab.bak
|
||||
```
|
||||
|
||||
2. **编辑文件**:
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo nano /etc/fstab
|
||||
```
|
||||
|
||||
3. **在文件末尾添加以下一行**:
|
||||
|
||||
Plaintext
|
||||
|
||||
```
|
||||
192.168.3.17:/volume2/backup /mnt/nas_backup nfs defaults,timeo=900,retrans=5,_netdev 0 0
|
||||
```
|
||||
|
||||
|
||||
#### 参数详解:
|
||||
|
||||
- **`defaults`**: 使用默认的挂载参数(rw, suid, dev, exec, auto, nouser, async)。
|
||||
|
||||
- **`timeo=900`**: 设置超时时间为 90 秒(单位是 1/10 秒)。
|
||||
|
||||
- **`retrans=5`**: 如果超时,尝试重连 5 次。
|
||||
|
||||
- **`_netdev`**: **关键参数**。告诉系统这是一个网络设备,务必等到网络服务完全启动后再尝试挂载,防止开机过程因找不到网络而卡死。
|
||||
|
||||
|
||||
---
|
||||
|
||||
#### 3. 测试配置(非常重要)
|
||||
|
||||
**千万不要直接重启!** 如果 `/etc/fstab` 写错了,系统可能无法正常启动。
|
||||
|
||||
执行以下命令验证:
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
# 1. 先卸载当前的挂载(如果当前还挂着的话)
|
||||
sudo umount /mnt/nas_backup
|
||||
|
||||
# 2. 模拟开机自动挂载
|
||||
sudo mount -a
|
||||
|
||||
# 3. 检查是否挂载成功
|
||||
df -h | grep nas_backup
|
||||
```
|
||||
|
||||
**如果 `sudo mount -a` 没有报错,且 `df` 能看到 NAS 空间,那么以后重启服务器,挂载都会自动生效。**
|
||||
|
||||
---
|
||||
|
||||
#### 4. 进阶:针对 Rsync 脚本的安全保护
|
||||
|
||||
在你的 `rsync` 脚本(`/usr/local/bin/rsync_backup.sh`)开头,建议加入一个**挂载检查**。防止在 NAS 掉线或由于某种原因挂载失败时,`rsync` 把备份数据写到了本地硬盘的挂载点目录(会导致笔记本硬盘迅速爆满)。
|
||||
|
||||
在脚本的配置区下方加入这段逻辑:
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
# 检查挂载点是否是一个有效的挂载
|
||||
if ! mountpoint -q /mnt/nas_backup; then
|
||||
echo "错误:NAS 未挂载,备份任务取消!" >> /var/log/rsync_backup.log
|
||||
# 在这里可以加入发送通知给你的逻辑
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 5. 常见问题:重启后仍然失效?
|
||||
|
||||
如果在执行了上述操作后重启依然不生效,通常是因为 Ubuntu 的 `nfs-common` 服务启动慢于 `mount -a` 的执行。
|
||||
|
||||
- **对策**:你可以启动 `Remote File Systems` 目标服务:
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo systemctl enable remote-fs.target
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 如何停止rsync进程
|
||||
|
||||
#### 1. 查找并杀死相关的 rsync 进程
|
||||
|
||||
你可以通过 `pgrep` 或 `ps` 命令锁定正在运行的备份任务。
|
||||
|
||||
- **查看当前运行的 rsync 进程:**
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
ps aux | grep rsync
|
||||
```
|
||||
|
||||
- **优雅地停止所有 rsync 进程(推荐):** 发送 `SIGTERM` 信号,允许 `rsync` 完成当前的写入并清理临时文件,防止损坏目标端的数据结构。
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo killall rsync
|
||||
```
|
||||
|
||||
- **强制杀死(如果进程卡死):** 如果执行 `killall` 后进程依然存在(通常是因为网络 I/O 挂起),请使用 `SIGKILL`。
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo killall -9 rsync
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
#### 2. 停止后台运行的脚本
|
||||
|
||||
由于你是通过脚本 `rsync_backup.sh` 启动的,有时只杀掉 `rsync` 进程,脚本可能会尝试进入循环或执行后续逻辑。
|
||||
|
||||
- **查找并杀掉备份脚本进程:**
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo pkill -f rsync_backup.sh
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
#### 3. 清理残留的临时文件
|
||||
|
||||
`rsync` 在传输过程中会在目标目录(NAS 挂载点)生成以 `.` 开头的临时文件。
|
||||
|
||||
- 如果你强行停止了进程,这些临时文件会残留在 `/mnt/nas_backup/daily_sync/` 中。
|
||||
|
||||
- 下一次运行 `rsync` 时,它通常会自动处理或覆盖这些文件,但如果你想手动清理:
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
# 注意:请确保没有 rsync 进程在运行时执行此操作
|
||||
sudo find /mnt/nas_backup/daily_sync/ -name ".*" -type f -delete
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
#### 4. 针对日志中 SIGINT/SIGTERM 报错的建议
|
||||
|
||||
从你之前的日志看,系统收到了 `code 20` 错误,这通常就是因为进程被手动中断导致的。
|
||||
|
||||
**为了防止下次备份时再次因为手动关闭终端而中断,建议采用以下两种方式之一运行:**
|
||||
|
||||
1. **使用 `nohup` (你已经在尝试的方式):**
|
||||
|
||||
Bash
|
||||
|
||||
```
|
||||
sudo nohup /usr/local/bin/rsync_backup.sh > /dev/null 2>&1 &
|
||||
```
|
||||
|
||||
2. **使用 `screen` 或 `tmux` (更专业):**
|
||||
|
||||
- 创建一个新窗口:`screen -S backup`
|
||||
|
||||
- 运行脚本:`sudo /usr/local/bin/rsync_backup.sh`
|
||||
|
||||
- 按下 `Ctrl + A + D` 脱离窗口(脚本继续运行)。
|
||||
|
||||
- 随时回来查看:`screen -r backup`
|
||||
Reference in New Issue
Block a user