发布于 

mongodb自动备份

使用 mongodump 结合 cron 任务来自动备份 MongoDB 数据库

查看mongodb安装位置,如果有用到

1
whereis mongod

安装 mongodump 工具

查看是否安装了mongodump

1
mongodump --version

如果没有安装

在 Debian/Ubuntu 上安装

1
2
sudo apt update
sudo apt install mongodb-clients

在 CentOS/RHEL 上安装

1
sudo yum install mongodb-org-tools

创建备份目录

创建一个用于存储备份文件的目录,并设置合适的权限

1
2
sudo mkdir -p /backup/mongodb
sudo chown -R $(whoami) /backup/mongodb # 或将所有者更改为对MongoDB有权限的用户,如mongodb

编写备份脚本 (Shell Script)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash

# 定义备份目录
BACKUP_DIR="/data/app/backup/mongodb"
# 定义日期格式
DATE=$(date +%Y%m%d_%H%M%S)
# 定义保留备份的天数
DAYS_TO_KEEP=5

# MongoDB 认证信息(如果启用了认证)
# MONGO_USER="your_username"
# MONGO_PASS="your_password"
# MONGO_AUTH_DB="admin" # 认证数据库,通常是 admin

# 创建当前备份的目录
mkdir -p $BACKUP_DIR/$DATE

# 执行 mongodump
# 如果无需认证,直接使用下面的命令
mongodump --out $BACKUP_DIR/$DATE

# 如果启用了认证,使用下面的命令(取消注释并替换你的信息)
# mongodump --username $MONGO_USER --password $MONGO_PASS --authenticationDatabase $MONGO_AUTH_DB --out $BACKUP_DIR/$DATE

# 压缩备份文件以节省空间
tar -czf $BACKUP_DIR/mongodb_backup_$DATE.tar.gz -C $BACKUP_DIR $DATE

# 删除压缩前的原始备份目录
rm -rf $BACKUP_DIR/$DATE

# 删除超过一定天数的旧备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +$DAYS_TO_KEEP -delete

# 输出备份完成信息
echo "MongoDB backup completed: $BACKUP_DIR/mongodb_backup_$DATE.tar.gz"

给脚本添加执行权限

1
sudo chmod +x /usr/local/bin/mongodb_backup.sh

配置 cron 定时任务

编辑当前用户的 cron 任务表

1
crontab -e

如果当前用户没有设置过,会让你选择编辑方式,输入数字即可选择

1
2
3
4
5
6
7
8
9
10
root@kremail-dev:/data/apps/backup# crontab -e
no crontab for root - using an empty one

Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed

Choose 1-4 [1]:

然后再次输入

1
crontab -e

添加一行配置来定时执行你的备份脚本。
例如,下面的例子表示每天凌晨 2 点执行备份脚本 ,直接新起一行放进去即可

1
0 2 * * * /usr/local/bin/mongodb_backup.sh >> /var/log/mongodb_backup.log 2>&1

退出编辑器后,运行以下命令,你应该能看到你刚添加的那行任务

1
crontab -l

可选)手动测试一次脚本:
为了万无一失,你可以手动执行一次脚本,看看它是否能正常运行,并观察日志文件是否生成

1
2
3
sh mongodb_backup.sh
# 查看日志
tail -f /var/log/mongodb_backup.log

如果报错:

1
2
3
root@kremail-dev:/data/apps/backup# sh mongodb_backup.sh
2025-09-01T07:52:00.596+0000 Failed: error creating intents to dump: error creating intents for database config: error getting collections for database `config`: (Unauthorized) not authorized on config to execute command { listCollections: 1, filter: {}, cursor: {}, lsid: { id: UUID("1255fd99-76ad-4d97-8b6b-1a8abcbd9697") }, $db: "config" }
MongoDB backup completed: /data/apps/backup/mongodb/mongodb_backup_20250901_075200.tar.gz

错误信息 (Unauthorized) not authorized on config to execute command { listCollections: 1… 表明你用来执行备份的MongoDB用户账号权限不足,无法读取 config 数据库的集合列表。config 数据库通常用于存储分片集群的元数据,对其进行备份需要特定权限

1
mongosh -u <你的管理员用户名>  -p --authenticationDatabase admin

例如

1
mongosh -u admin -p --authenticationDatabase admin

输入密码后执行

1
use admin
1
2
3
4
5
db.createUser({
user: "backupuser", // 备份用户名
pwd: "your_strong_password", // 设置一个强密码
roles: [ { role: "backup", db: "admin" } ] // 授予内置的backup角色
})

然后 ctrl+d退出MongoDB

修改备份脚本文件,再次执行然后成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@kremail-dev:/data/apps/backup# sh mongodb_backup.sh 
2025-09-01T08:00:19.345+0000 writing admin.system.users to /data/apps/backup/mongodb/20250901_080019/admin/system.users.bson
2025-09-01T08:00:19.346+0000 done dumping admin.system.users (2 documents)
2025-09-01T08:00:19.346+0000 writing admin.system.version to /data/apps/backup/mongodb/20250901_080019/admin/system.version.bson
2025-09-01T08:00:19.346+0000 done dumping admin.system.version (2 documents)
2025-09-01T08:00:19.346+0000 writing smart_email.emails to /data/apps/backup/mongodb/20250901_080019/smart_email/emails.bson
2025-09-01T08:00:19.346+0000 writing smart_email.failed_actions to /data/apps/backup/mongodb/20250901_080019/smart_email/failed_actions.bson
2025-09-01T08:00:19.346+0000 writing smart_email.processed_messages to /data/apps/backup/mongodb/20250901_080019/smart_email/processed_messages.bson
2025-09-01T08:00:19.347+0000 writing smart_email.memories to /data/apps/backup/mongodb/20250901_080019/smart_email/memories.bson
2025-09-01T08:00:19.351+0000 done dumping smart_email.memories (49 documents)
2025-09-01T08:00:19.353+0000 writing smart_email.experts to /data/apps/backup/mongodb/20250901_080019/smart_email/experts.bson
2025-09-01T08:00:19.356+0000 done dumping smart_email.processed_messages (1649 documents)
2025-09-01T08:00:19.356+0000 writing smart_email.generation_result to /data/apps/backup/mongodb/20250901_080019/smart_email/generation_result.bson
2025-09-01T08:00:19.356+0000 done dumping smart_email.experts (8 documents)
2025-09-01T08:00:19.357+0000 done dumping smart_email.generation_result (1 document)
2025-09-01T08:00:19.375+0000 done dumping smart_email.emails (1870 documents)
2025-09-01T08:00:19.414+0000 done dumping smart_email.failed_actions (38696 documents)
MongoDB backup completed: /data/apps/backup/mongodb/mongodb_backup_20250901_080019.tar.gz

验证备份

自动化流程搭建好后,定期验证其可靠性很重要,检查备份文件,查看备份目录中是否生成了压缩文件

1
ls -l /backup/mongodb/

验证备份完整性:定期尝试从备份文件中恢复数据到测试环境是验证备份是否有效的最佳方式。可以使用 mongorestore 命令

1
mongorestore --drop --gzip --archive=/backup/mongodb/mongodb_backup_20250901_020000.tar.gz

注意事项

权限问题:确保执行 cron 任务的用户对备份目录、脚本文件以及 MongoDB 数据库本身有必要的读写和执行权限。
资源占用:巨大的数据库备份可能会在备份期间暂时影响 MongoDB 服务器性能。可以考虑在业务低峰期安排备份任务。
监控与日志:定期检查 /var/log/mongodb_backup.log(或你自定义的日志路径),确保备份任务正在按时运行且没有错误。
远程与离线存储:为应对服务器本地灾难(如硬盘损坏),最好将备份文件复制到远程服务器或云存储(例如用 rsync, scp 或使用 rclone 同步到云)。
安全:如果备份脚本中包含数据库密码,请确保只有足够权限的用户才能读取该脚本 (chmod 700 /usr/local/bin/mongodb_backup.sh)

其他问题,任务没有被执行

系统重启后,一般情况下cron任务会继续执行,因为cron服务通常会自动随系统启动。但为了确保可靠,最好检查一下cron服务的状态。

1
sudo systemctl status cron

如果状态显示为 inactive 或 dead,你需要启动它

1
2
sudo systemctl start cron   # 启动cron
sudo systemctl enable cron # 设置开机自启(可选,确保重启后自动运行)

如果服务已运行但任务仍不执行,可以尝试重启cron服务以重新加载配置

1
2
3
4
5
6
7
sudo systemctl restart cron
```[1,7](@ref)

#### 2. 查看系统日志
Cron任务的执行情况通常会被记录在系统日志中,这是排查问题最直接的方式。使用以下命令查看与cron相关的日志条目:
```bash
grep CRON /var/log/syslog

检查脚本权限与路径

1
chmod +x /data/apps/backup/mongodb_backup.sh

路径问题:虽然在你的crontab中脚本路径是绝对路径,但要确保脚本内部所有命令也都使用绝对路径,或者已在脚本内部正确设置了环境变量(如PATH)。因为cron执行时的环境变量与用户登录shell不同

检查时间与时区

1
date

查看系统日志

1
grep CRON /var/log/syslog

结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
root@kremail-prod:/data/apps/backup/mongodb# grep CRON /var/log/syslog
Sep 1 00:17:01 kremail-prod CRON[3779891]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 01:17:01 kremail-prod CRON[3788125]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 01:48:01 kremail-prod CRON[3793100]: (root) CMD ( test -x /etc/cron.daily/popularity-contest && /etc/cron.daily/popularity-contest --crond)
Sep 1 02:17:01 kremail-prod CRON[3797132]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 03:10:01 kremail-prod CRON[3804490]: (root) CMD (test -e /run/systemd/system || SERVICE_MODE=1 /sbin/e2scrub_all -A -r)
Sep 1 03:17:01 kremail-prod CRON[3805548]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 04:17:01 kremail-prod CRON[3813664]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 05:17:01 kremail-prod CRON[3821165]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 06:17:01 kremail-prod CRON[3829465]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 06:25:01 kremail-prod CRON[3830582]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ))
Sep 1 06:52:01 kremail-prod CRON[3834122]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ))
Sep 1 07:17:01 kremail-prod CRON[3836896]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 08:17:01 kremail-prod CRON[3844972]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 09:17:01 kremail-prod CRON[3853988]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 09:17:02 kremail-prod cron[3853993]: (CRON) INFO (pidfile fd = 3)
Sep 1 09:17:02 kremail-prod cron[3853993]: (CRON) INFO (Skipping @reboot jobs -- not system startup)
Sep 1 09:19:55 kremail-prod cron[3854182]: (CRON) INFO (pidfile fd = 3)
Sep 1 09:19:55 kremail-prod cron[3854182]: (CRON) INFO (Skipping @reboot jobs -- not system startup)
Sep 1 10:00:01 kremail-prod CRON[3859738]: (root) CMD (/data/apps/backup/mongodb_backup.sh >> /data/apps/backup/log/mongodb_backup.log 2>&1)
Sep 1 10:00:01 kremail-prod CRON[3859737]: (CRON) info (No MTA installed, discarding output)
Sep 1 10:16:38 kremail-prod cron[3862303]: (CRON) INFO (pidfile fd = 3)
Sep 1 10:16:38 kremail-prod cron[3862303]: (CRON) INFO (Skipping @reboot jobs -- not system startup)
Sep 1 10:17:01 kremail-prod CRON[3862312]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Sep 1 10:18:18 kremail-prod cron[3862390]: (CRON) INFO (pidfile fd = 3)
Sep 1 10:18:18 kremail-prod cron[3862390]: (CRON) INFO (Skipping @reboot jobs -- not system startup)
Sep 1 10:20:01 kremail-prod CRON[3862503]: (root) CMD (/data/apps/backup/mongodb_backup.sh >> /data/apps/backup/log/mongodb_backup.log 2>&1)
Sep 1 10:20:01 kremail-prod CRON[3862502]: (CRON) info (No MTA installed, discarding output)
Sep 1 10:58:06 kremail-prod cron[3868159]: (CRON) INFO (pidfile fd = 3)
Sep 1 10:58:06 kremail-prod cron[3868159]: (CRON) INFO (Skipping @reboot jobs -- not system startup)
Sep 1 11:00:01 kremail-prod CRON[3868291]: (root) CMD (/data/apps/backup/mongodb_backup.sh >> /data/apps/backup/log/mongodb_backup.log 2>&1)
Sep 1 11:00:01 kremail-prod CRON[3868290]: (CRON) info (No MTA installed, discarding output)

可以看到任务执行了,但是备份没有出来,回到对应目录,创建该任务的日志目录和日志文件,再次重启任务执行,功能正常

1
2
3
4
5
root@kremail-prod:/data/apps/backup# mkdir log
root@kremail-prod:/data/apps/backup# ls
log mongodb mongodb_backup.sh
root@kremail-prod:/data/apps/backup# cd log/
root@kremail-prod:/data/apps/backup/log# touch mongodb_backup.log