首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >将服务器文件备份到本地NAS

将服务器文件备份到本地NAS

作者头像
逍遥子大表哥
发布2025-07-28 20:13:56
发布2025-07-28 20:13:56
20300
代码可运行
举报
文章被收录于专栏:kali blogkali blog
运行总次数:0
代码可运行

做好服务器重要文件的备份,是网络运维人日常工作之一。通常,我们是将文件备份到服务器本地,能否将其保存到网盘或者本地磁盘呢?

本文将以腾讯云服务器为例,讲解如何将重要的数据备份到本地NAS磁盘或者网盘。

实验环境

  • 腾讯云(公网服务器)
  • 9.9元的NAS (安装了Alist)

注意:本文采用了IPv6实现异网之间的互通,请分别配置两端的IPv6网络。

进入控制台 开启ipv6
进入控制台 开启ipv6

进入控制台 开启ipv6

我们可以利用ping命令检测公网服务器到你本地NAS的网络。

代码语言:javascript
代码运行次数:0
运行
复制
ping -6  nb.com

安装cadaver

cadaver的是Linux中常用的命令行WebDAV客户端。支持文件上载,下载,屏幕显示,名称空间操作(移动和复制),集合创建和删除以及锁定操作。

代码语言:javascript
代码运行次数:0
运行
复制
yum install cadaver
#debian系统
apt-get install cadaver

连接测试

代码语言:javascript
代码运行次数:0
运行
复制
cadaver https://nas.nb.cn:5244/dav #这里我直接用了alist的dav

上传脚本

脚本说明:

  • 备份数据库到.sql文件
  • 压缩为tar.gz
  • 上传到NAS的指定目录
  • NAS保留最新的三个备份文件(服务器不存放)
代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash

# MySQL配置
DB_USER="root"
DB_PASSWORD="admin" #你的数据库密码
DB_NAMES=("blog" "bbs") #要备份的数据库

# Alist认证配置
WEBDAV_USER="admin"
WEBDAV_PASS="admin==" #alist 密码

# WebDAV地址配置
NAS_HOST="nas.nb.cn:5246" #alist webdav地址
BASE_PATH="/dav"
REMOTE_DIR="本地磁盘/数据备份/数据库"

# 编码处理(关键改进)
urlencode() {
    echo -n "$1" | xxd -plain | tr -d '\n' | sed 's/\(..\)/%\1/g'
}
encoded_pass=$(urlencode "${WEBDAV_PASS}")
encoded_remote_dir=$(echo -n "${REMOTE_DIR}" | sed 's/ /%20/g; s/\//%2F/g')

# 调试设置(输出到终端和日志)
exec > >(tee webdav_debug.log) 2>&1

# 创建临时工作目录
BACKUP_DIR=$(mktemp -d)
trap 'rm -rf "${BACKUP_DIR}"' EXIT

# ========== 数据库备份部分 ==========
echo "开始数据库备份..."
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
COMPRESSED_FILE="${BACKUP_DIR}/db_backup_${TIMESTAMP}.tar.gz"
SQL_FILES=()

for DB in "${DB_NAMES[@]}"; do
    SQL_FILE="${BACKUP_DIR}/${DB}_${TIMESTAMP}.sql"
    echo "备份数据库: ${DB}"
    if ! mysqldump -u"${DB_USER}" -p"${DB_PASSWORD}" --single-transaction "${DB}" > "${SQL_FILE}"; then
        echo "❌ 数据库 ${DB} 备份失败!"
        exit 1
    fi
    SQL_FILES+=("${SQL_FILE}")
done

# ========== 压缩部分 ==========
echo "压缩备份文件..."
if ! tar -czf "${COMPRESSED_FILE}" -C "${BACKUP_DIR}" "${SQL_FILES[@]##*/}"; then
    echo "❌ 压缩失败!"
    exit 1
fi

# 验证压缩文件
if [ ! -s "${COMPRESSED_FILE}" ]; then
    echo "❌ 压缩文件为空或不存在!"
    exit 1
fi
echo "压缩文件大小: $(du -h ${COMPRESSED_FILE} | cut -f1)"

# ========== WebDAV 上传部分 ==========
# 构建完整URL(关键改进)
UPLOAD_URL="https://${NAS_HOST}${BASE_PATH}/${encoded_remote_dir}/$(basename ${COMPRESSED_FILE})"
echo "完整上传路径: ${UPLOAD_URL}"

# 分步目录创建(Alist需要层级创建)
IFS='/' read -ra dir_parts <<< "${REMOTE_DIR}"
current_path=""
for part in "${dir_parts[@]}"; do
    current_path="${current_path}/${part}"
    encoded_part=$(urlencode "${part}")
    mkcol_url="https://${NAS_HOST}${BASE_PATH}/${encoded_path}${encoded_part}"
    echo "创建目录层级: ${mkcol_url}"
    curl -k -u "${WEBDAV_USER}:${WEBDAV_PASS}" -X MKCOL "${mkcol_url}" -s -o /dev/null
done

# 上传文件(带详细日志)
echo "正在上传..."
http_status=$(curl -k -u "${WEBDAV_USER}:${WEBDAV_PASS}" -w "%{http_code}" -T "${COMPRESSED_FILE}" "${UPLOAD_URL}" -s -o /dev/null)

if [ "${http_status}" -eq 201 ] || [ "${http_status}" -eq 204 ]; then
    echo "✅ 上传成功 (HTTP状态码: ${http_status})"
else
    echo "❌ 上传失败 (HTTP状态码: ${http_status})"
    echo "调试信息:"
    curl -k -v -u "${WEBDAV_USER}:${WEBDAV_PASS}" -T "${COMPRESSED_FILE}" "${UPLOAD_URL}" -s
    exit 1
fi

# ========== 清理旧备份 ==========
echo "清理旧备份..."
backup_list=$(curl -k -u "${WEBDAV_USER}:${WEBDAV_PASS}" -X PROPFIND \
-H "Depth: 1" "https://${NAS_HOST}${BASE_PATH}/${encoded_remote_dir}/" 2>/dev/null | \
grep -oP '<d:href>.*?db_backup_.*?\.tar\.gz</d:href>' | \
sed 's/<d:href>//g; s/<\/d:href>//g' | \
sort -r | \
awk -F/ '{print $NF}')

echo "当前备份列表:"
echo "${backup_list}"

old_files=$(echo "${backup_list}" | tail -n +4)
for file in ${old_files}; do
    echo "删除旧备份: ${file}"
    delete_url="https://${NAS_HOST}${BASE_PATH}/${encoded_remote_dir}/${file}"
    curl -k -u "${WEBDAV_USER}:${WEBDAV_PASS}" -X DELETE "${delete_url}"
done

echo "✅ 所有操作完成"

注意:

如果上传报错,或者无法成功。请手动上传文件,检测网络和配置是否存在问题。

代码语言:javascript
代码运行次数:0
运行
复制
curl -k -u admin:admin== -T test.txt \
https://nas.nb.cn:5246/dav/本地磁盘/数据备份/数据库/test.txt
上传效果
上传效果

上传效果

存放效果
存放效果

最后,我们可以设置定时脚本。每三天执行一次备份。

代码语言:javascript
代码运行次数:0
运行
复制
0 3 */3 * * /root/mytool/sqlback.sh >> /var/log/sqlback.log 2>&1

如果要上传到网盘。请修改路劲REMOTE_DIR="本地磁盘/数据备份/数据库"即可!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 kali笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实验环境
  • 安装cadaver
  • 上传脚本
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档