
做好服务器重要文件的备份,是网络运维人日常工作之一。通常,我们是将文件备份到服务器本地,能否将其保存到网盘或者本地磁盘呢?
本文将以腾讯云服务器为例,讲解如何将重要的数据备份到本地NAS磁盘或者网盘。
注意:本文采用了IPv6实现异网之间的互通,请分别配置两端的IPv6网络。

进入控制台 开启ipv6
我们可以利用ping命令检测公网服务器到你本地NAS的网络。
ping -6  nb.com

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

连接测试
cadaver https://nas.nb.cn:5244/dav #这里我直接用了alist的dav

脚本说明:
.sql文件tar.gz#!/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 "✅ 所有操作完成"
注意:
如果上传报错,或者无法成功。请手动上传文件,检测网络和配置是否存在问题。
curl -k -u admin:admin== -T test.txt \
https://nas.nb.cn:5246/dav/本地磁盘/数据备份/数据库/test.txt

上传效果

最后,我们可以设置定时脚本。每三天执行一次备份。
0 3 */3 * * /root/mytool/sqlback.sh >> /var/log/sqlback.log 2>&1
如果要上传到网盘。请修改路劲REMOTE_DIR="本地磁盘/数据备份/数据库"即可!