一、总体架构
┌─────────────────────┐ ┌─────────────────────┐
│ CentOS 应用服务器 │ │ Windows 服务器 │
│ │ 445端口 │ │
│ 1. mongodump │ ──────▶ │ 共享目录 │
│ 备份到本地 │ smb协议 │ D:\backups\mongo │
│ 2. smbclient 上传 │ │ 专用备份账号 │
│ 3. 清理旧备份 │ │ │
└─────────────────────┘ └─────────────────────┘
│
│(如 MongoDB 在另一台机器)
▼
MongoDB 服务器 (27017)
部署顺序建议:先配 Windows → 再配 CentOS → 手动测试 → 加定时任务。
二、Windows 服务器配置
2.1 创建专用备份账号
不要用管理员账号做备份。创建一个专用本地账号,只给共享目录权限。
图形界面操作步骤:
Win + R输入lusrmgr.msc回车,打开「本地用户和组」- Windows Server 也可以:右键「此电脑」→「管理」→「计算机管理」→「本地用户和组」→「用户」
- 右键「用户」→「新用户」
- 用户名填
mongobak,设置一个强密码,描述可填「MongoDB备份专用账号」 - 取消勾选「用户下次登录时须更改密码」,勾选「密码永不过期」
- 点「创建」
注意:
- 这个账号不需要加入 Administrators 组,保持普通用户即可,权限最小化。
- 如果是 Windows 家庭版(没有 lusrmgr.msc),可用「设置 → 账户 → 其他用户」添加本地用户,或用管理员命令提示符执行
net user mongobak 密码 /add。
2.2 创建备份目录并设置共享
- 打开资源管理器,在 D 盘新建文件夹
backups,进入后再新建子文件夹mongomongo子目录对应脚本里的WIN_SUBDIR,名字要保持一致
- 右键
backups文件夹 →「属性」→「共享」选项卡 →「高级共享」 - 勾选「共享此文件夹」,共享名填
backups - 点「权限」按钮:
- 删除 Everyone
- 点「添加」→ 输入
mongobak→ 确定 - 给
mongobak勾选「完全控制」→ 确定
- 切到「安全」选项卡 →「编辑」→「添加」→ 输入
mongobak→ 确定- 给
mongobak勾选「修改」权限 → 确定
- 给
共享权限(第 4 步)和 NTFS 权限(第 5 步)两层都要设置,缺一不可。实际生效权限取两者的交集。
2.3 防火墙放行 SMB(445 端口)
- 打开「控制面板」→「系统和安全」→「Windows Defender 防火墙」
- 点左侧「高级设置」,打开「高级安全 Windows Defender 防火墙」
- 点左侧「入站规则」
- 在规则列表中找到「文件和打印机共享(SMB-In)」(专用/公用配置文件各一条)
- 右键 →「启用规则」
也可以在第 2 步点「允许应用或功能通过 Windows Defender 防火墙」,勾选「文件和打印机共享」。
2.4 验证共享
在任意一台 Windows 机器上,Win + R 输入:
\\192.168.1.10\backups
用 mongobak 账号登录,能进入并新建文件即成功。
也可以直接在 CentOS 上验证,见 3.4 节。
三、CentOS 应用服务器配置
3.1 安装必要软件
# 安装 smbclient(用于上传)
sudo yum install -y samba-client
# 安装 mongodb-database-tools(提供 mongodump/mongorestore)
# 先添加 MongoDB 官方源(以 7.0 为例,按你的服务端版本调整)
cat << 'EOF' | sudo tee /etc/yum.repos.d/mongodb-org-7.0.repo
[mongodb-org-7.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://pgp.mongodb.com/server-7.0.asc
EOF
sudo yum install -y mongodb-database-tools
# 验证
mongodump --version
smbclient --version
mongodump大版本最好与 MongoDB 服务端大版本一致,避免兼容问题。
3.2 创建本地备份目录
sudo mkdir -p /data/dbbackup
3.3 创建凭证文件
sudo mkdir -p /root/.smb
sudo tee /root/.smb/win_cred << 'EOF'
username=mongobak
password=你的备份账号密码
EOF
sudo chmod 600 /root/.smb/win_cred
- 密码改成你在 2.1 步设置的实际密码。
- 如果 Windows 服务器在域里,加一行
domain=域名;本地账号不用加。chmod 600必须做,否则凭证会被其他用户读到。
3.4 测试共享连通性
# 列目录测试(能列出 mongo 目录说明通了)
smbclient -m SMB3 "//192.168.1.10/backups" -A /root/.smb/win_cred -c "ls"
# 写入测试
echo "test" > /tmp/smb_test.txt
smbclient -m SMB3 "//192.168.1.10/backups" -A /root/.smb/win_cred \
-c "cd mongo; put /tmp/smb_test.txt smb_test.txt"
smbclient -m SMB3 "//192.168.1.10/backups" -A /root/.smb/win_cred \
-c "cd mongo; ls; del smb_test.txt"
如果这里报错,先解决再继续,常见报错见第五节排查表。
3.5 部署备份脚本
- 把脚本上传到服务器,例如
/opt/scripts/mongo_backup.sh - 修改脚本开头的配置区:
DB_HOST="127.0.0.1" # MongoDB 不在本机就改成它的 IP
DB_PORT="27017"
TARGET_DBS=("TestDB") # 要备份的数据库列表,空格分隔可写多个,如 ("TestDB" "OtherDB")
# 备份所有数据库则改成:TARGET_DBS=("ALL")
WIN_SHARE_IP="192.168.1.10" # 改成 Windows 服务器实际 IP
WIN_SHARE_PATH="backups"
WIN_SUBDIR="mongo"
- 注意换行符问题:如果脚本是在 Windows 上编辑后传过去的,行尾可能是 CRLF,运行会报「没有那个文件或目录」。先转换:
sudo yum install -y dos2unix
sudo dos2unix /opt/scripts/mongo_backup.sh
- 赋权并手动测试:
sudo chmod +x /opt/scripts/mongo_backup.sh
sudo /opt/scripts/mongo_backup.sh
- 检查两处结果:
- 本地
/data/dbbackup/下有TestDB_backup_xxx.gzip - Windows 的
D:\backups\mongo\下有同名文件
- 本地
3.6 配置定时任务
sudo crontab -e
添加一行(每天凌晨 2 点备份,日志追加到文件):
0 2 * * * /opt/scripts/mongo_backup.sh >> /var/log/mongo_backup.log 2>&1
查看日志:
tail -50 /var/log/mongo_backup.log
3.7 MongoDB 在其他机器时的额外检查
如果 DB_HOST 不是 127.0.0.1,需要确认:
MongoDB 的
bindIp允许应用服务器访问,在mongod.conf中:net: bindIp: 127.0.0.1,192.168.x.x # 加上 MongoDB 服务器的内网 IP改完重启 mongod。
MongoDB 服务器防火墙放行 27017 给应用服务器:
sudo firewall-cmd --permanent --new-zone=mongo sudo firewall-cmd --permanent --zone=mongo --add-source=应用服务器IP/32 sudo firewall-cmd --permanent --zone=mongo --add-port=27017/tcp sudo firewall-cmd --reload如果 MongoDB 开了认证,在脚本里填
DB_USER/DB_PASS,该账号至少需要backup角色或对目标库的读权限。
四、恢复数据的方法
# 从本地备份恢复
mongorestore --host 127.0.0.1 --port 27017 \
--gzip --archive=/data/dbbackup/TestDB_backup_20260825_020000.gzip \
--db TestDB --drop
# 文件在 Windows 共享上时,先拉回来再恢复
smbclient -m SMB3 "//192.168.1.10/backups" -A /root/.smb/win_cred \
-c "cd mongo; get TestDB_backup_20260825_020000.gzip /tmp/restore.gzip"
mongorestore --gzip --archive=/tmp/restore.gzip --db TestDB --drop
--drop会先删除现有集合再恢复,生产环境慎用;恢复到新库名可以去掉--db改用--nsFrom/--nsTo。
如果用的是ALL模式备份,恢复单个库时加--nsInclude过滤,例如--nsInclude="TestDB.*"。
五、常见问题排查
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
无法执行 xxx.sh: 没有那个文件或目录(文件明明存在) |
脚本带 Windows 换行符(CRLF) | dos2unix 或 sed -i 's/\r$//' 转换,见 3.5 节 |
NT_STATUS_ACCESS_DENIED |
账号密码错 / 没共享权限 / NTFS 权限不足 | 核对凭证文件;检查共享权限和「安全」选项卡都有 mongobak |
NT_STATUS_LOGON_FAILURE |
密码错误或账号被锁 | 在 Windows 上重置密码,同步更新凭证文件 |
NT_STATUS_BAD_NETWORK_NAME |
共享名不对 | smbclient -L //IP -A 凭证 列出所有共享核对名字 |
| 连接超时 | 防火墙 / 445 不通 | telnet 192.168.1.10 445 测试;按 2.3 节放行文件和打印机共享 |
protocol negotiation failed |
SMB 协议协商失败 | 脚本已加-m SMB3;确认 Windows 没禁用 SMB3 |
| 中文目录乱码 | 系统 locale 不对 | 脚本已强制 UTF-8;确认 CentOS 装了中文 locale |
| mongodump 连不上 | bindIp / 防火墙 / 认证 | 见 3.7 节 |
| 定时任务没执行 | cron 环境变量差异 | 脚本内用绝对路径;查看/var/log/mongo_backup.log 和 /var/log/cron |
六、安全建议
- 备份账号
mongobak不要加入任何管理员组,只对D:\backups有权限。 - 凭证文件必须
chmod 600,属 root。 - 备份文件包含业务数据,共享目录不要对 Everyone 开放。
- 建议定期(比如每季度)做一次恢复演练,确认备份文件真的可用。
- 本地只保留 7 天(
LOCAL_RETENTION_DAYS),共享保留 30 天(WIN_RETENTION_DAYS),可按磁盘容量调整。