内网跨服务器定时同步指定数据库最新备份

前言

在企业内网环境中,数据库备份的异地容灾是保障数据安全的核心环节。本文针对两台已安装宝塔面板的内网服务器(192.168.3.1 为源服务器,192.168.3.2 为目标服务器),实现仅同步指定数据库(database_1)的最新备份文件的需求,全程基于宝塔面板可视化操作 + Shell 脚本,无需复杂命令行运维,适合运维新手和中小企业使用。

本文核心目标

  1. 配置源服务器免密登录目标服务器,实现无人值守传输;
  2. 编写 Shell 脚本,精准筛选database_1的最新备份文件;
  3. 借助宝塔计划任务,实现定时自动同步 + 自动清理旧备份。

前置条件

  1. 两台服务器内网互通(可通过ping 192.168.3.2在 3.1 上测试);
  2. 宝塔面板已正常安装,且源服务器已配置好longxincrm2数据库的自动备份(宝塔默认备份路径:/www/backup/database)。

第一步:配置源服务器(3.1)免密登录目标服务器(3.2)

脚本中使用scp传输文件时,若未配置免密,会因需要手动输入密码导致定时任务执行失败。这是实现无人值守的核心前提 ,操作全程在3.1 的宝塔终端完成。

1.1 生成 SSH 密钥对

  1. 登录192.168.3.1的宝塔面板,点击左侧【终端】,进入命令行界面;
  2. 执行密钥生成命令,全程回车,不设置密码(设置密码会破坏免密逻辑):
bash 复制代码
ssh-keygen -t rsa

执行完成后,会在/root/.ssh目录下生成两个文件:id_rsa(私钥,本地保留)、id_rsa.pub(公钥,需传至目标服务器)。

1.2 推送公钥至目标服务器(3.2)

1、执行公钥推送命令,将 3.1 的公钥发送到 3.2 的 root 用户下:

bash 复制代码
ssh-copy-id root@192.168.3.2

2、首次执行会提示确认服务器指纹,输入yes并回车;

3、输入3.2 的 root 密码,回车后即可完成公钥推送。

1.3 验证免密登录是否成功

执行以下命令,尝试登录 3.2:

bash 复制代码
ssh root@192.168.3.2

无需输入密码直接进入 3.2 的命令行 ,说明免密配置成功;输入exit即可退出 3.2,返回 3.1 终端。

特殊情况:SSH 端口非默认 22 时的处理

若你的宝塔服务器修改了 SSH 默认端口(如改为 2222),需在上述命令中添加端口参数:

bash 复制代码
# 生成密钥后,推送公钥时指定端口
ssh-copy-id -p 2222 root@192.168.3.2

# 验证免密时指定端口
ssh -p 2222 root@192.168.3.2

第二步:编写同步的 Shell 脚本

2.1 在计划任务中添加shell脚本,如下图:

bash 复制代码
#!/bin/bash
# 脚本功能:同步192.168.3.1上database_1的最新数据库备份到192.168.3.2,并清理3.2上7天前的旧备份
# 配置项(根据实际情况修改,若SSH端口非22,仅需修改SCP_PORT)
DB_NAME="database_1"                  # 需同步的数据库名
BACKUP_DIR="/www/backup/database"     # 宝塔默认数据库备份目录
REMOTE_USER="root"                    # 目标服务器用户名
REMOTE_HOST="192.168.3.2"             # 目标服务器内网IP
REMOTE_DIR="/www/backup/database"     # 目标服务器备份存储目录
SCP_PORT="22"                         # SSH端口,默认22,修改过则改为实际端口

# 1. 筛选database_1的最新备份文件
# 匹配规则:db_数据库名_时间戳.sql.gz(宝塔自动备份的文件格式)
LATEST_FILE=$(ls -t ${BACKUP_DIR}/db_${DB_NAME}_*.sql.gz 2>/dev/null | head -1)

# 2. 检查是否找到备份文件
if [ -z "$LATEST_FILE" ]; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] 错误:未找到${DB_NAME}的备份文件!" >> /www/backup/sync_backup.log
    exit 1
fi

echo "[$(date +'%Y-%m-%d %H:%M:%S')] 找到最新备份文件:${LATEST_FILE}" >> /www/backup/sync_backup.log

# 3. 传输最新备份文件到目标服务器
if scp -P ${SCP_PORT} "${LATEST_FILE}" ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] 备份文件传输成功!" >> /www/backup/sync_backup.log
else
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] 错误:备份文件传输失败!" >> /www/backup/sync_backup.log
    exit 1
fi

# 4. 清理目标服务器上7天前的database_1旧备份(保留7天,可修改+7为其他天数)
ssh -p ${SCP_PORT} ${REMOTE_USER}@${REMOTE_HOST} "find ${REMOTE_DIR}/db_${DB_NAME}_*.sql.gz -mtime +7 -delete"
if [ $? -eq 0 ]; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] 成功清理${REMOTE_HOST}上7天前的${DB_NAME}旧备份" >> /www/backup/sync_backup.log
else
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] 警告:清理${REMOTE_HOST}旧备份失败!" >> /www/backup/sync_backup.log
fi

# 脚本执行完成
exit 0

2.2 手动执行测试(关键步骤)

配置完成后,不要直接等待定时执行,先手动测试脚本是否正常运行:

  1. 在计划任务列表中,找到刚创建的任务,点击右侧【执行】;
  2. 点击【查看日志】,查看执行结果;
  3. 同时登录 3.2 的宝塔面板,进入/www/backup/database目录,检查是否出现database_1的最新备份文件。
  • 执行成功:日志中显示 "找到最新备份文件""传输成功""清理旧备份成功";
  • 执行失败:根据日志中的 "错误提示" 排查(如免密配置失败、路径不存在、端口错误)。

第三步:验证与日常维护

3.1 容灾验证

每周手动登录 3.2 服务器,检查备份文件的完整性 (文件大小与 3.1 一致)和时效性(每天都有最新文件),并尝试恢复备份到测试库,验证备份可用。

3.2 日志查看

脚本执行日志会保存在 3.1 的/www/backup/sync_backup.log,若出现同步失败,优先查看该日志定位问题。

常见问题排查

  1. scp 传输失败,提示 "Permission denied"

    • 原因:免密配置未成功,或 SSH 端口填写错误;
    • 解决:重新执行ssh-copy-id,并核对脚本中的SCP_PORT
  2. 未找到备份文件

    • 原因:宝塔的数据库自动备份未执行,或备份文件名格式与脚本匹配规则不符;
    • 解决:检查宝塔计划任务中的 "备份数据库" 任务是否执行,核对DB_NAME是否与实际数据库名一致。
  3. 清理旧备份失败

    • 原因:目标服务器的/www/backup/database目录权限不足;
    • 解决:在 3.2 的宝塔终端执行chmod 755 /www/backup/database

总结

本文通过SSH 免密配置 + 精准筛选 Shell 脚本 + 宝塔计划任务的组合,完美解决了 "宝塔内网服务器仅同步指定数据库最新备份" 的需求。整个方案无需脱离宝塔面板,操作简单、稳定性高,既保证了数据的异地容灾,又避免了无效备份文件的冗余存储。

对于多数据库、多服务器的同步场景,仅需复制脚本并修改DB_NAMEREMOTE_HOST,即可快速扩展,适合中小企业批量部署。

相关推荐
J超会运2 小时前
从零部署Nginx:Web全栈实战指南
运维·前端·nginx
锋风Fengfeng2 小时前
远程服务器运行Android Studio开发aosp源码
android·服务器·android studio
乾元2 小时前
本地大模型:如何在内网部署 Llama/Qwen 等安全增强模型
运维·网络·人工智能·安全·机器学习·llama·安全架构
流水迢迢lst2 小时前
Linux概述及基础命令
linux·运维·服务器
醇氧2 小时前
Window 查看是否安装wsl
linux·运维·服务器
cyw89982 小时前
docker 安装 ollama 并运行
运维·docker·容器
进击切图仔2 小时前
docker compose 的简单使用
运维·docker·容器
ljh5746491192 小时前
chomd 命令的解释和常用用法和高级用法
linux·运维·服务器
Johnstons2 小时前
当网络运维遇上全流量回溯:一次关于「看得见」的实践
运维·网络