1. 项目概述:为什么Ubuntu 14.04下的MongoDB备份不是“点一下就完事”的事
在2015年前后,Ubuntu 14.04 LTS(Trusty Tahr)是大量中小型企业、初创团队和教学实验环境的主力系统——它稳定、社区支持强、软件源成熟,但它的生命周期早已结束(官方支持于2019年4月终止),这意味着你今天还在用它,大概率不是因为怀旧,而是因为一套跑在上面的老旧业务系统无法轻易迁移,比如一个基于PHP+MongoDB 2.4/2.6的老CMS、某高校实验室的定制化数据采集平台,或者某嵌入式设备管理后台。而MongoDB在那个年代默认不启用认证、不强制副本集、 mongodump 默认不压缩、备份路径权限常被忽略——这些都不是“配置错误”,而是那个技术阶段的真实约束。
我接手过三个真实案例:一所职校的实训平台因磁盘满导致 /var/lib/mongodb 被写爆,备份脚本却一直往同一分区写;一家本地电商把 mongodump 加进crontab,但没配 --out 绝对路径,结果每天生成一堆空目录;还有个更典型的——运维同学执行 mongorestore 时发现恢复速度极慢,查了一整天才发现他用的是 mongodump 导出的BSON文件,却误以为是JSON格式,反复用 mongoimport 重试。这些都不是操作失误,而是对Ubuntu 14.04 + MongoDB组合的技术边界缺乏系统性认知。
所以这篇内容不是教你怎么敲两条命令,而是带你回到那个技术语境里,搞清楚: 为什么 mongodump 在Ubuntu 14.04上必须指定 --dbpath 或连接URI?为什么 mongorestore 恢复时要特别注意 --drop 的触发时机?为什么一个看似简单的 sudo service mongodb restart 可能让备份瞬间失效? 它面向三类人:仍在维护老系统的运维工程师、需要复现历史实验环境的高校教师、以及想真正理解备份底层逻辑的数据库初学者。你不需要会写Shell脚本,但得明白每一步背后Linux进程、MongoDB锁机制和文件系统权限是怎么咬合的。
2. 整体设计思路:避开Ubuntu 14.04的三个经典陷阱
2.1 陷阱一:系统级服务管理与MongoDB进程状态的错位
Ubuntu 14.04默认使用Upstart管理服务,而MongoDB官方包(尤其是2.4.x系列)的Upstart配置文件 /etc/init/mongodb.conf 存在一个隐蔽问题:它定义的 start on 事件是 filesystem and net-device-up IFACE!=lo ,但实际启动时,MongoDB进程可能因 /var/lib/mongodb 目录权限不足(比如被 chown -R root:root 误操作过)而静默失败—— sudo service mongodb status 显示 start/running ,但 ps aux | grep mongod 却找不到进程。这时候你执行 mongodump ,得到的会是“connection refused”错误,而非直观的“服务未启动”。
我的解法从来不是重启服务,而是先验证进程真实状态:
# 不依赖service命令,直接查进程树
sudo ps aux | grep '[m]ongod'
# 检查MongoDB日志的最后10行(关键!)
sudo tail -10 /var/log/mongodb/mongodb.log
# 验证端口监听(Ubuntu 14.04默认bind_ip=127.0.0.1,不监听0.0.0.0)
sudo netstat -tuln | grep :27017
如果日志里出现 ERROR: dbpath (/var/lib/mongodb) does not exist 或 Permission denied ,说明Upstart启动脚本没帮你创建目录或修复权限——这正是Ubuntu 14.04时代最常被忽略的细节: 服务管理脚本不等于进程保障脚本 。你必须手动补全:
sudo mkdir -p /var/lib/mongodb
sudo chown -R mongodb:mongodb /var/lib/mongodb
sudo chmod 0755 /var/lib/mongodb
提示:
mongodb用户是Ubuntu包预建的系统用户,不能用root替代。我见过有人chown root:root后,mongod进程因权限过高被SELinux(如果启用)或AppArmor拦截,这种问题在14.04的AppArmor默认策略下极难排查。
2.2 陷阱二: mongodump 的默认行为与Ubuntu文件系统特性的冲突
mongodump 在Ubuntu 14.04上的默认行为有两大隐患:一是它默认将备份写入当前工作目录的 dump/ 子目录,而Ubuntu的 /home 分区往往独立于 / ,一旦 /home 空间不足,备份会中断且不报错;二是它默认不启用压缩(MongoDB 2.4不支持 --gzip ,2.6才加入),一个1GB的数据库导出后变成1.8GB的BSON文件,而Ubuntu 14.04的ext4文件系统在小文件写入时有额外开销,备份耗时翻倍。
我坚持用绝对路径+显式参数控制:
# 永远指定--out到有足够空间的分区,比如/data/backups
sudo mongodump --host 127.0.0.1:27017 --out /data/backups/mongo_$(date +%Y%m%d_%H%M)
# 如果是MongoDB 2.6+,强制启用gzip(节省50%空间,提升IO效率)
sudo mongodump --host 127.0.0.1:27017 --gzip --out /data/backups/mongo_$(date +%Y%m%d_%H%M)
这里的关键是 --host 参数——Ubuntu 14.04的 mongod 默认bind到127.0.0.1,不监听Unix socket( /tmp/mongodb-27017.sock ),所以 mongodump 若不指定 --host ,会尝试连接socket,失败后才fallback到localhost,这个过程增加200ms延迟,在批量备份时累积成分钟级浪费。
2.3 陷阱三: mongorestore 的原子性假象与数据一致性风险
很多人认为 mongorestore 是“一键还原”,但在Ubuntu 14.04+MongoDB 2.4/2.6组合下,它存在两个致命一致性漏洞:第一, --drop 参数不是事务性的,它先删库再导入,中间任何中断都会导致库为空;第二, mongorestore 默认按集合并发导入,但Ubuntu 14.04的默认ulimit(


1697

被折叠的 条评论
为什么被折叠?



