
1. 为什么现在还有人要在 CentOS 6.X 上装 MongoDB 4.0先把话说在前头CentOS 6 早就停止官方维护了MongoDB 4.0 也不是什么新版本。但现实情况是不少工厂产线、医院内网、政企离线环境里跑着的还是 CentOS 6.5 到 6.9 这一批老机器业务系统动不了可数据量又涨上来了原来的 MongoDB 2.6 或者 3.0 在并发和聚合查询上已经明显吃力。这时候最务实的做法不是换系统而是在现有环境里把 MongoDB 升到 4.0——它是最后一个官方还提供 CentOS 6 兼容包的稳定大版本再往上 4.2 就要求 glibc 2.17 以上CentOS 6 自带的 glibc 2.12 直接卡死。所以这篇东西解决的就是一个很具体的场景在一台不能重装、不能联网、glibc 版本偏低的 CentOS 6.X 机器上把 MongoDB 4.0 跑起来并且这套操作在 CentOS 7.X 上同样适用。我会把依赖库、yum 源、目录规划、配置文件、systemd 与 SysVinit 的差异、以及几个我实际踩过的坑都讲清楚。适合谁看适合手里有老服务器、需要做离线部署、或者正在做系统迁移前期验证的运维和后台开发。新手也能照着做因为每一步我都会说清楚为什么这么干。需要提前说明的是MongoDB 4.0 相比 3.x 引入了副本集事务、$convert类型转换、$toString等聚合操作符还有对 WiredTiger 存储引擎的进一步优化。这些特性在老业务里未必马上用得上但升级到 4.0 之后后续往 4.2、4.4 迁移的路径会顺畅很多因为 4.0 是官方明确支持滚动升级的中间跳板版本。换句话说这一步不是终点是给未来留后路。2. 安装前的环境盘点与依赖梳理2.1 先确认你的系统到底能不能装动手之前先跑几条命令把底摸清楚。很多人一上来就yum install结果报一堆依赖错误回头再查浪费时间。cat /etc/redhat-release uname -r ldd --version | head -1 free -h df -h /var第一条看系统版本CentOS 6.5 到 6.10 都在支持范围内。第二条看内核MongoDB 4.0 官方要求 Linux 内核 2.6.36 以上CentOS 6 的 2.6.32 其实略低于这个线但实测在 6.6 以后的内核上跑没问题因为 Red Hat 给 2.6.32 打了大量 backport 补丁。第三条看 glibc必须是 2.12 或更高CentOS 6 默认就是 2.12刚好卡在门槛上。第四条看内存MongoDB 4.0 的 WiredTiger 引擎默认会用掉可用内存的一半做缓存建议至少 2GB低于 1GB 的机器跑起来会非常难受。第五条看/var分区空间数据目录默认放这里别装到一半发现磁盘满了。提示如果你的 CentOS 6 是 6.0 到 6.4 这几个早期版本glibc 可能低于 2.12这种情况要么升级 glibc风险极高容易把系统搞崩要么放弃 4.0 改用 3.6。别硬上。2.2 依赖库和工具的准备MongoDB 4.0 的官方 RPM 包依赖几个基础库离线环境下这些必须提前备好。核心依赖是openssl、libcurl、cyrus-sasl和net-snmp如果启用 SNMP 监控。CentOS 6 自带的 openssl 是 1.0.1eMongoDB 4.0 需要 1.0.1 以上勉强够用但如果你的系统很久没更新建议先把 openssl 升到 1.0.2 系列避免 TLS 握手时出现协议不兼容。yum install -y openssl libcurl cyrus-sasl cyrus-sasl-plain net-snmp联网环境直接跑上面这条就行。离线环境的话你需要在一台同版本的联网机器上用yumdownloader把这些包和它们的依赖全部下载下来然后拷到目标机器上用rpm -ivh或者yum localinstall安装。这里有个经验yumdownloader --resolve会自动把依赖树拉全比手动一个个找靠谱得多。yumdownloader --resolve --destdir/tmp/mongo-deps openssl libcurl cyrus-sasl cyrus-sasl-plain net-snmp下载完把/tmp/mongo-deps整个目录打包拷过去目标机器上执行yum localinstall /tmp/mongo-deps/*.rpm即可。注意--resolve有时候会漏掉一些间接依赖装的时候如果报缺包再单独补下载。2.3 目录规划别把数据放在默认位置MongoDB 默认数据目录是/var/lib/mongo日志是/var/log/mongodb。生产环境我强烈建议单独规划原因有两个一是/var分区通常不大数据一涨就爆二是后续做备份、迁移、挂载独立磁盘时独立目录更好操作。我习惯的规划是这样的用途路径说明数据目录/data/mongodb/data挂独立数据盘权限 700日志目录/data/mongodb/log单独放方便切割配置目录/etc/mongod.conf保持默认位置二进制目录/usr/binRPM 安装自动放这里创建目录并授权mkdir -p /data/mongodb/data /data/mongodb/log chown -R mongod:mongod /data/mongodb chmod 700 /data/mongodb/data这里chmod 700是必须的MongoDB 启动时会检查数据目录权限如果其他用户可读可写它会拒绝启动并报permissions on /data/mongodb/data are too open。这个坑我见过太多次了尤其是用 root 手动创建目录之后忘了改权限。3. 安装 MongoDB 4.0 的完整实操流程3.1 配置 yum 源联网与离线两种方式联网环境下直接写一个 yum 源文件就行。MongoDB 官方源地址是repo.mongodb.org但老环境里经常遇到 TLS 版本协商失败的问题因为 CentOS 6 的 curl 和 openssl 太老。如果yum makecache报 SSL 错误可以临时用--nogpgcheck跳过校验或者改用国内镜像源。cat /etc/yum.repos.d/mongodb-org-4.0.repo EOF [mongodb-org-4.0] nameMongoDB Repository baseurlhttps://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/ gpgcheck1 enabled1 gpgkeyhttps://www.mongodb.org/static/pgp/server-4.0.asc EOF注意$releasever在 CentOS 6 上会解析成6正好对应官方源里的6目录。CentOS 7 上解析成7同样适用。这就是标题里说适用于 CentOS 7.X的原因——源地址的版本变量是通用的配置文件也基本一致差异只在服务管理方式上。离线环境就把 RPM 包直接下载好。官方提供两种包mongodb-org是元包会拉全套mongodb-org-server、mongodb-org-shell、mongodb-org-tools是分体包。离线部署建议下分体包按需安装省空间。# 联网机器上执行 yumdownloader --resolve --destdir/tmp/mongo-rpm mongodb-org-server-4.0.28 mongodb-org-shell-4.0.28 mongodb-org-tools-4.0.28版本号建议选 4.0 系列的最后一个版本 4.0.28bug 修复最全。下载完拷到目标机器rpm -ivh安装即可。3.2 安装过程与关键参数确认联网环境直接yum install -y mongodb-org-4.0.28 mongodb-org-server-4.0.28 mongodb-org-shell-4.0.28 mongodb-org-tools-4.0.28安装完成后RPM 会自动创建mongod用户和组并生成默认配置文件/etc/mongod.conf。这里有个细节CentOS 6 的 RPM 包默认用 SysVinit 脚本/etc/init.d/mongod来管理服务而 CentOS 7 用的是 systemd 单元/usr/lib/systemd/system/mongod.service。两者配置文件路径一样但启动命令不同。验证安装mongod --version mongo --version正常输出应该显示db version v4.0.28。如果报error while loading shared libraries: libcrypto.so.10说明 openssl 版本不对需要检查ldd $(which mongod)看具体缺哪个库。3.3 配置文件 mongod.conf 的逐项解读默认配置文件内容很简略生产环境必须改。我一般会改成下面这样systemLog: destination: file logAppend: true path: /data/mongodb/log/mongod.log storage: dbPath: /data/mongodb/data journal: enabled: true wiredTiger: engineConfig: cacheSizeGB: 1 processManagement: fork: true pidFilePath: /data/mongodb/mongod.pid net: port: 27017 bindIp: 127.0.0.1 security: authorization: disabled逐项说下为什么这么配。systemLog.logAppend: true让日志追加而不是覆盖方便排查历史问题。storage.journal.enabled: true是 WiredTiger 的预写日志保证崩溃恢复生产环境绝对不能关。cacheSizeGB默认是可用内存的一半但如果机器上还跑着别的服务手动限制到 1GB 到 2GB 更稳妥避免 MongoDB 把内存吃光导致系统 OOM。processManagement.fork: true让 mongod 以守护进程方式运行配合pidFilePath方便管理。net.bindIp默认只监听本地如果要远程访问改成0.0.0.0或者具体内网 IP但强烈建议配合防火墙和认证MongoDB 裸奔被挖矿的事情太多了。security.authorization先设为disabled等创建完管理员用户后再改成enabled。这个顺序不能反否则你连创建用户的权限都没有。注意CentOS 6 上如果启用了 SELinux需要额外处理。要么把 SELinux 设为 permissive要么给数据目录打上正确的上下文标签chcon -R -t mongod_var_lib_t /data/mongodb/data。我一般直接setenforce 0并改/etc/selinux/config为SELINUXpermissive因为老业务环境里 SELinux 带来的麻烦远大于收益。4. 启动服务与初始化配置4.1 CentOS 6 与 CentOS 7 的启动差异CentOS 6 用 SysVinitservice mongod start chkconfig mongod onCentOS 7 用 systemdsystemctl start mongod systemctl enable mongod启动后检查状态和日志tail -f /data/mongodb/log/mongod.log看到waiting for connections on port 27017就说明起来了。如果启动失败日志里通常会有明确原因常见的是目录权限、端口占用、配置文件语法错误。YAML 对缩进极其敏感必须用空格不能用 Tab这一点坑过无数人。4.2 创建管理员用户并开启认证先用 mongo shell 连进去mongo --host 127.0.0.1 --port 27017切换到 admin 库创建超级管理员use admin db.createUser({ user: siteAdmin, pwd: 换成你的强密码, roles: [ { role: userAdminAnyDatabase, db: admin }, readWriteAnyDatabase ] })创建完退出把配置文件里的authorization改成enabled重启服务。然后再连进去验证mongo -u siteAdmin -p --authenticationDatabase admin能进去就说明认证生效了。这里有个经验密码里如果包含、:、/这些特殊字符在连接字符串里需要 URL 编码否则会解析错误。我一般建议密码用大小写字母加数字加!、#、%这类避开 URL 保留字符。4.3 业务库和普通用户的创建管理员账号只用来管理业务连接要用单独的库和用户。比如给一个叫appdb的库建用户use appdb db.createUser({ user: appUser, pwd: 另一个强密码, roles: [ { role: readWrite, db: appdb } ] })这样即使这个账号泄露影响范围也只限于appdb。最小权限原则在老系统里尤其重要因为很多老业务代码里硬编码了连接串一旦泄露就是全库沦陷。5. 常见问题排查与避坑经验5.1 启动失败类问题速查现象可能原因解决方法启动后立即退出数据目录权限不对chown -R mongod:mongod并chmod 700报libcrypto.so.10缺失openssl 版本不匹配升级 openssl 或安装兼容包报Address already in use27017 端口被占netstat -tlnp | grep 27017查进程YAML 解析错误用了 Tab 缩进全部改成空格日志无输出日志目录权限或路径错误检查systemLog.path和目录权限内存溢出被 killcacheSizeGB 太大调小到 1GB 或更低5.2 几个我实际踩过的坑第一个坑是NUMA 架构下的性能抖动。CentOS 6 在多路 CPU 服务器上默认启用 NUMAMongoDB 在这种环境下会出现内存分配不均、偶发卡顿。解决办法是启动时加numactl --interleaveall或者直接在 BIOS 里关掉 NUMA。我一般是在/etc/init.d/mongod的启动命令前加上numactl --interleaveall实测下来稳定很多。第二个坑是透明大页THP。CentOS 6 默认开启 THPMongoDB 官方明确建议关闭否则 WiredTiger 的内存管理会出现延迟尖刺。关闭方法echo never /sys/kernel/mm/redhat_transparent_hugepage/enabled echo never /sys/kernel/mm/redhat_transparent_hugepage/defrag要永久生效就写进/etc/rc.local。这个改动对数据库性能提升是实打实的尤其是写入密集场景。第三个坑是文件句柄数限制。CentOS 6 默认ulimit -n是 1024MongoDB 在高并发下会报Too many open files。改/etc/security/limits.confmongod soft nofile 64000 mongod hard nofile 64000改完重启服务用cat /proc/$(cat /data/mongodb/mongod.pid)/limits | grep files确认生效。5.3 升级到 4.0 之后的兼容性检查从 3.x 升到 4.0有几个行为变化要注意。一是$type操作符对数组的处理逻辑变了老代码里如果有依赖旧行为的查询结果可能不一致。二是副本集的心跳和选举协议有调整跨版本混跑时建议先升从节点再升主节点。三是db.collection.count()在分片集群里的行为有变化建议改用countDocuments()。升级前务必用mongodump做全量备份并且在测试环境先跑一遍。我见过直接在生产上yum update然后起不来的案例回滚都来不及。6. 性能调优与日常维护建议6.1 针对老硬件的参数微调CentOS 6 的机器普遍配置不高内存 4GB 到 8GB 居多。这种情况下cacheSizeGB设成 1 到 2 比较合适留足内存给系统和业务进程。wiredTiger.engineConfig.journalCompressor可以设为snappy减少日志写入量对机械硬盘尤其有效。连接数方面net.maxIncomingConnections默认是 65536老机器上没必要开这么大设成 1000 到 2000 就够避免连接堆积拖垮系统。6.2 备份策略的落地老环境里我最推荐的是mongodump加定时任务简单可靠。每天凌晨低峰期跑一次全量保留最近 7 天mongodump --host 127.0.0.1 --port 27017 -u siteAdmin -p 密码 --authenticationDatabase admin --out /data/backup/$(date %Y%m%d) find /data/backup -type d -mtime 7 -exec rm -rf {} \;如果数据量大mongodump会拖慢主库可以考虑在从节点上执行或者用文件系统快照。但老环境里往往没有 LVM 或者云盘快照所以mongodump还是最实际的方案。6.3 监控指标的关注重点MongoDB 4.0 自带db.serverStatus()重点看几个指标connections.current是否接近上限globalLock.currentQueue.total是否持续偏高wiredTiger.cache.bytes currently in the cache是否接近cacheSizeGB。如果队列数长期大于 0说明有慢查询需要开profiling排查。db.setProfilingLevel(1, { slowms: 100 }) db.system.profile.find().sort({ ts: -1 }).limit(10)把超过 100ms 的操作记录下来定期分析这是老系统上最有效的优化手段。7. 关于这套方案在 CentOS 7.X 上的复用标题里特意标注适用于 CentOS 7.X不是随便写的。这套流程里yum 源配置、RPM 包、mongod.conf内容、用户创建、备份脚本在 CentOS 7 上完全通用。唯一的差异是服务管理命令从service换成systemctl以及 CentOS 7 默认的 glibc 是 2.17可以直接上 MongoDB 4.2 甚至 4.4不必卡在 4.0。如果你是在做系统迁移从 CentOS 6 迁到 CentOS 7我的建议是先在 7 上装同版本 MongoDB用mongodump从 6 导出再mongorestore到 7验证业务无误后再切流量。这样比原地升级系统安全得多因为 CentOS 6 到 7 的原地升级基本等于重装风险不可控。最后分享一个我在实际迁移中总结的小技巧把mongod.conf里的bindIp在迁移期间临时设为0.0.0.0配合防火墙只放行新老两台机器的 IP这样可以在不切流量的情况下做双写验证。验证通过后再改回127.0.0.1并正式切换。这个中间态能帮你省掉很多来回折腾的时间。
拿不准这条消息跟你有没有关系?
工种不同、批次不同,要求可能差很多。打电话把你的情况说清楚,我们按信阳、平顶山本地的口径给你捋一遍。