MongoDB
大约 16 分钟约 4777 字
MongoDB
下载MongoDB
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.1.tgz多版本下载地址
# MongoDB 5.0(RHEL 7)
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.1.tgz
# MongoDB 6.0(RHEL 8)
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-6.0.8.tgz
# MongoDB 7.0(RHEL 8)
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-7.0.4.tgz
# 使用 curl 下载(支持断点续传)
curl -C - -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.1.tgz
# 使用 yum 仓库安装(推荐生产环境使用)
# 创建 /etc/yum.repos.d/mongodb-org-5.0.repo
cat > /etc/yum.repos.d/mongodb-org-5.0.repo << 'EOF'
[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
EOF
# 通过 yum 安装
yum install -y mongodb-org
# 安装后自动创建 systemd 服务:mongod.service
# 锁定版本,防止意外升级
yum install -y yum-plugin-versionlock
yum versionlock mongodb-org-*解压安装
tar xf mongodb-linux-x86_64-rhel70-5.0.1.tgz -C /usr/local
cd /usr/local
mv mongodb-linux-x86_64-rhel70-5.0.1 mongodb
cd mongodb
mkdir data log conf创建必要目录和用户
# 创建 mongodb 用户和组
groupadd -r mongod
useradd -r -g mongod -d /var/lib/mongo -s /sbin/nologin mongod
# 创建数据、日志、配置目录
mkdir -p /usr/local/mongodb/{data,log,conf}
mkdir -p /var/lib/mongo
mkdir -p /var/log/mongodb
mkdir -p /var/run/mongodb
# 设置目录权限
chown -R mongod:mongod /usr/local/mongodb/data
chown -R mongod:mongod /usr/local/mongodb/log
chown -R mongod:mongod /var/lib/mongo
chown -R mongod:mongod /var/log/mongodb
chown -R mongod:mongod /var/run/mongodb
# 设置目录权限(安全加固)
chmod 750 /usr/local/mongodb/data
chmod 750 /usr/local/mongodb/log
chmod 750 /var/lib/mongo
chmod 750 /var/log/mongodb
# 创建 PID 文件目录
touch /var/run/mongodb/mongod.pid
chown mongod:mongod /var/run/mongodb/mongod.pid配置文件
vi mongod.conf
# 内容
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /usr/local/mongodb/log/mongod.log
# Where and how to store data.
storage:
dbPath: /usr/local/mongodb/data
journal:
enabled: true
# engine:
# wiredTiger:
# how the process runs
processManagement:
fork: true # fork and run in background
timeZoneInfo: /usr/share/zoneinfo
# network interfaces
net:
port: 27017
bindIp: 0.0.0.0 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
### 添加授权
security:
authorization: enabled完整生产配置文件示例
# /usr/local/mongodb/conf/mongod.conf
# 完整的生产环境配置
systemLog:
destination: file
logAppend: true
path: /usr/local/mongodb/log/mongod.log
# 日志保留策略
logRotate: reopen
# 冗长日志(调试时开启)
# verbosity: 1
# 组件日志级别
component:
accessControl:
verbosity: 1
command:
verbosity: 1
storage:
dbPath: /usr/local/mongodb/data
journal:
enabled: true
# WiredTiger 存储引擎配置
engine: wiredTiger
wiredTiger:
engineConfig:
# 缓存大小(默认为物理内存的 50%)
cacheSizeGB: 4
# 压缩配置
journalCompressor: snappy
collectionConfig:
blockCompressor: snappy
indexConfig:
prefixCompression: true
# 索引构建在后台执行
indexBuildRetry: true
processManagement:
fork: true
pidFilePath: /var/run/mongodb/mongod.pid
timeZoneInfo: /usr/share/zoneinfo
net:
port: 27017
bindIp: 127.0.0.1,192.168.1.10 # 生产环境建议绑定具体 IP
# 最大连接数
maxIncomingConnections: 1000
# Wire 压缩
wireObjectCheck: true
# IPv6 支持
ipv6: false
security:
authorization: enabled
# 密钥文件(副本集使用)
# keyFile: /usr/local/mongodb/conf/keyfile
# JavaScript 执行
javascriptEnabled: true
# 操作日志(oplog)配置
replication:
# 副本集名称(启用副本集时取消注释)
# replSetName: rs0
# oplog 大小(GB)
# oplogSizeMB: 2048
# 慢查询日志
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100 # 超过 100ms 记录慢查询
# 审计日志(安全合规需要)
# auditLog:
# destination: file
# path: /usr/local/mongodb/log/audit.log
# format: JSON
setParameter:
# 文档验证级别
# enableLocalhostAuthBypass: false
# 最大文档大小(16MB 默认)
# maxDocumentSize: 16777216WiredTiger 存储引擎调优
# 存储引擎配置详解
storage:
engine: wiredTiger
wiredTiger:
engineConfig:
# 缓存大小配置
# 默认 (max(256MB, RAM-1GB))
# 生产建议设为物理内存的 50%-60%
cacheSizeGB: 4
# 日志压缩算法:none, snappy(默认), zlib, zstd
journalCompressor: snappy
# 检查点间隔(秒)
checkpointIntervalSecs: 60
# 检查点等待(毫秒)
checkpointWaitSecs: 5
# 是否使用分离的(分离到不同目录)日志
# separateLog: false
collectionConfig:
# 集合数据压缩:none, snappy(默认), zlib, zstd
blockCompressor: snappy
# zstd 压缩率更高但 CPU 消耗更大
# blockCompressor: zstd
indexConfig:
# 索引前缀压缩(默认开启,节省内存)
prefixCompression: true
# 压缩算法对比:
# none - 不压缩,读写最快,占用空间最大
# snappy - 均衡选择,压缩速度和压缩率适中
# zlib - 压缩率最高,但 CPU 消耗大,读写较慢
# zstd - MongoDB 4.2+ 支持,压缩率接近 zlib,速度更快启动mongod服务器
cd /usr/local/mongodb/bin
# 基于配置参数启动mongodb
./mongod --dbpath ../data/ --logpath ../log/mongod.log --bind_ip 0.0.0.0 --fork --auth
# 基于配置文件启动
cd /usr/local/mongodb/bin
./mongod -f /usr/local/mongodb/mongod.conf
[root@node1 ~]# ps -ef | grep mongod
mongod 1574 1 4 20:39 ? 00:00:00 /usr/bin/mongod -f /etc/mongod.conf
root 1610 1399 0 20:40 pts/0 00:00:00 grep --color=auto mongod启动报错
about to fork child process, waiting until server is ready for connections.
forked process: 3988
ERROR: child process failed, exited with 1
To see additional information in this output, start without the "--fork" option.
进入/usr/local/mongodb/data删除mongod.lock
启动问题排查
# 不带 fork 前台启动,查看详细错误信息
/usr/local/mongodb/bin/mongod --dbpath /usr/local/mongodb/data --logpath /usr/local/mongodb/log/mongod.log
# 常见启动失败原因及解决方案:
# 1. 目录权限不足
ls -la /usr/local/mongodb/data/
chown -R mongod:mongod /usr/local/mongodb/data
# 2. 端口被占用
ss -tlnp | grep 27017
# 修改端口或杀掉占用进程
# 3. 数据目录损坏(mongod.lock 残留)
rm -f /usr/local/mongodb/data/mongod.lock
rm -f /usr/local/mongodb/data/WiredTiger.lock
rm -f /var/run/mongodb/mongod.pid
# 4. 磁盘空间不足
df -h /usr/local/mongodb/data
# 5. SELinux 阻止
getenforce
setenforce 0 # 临时关闭
# 或配置 SELinux 策略
# 6. 数据目录有残留的 journal
rm -rf /usr/local/mongodb/data/journal/*开放端口,并重启防火墙端口
firewall-cmd --zone=public --add-port=27017/tcp --permanent
firewall-cmd --reload防火墙配置详解
# 开放 MongoDB 默认端口
firewall-cmd --zone=public --add-port=27017/tcp --permanent
firewall-cmd --reload
# 验证端口是否开放
firewall-cmd --list-ports
firewall-cmd --query-port=27017/tcp
# 如果使用 iptables
iptables -A INPUT -p tcp --dport 27017 -j ACCEPT
service iptables save
# 限制来源 IP(推荐生产环境)
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="27017" accept'
firewall-cmd --reload
# 使用 firewalld 服务方式
firewall-cmd --permanent --new-service=mongodb
firewall-cmd --permanent --service=mongodb --add-port=27017/tcp
firewall-cmd --permanent --zone=public --add-service=mongodb
firewall-cmd --reload
# SELinux 配置(如果需要开启 SELinux)
# 安装 MongoDB SELinux 策略包
yum install -y mongodb-org-server
# 或者手动配置 SELinux 策略
semanage port -a -t mongod_port_t -p tcp 27017
semanage fcontext -a -t mongod_var_lib_t "/usr/local/mongodb/data(/.*)?"
restorecon -Rv /usr/local/mongodb/data添加PATH
#对于交互式会话,请使用以下命令在 ~/.bash_profile 文件中修改 PATH 环境变量:
echo 'export PATH="$PATH:/usr/local/mongodb/bin"' >> ~/.bash_profile
#对于非交互式会话,请使用以下命令在 ~/.bashrc 文件中修改 PATH 环境变量:
echo 'export PATH="$PATH:/usr/local/mongodb/bin"' >> ~/.bashrc
source ~/.bashrc环境变量配置详解
# 添加 MongoDB 到 PATH
echo 'export PATH="$PATH:/usr/local/mongodb/bin"' >> ~/.bashrc
source ~/.bashrc
# 验证
mongod --version
mongo --version
mongos --version
mongodump --version
# 创建全局环境变量文件(对所有用户生效)
cat > /etc/profile.d/mongodb.sh << 'EOF'
export PATH="$PATH:/usr/local/mongodb/bin"
export MONGODB_HOME=/usr/local/mongodb
EOF
chmod +x /etc/profile.d/mongodb.sh
source /etc/profile.d/mongodb.sh关闭mongodb
mongod --shutdown --dbpath=/usr/local/mongodb/data启动mongodb
mongod -f /usr/local/mongodb/mongod.conf注意
一定要正常关闭,切记不要使用kill的形式,容易损坏
安全关闭 MongoDB 的方法
# 方法 1:mongod --shutdown(推荐)
mongod --shutdown --dbpath=/usr/local/mongodb/data
# 方法 2:通过 mongo shell 发送 shutdown 命令
mongo admin --eval 'db.shutdownServer()'
# 方法 3:通过 mongo shell(带认证)
mongo -u admin -p password --authenticationDatabase admin --eval 'db.shutdownServer()'
# 方法 4:使用 systemctl(如果配置了 systemd 服务)
systemctl stop mongod
# 方法 5:使用 SIGTERM 信号(安全的 kill 方式)
kill $(cat /var/run/mongodb/mongod.pid)
# 注意:千万不要使用 kill -9,会导致数据损坏
# 验证 MongoDB 已关闭
ps -ef | grep mongod
ss -tlnp | grep 27017给需要的数据库授权
mongo
use sunnyfandb
db.createUser({user:"sunnyfan",pwd:"sunnyfan",roles:[{role:"dbOwner",db:"sunnyfandb"}]})用户管理详解
# ====== 创建管理员用户 ======
mongo
use admin
db.createUser({
user: "admin",
pwd: "AdminPass_2024!",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" },
{ role: "clusterAdmin", db: "admin" },
{ role: "clusterMonitor", db: "admin" }
]
})
# ====== 创建普通数据库用户 ======
use sunnyfandb
db.createUser({
user: "sunnyfan",
pwd: "sunnyfan",
roles: [
{ role: "dbOwner", db: "sunnyfandb" }
]
})
# ====== 创建只读用户 ======
use sunnyfandb
db.createUser({
user: "readonly_user",
pwd: "ReadOnlyPass_2024!",
roles: [
{ role: "read", db: "sunnyfandb" }
]
})
# ====== 创建备份用户 ======
use admin
db.createUser({
user: "backup_user",
pwd: "BackupPass_2024!",
roles: [
{ role: "backup", db: "admin" },
{ role: "restore", db: "admin" }
]
})
# ====== 常用角色说明 ======
# read - 读取指定数据库
# readWrite - 读写指定数据库
# dbAdmin - 管理指定数据库(schema、索引等)
# dbOwner - 拥有指定数据库的全部权限
# userAdmin - 管理指定数据库的用户
# clusterAdmin - 管理集群(副本集、分片)
# clusterMonitor - 监控集群状态
# backup - 备份数据
# restore - 恢复数据
# readAnyDatabase - 读取所有数据库
# readWriteAnyDatabase - 读写所有数据库
# userAdminAnyDatabase - 管理所有数据库的用户
# dbAdminAnyDatabase - 管理所有数据库
# ====== 查看用户 ======
use admin
db.system.users.find().pretty()
db.getUsers()
db.getUser("sunnyfan")
# ====== 修改用户密码 ======
use sunnyfandb
db.changeUserPassword("sunnyfan", "NewPassword_2024!")
# ====== 删除用户 ======
use sunnyfandb
db.dropUser("sunnyfan")
# ====== 用户权限管理 ======
# 授予角色
db.grantRolesToUser("sunnyfan", [{role: "readWrite", db: "another_db"}])
# 撤销角色
db.revokeRolesFromUser("sunnyfan", [{role: "readWrite", db: "another_db"}])重启验证授权是否正常
shell验证
mongo
use sunnyfandb
db.auth("sunnyfan","sunnyfan")连接验证与常用操作
# 使用认证连接
mongo -u sunnyfan -p sunnyfan --authenticationDatabase sunnyfandb
# 连接指定主机和端口
mongo --host 192.168.1.10 --port 27017 -u admin -p password --authenticationDatabase admin
# 使用连接字符串
mongo "mongodb://sunnyfan:sunnyfan@192.168.1.10:27017/sunnyfandb?authSource=sunnyfandb"
# 测试连接是否正常
mongo --eval 'db.runCommand({ping:1})' sunnyfandb -u sunnyfan -p sunnyfan
# 查看数据库状态
mongo -u admin -p password --authenticationDatabase admin --eval 'db.serverStatus()'
# 查看数据库列表
mongo -u admin -p password --authenticationDatabase admin --eval 'show dbs'
# 查看集群状态
mongo -u admin -p password --authenticationDatabase admin --eval 'rs.status()'开机自动启动mongodb
cd /etc/rc.d/init.d
vi mongod
# 内容
#!/bin/bash
#
#chkconfig: 2345 80 90
#description: mongod
start() {
/usr/local/mongodb/bin/mongod --config /usr/local/mongodb//mongod.conf
}
stop() {
/usr/local/mongodb/bin/mongod --config /usr/local/mongodb//mongod.conf --shutdown
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo
$"Usage: $0 {start|stop|restart}"
exit 1
esac
# 保存完成之后,添加脚本执行权限
chmod +x /etc/rc.d/init.d/mongod
chkconfig --add mongod
chkconfig --level 345 mongod on
chkconfig --list mongod
# MongoDB服务的启动与关闭
service mongod start
service mongod stopSystemd 服务配置(推荐方式)
# ====== 创建 systemd 服务文件 ======
cat > /etc/systemd/system/mongod.service << 'EOF'
[Unit]
Description=MongoDB Database Server
After=network-online.target
Wants=network-online.target
[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /usr/local/mongodb/conf/mongod.conf"
EnvironmentFile=-/etc/sysconfig/mongod
ExecStart=/usr/local/mongodb/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/mongod.pid
Type=forking
Restart=on-failure
RestartSec=5
LimitNOFILE=64000
TimeoutStartSec=300
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target
EOF
# ====== 创建 sysconfig 文件 ======
cat > /etc/sysconfig/mongod << 'EOF'
OPTIONS="-f /usr/local/mongodb/conf/mongod.conf"
EOF
# ====== 启用并启动服务 ======
systemctl daemon-reload
systemctl enable mongod
systemctl start mongod
systemctl status mongod
# ====== 服务管理命令 ======
systemctl start mongod # 启动
systemctl stop mongod # 停止
systemctl restart mongod # 重启
systemctl status mongod # 状态
systemctl reload mongod # 重新加载配置
# 查看服务日志
journalctl -u mongod -f
journalctl -u mongod --since "2024-01-01" --until "2024-01-02"常用数据库操作
基础 CRUD 操作
// ====== 数据库操作 ======
show dbs // 显示所有数据库
use mydb // 切换/创建数据库
db.dropDatabase() // 删除当前数据库
db.getName() // 获取当前数据库名
// ====== 集合操作 ======
show collections // 显示当前数据库的所有集合
db.createCollection("users") // 创建集合
db.users.drop() // 删除集合
// ====== 插入文档 ======
db.users.insertOne({name: "张三", age: 25, email: "zhangsan@example.com"})
db.users.insertMany([
{name: "李四", age: 30, email: "lisi@example.com"},
{name: "王五", age: 28, email: "wangwu@example.com"},
{name: "赵六", age: 35, email: "zhaoliu@example.com"}
])
// ====== 查询文档 ======
db.users.find() // 查询所有
db.users.find().pretty() // 格式化输出
db.users.findOne({name: "张三"}) // 查询单个
db.users.find({age: {$gt: 25}}) // age > 25
db.users.find({age: {$gte: 25}}) // age >= 25
db.users.find({age: {$lt: 30}}) // age < 30
db.users.find({age: {$in: [25, 30, 35]}}) // age in (25, 30, 35)
db.users.find({name: /张/}) // 正则匹配
db.users.find({name: {$regex: "^张"}}) // 以"张"开头
// 投影(只返回指定字段)
db.users.find({}, {name: 1, age: 1, _id: 0})
// 排序
db.users.find().sort({age: 1}) // 升序
db.users.find().sort({age: -1}) // 降序
// 分页
db.users.find().skip(10).limit(5) // 跳过 10 条,取 5 条
// 计数
db.users.countDocuments({age: {$gt: 25}})
db.users.estimatedDocumentCount()
// 去重
db.users.distinct("age")
// ====== 更新文档 ======
db.users.updateOne({name: "张三"}, {$set: {age: 26}})
db.users.updateMany({age: {$lt: 30}}, {$set: {status: "young"}})
// 更新操作符
// $set - 设置字段值
// $unset - 删除字段
// $inc - 增加数值
// $mul - 乘以数值
// $rename - 重命名字段
// $min/$max - 取最小/最大值
// $push - 向数组添加元素
// $pull - 从数组删除元素
// $addToSet - 向数组添加唯一元素
// $pop - 删除数组首/尾元素
db.users.updateOne({name: "张三"}, {$inc: {age: 1}})
db.users.updateOne({name: "张三"}, {$push: {tags: "vip"}})
db.users.updateOne({name: "张三"}, {$addToSet: {tags: "premium"}})
// ====== 删除文档 ======
db.users.deleteOne({name: "张三"})
db.users.deleteMany({age: {$lt: 20}})
// ====== 聚合操作 ======
db.orders.aggregate([
{$match: {status: "completed"}},
{$group: {
_id: "$userId",
totalAmount: {$sum: "$amount"},
count: {$sum: 1},
avgAmount: {$avg: "$amount"}
}},
{$sort: {totalAmount: -1}},
{$limit: 10}
])
// 管道阶段:
// $match - 过滤
// $group - 分组
// $sort - 排序
// $limit - 限制数量
// $skip - 跳过
// $project - 投影
// $unwind - 展开数组
// $lookup - 左外连接
// $count - 计数索引管理
// ====== 创建索引 ======
// 单字段索引
db.users.createIndex({name: 1}) // 1 升序,-1 降序
db.users.createIndex({email: 1}, {unique: true}) // 唯一索引
db.users.createIndex({age: -1}) // 降序索引
// 复合索引
db.users.createIndex({name: 1, age: -1})
// 文本索引
db.articles.createIndex({content: "text"})
// TTL 索引(自动过期)
db.logs.createIndex({createdAt: 1}, {expireAfterSeconds: 86400}) // 24 小时过期
// 地理空间索引
db.places.createIndex({location: "2dsphere"})
// 后台创建索引(不阻塞数据库)
db.users.createIndex({name: 1}, {background: true})
// ====== 查看索引 ======
db.users.getIndexes()
db.users.getIndexKeys()
// ====== 删除索引 ======
db.users.dropIndex("name_1") // 按索引名删除
db.users.dropIndexes() // 删除所有索引(除 _id 外)
// ====== 查看查询计划 ======
db.users.find({name: "张三"}).explain("executionStats")
db.users.find({age: {$gt: 25}}).explain("queryPlanner")
// ====== 索引使用分析 ======
db.users.find({name: "张三"}).hint({name: 1}) // 强制使用指定索引数据备份与恢复
mongodump / mongorestore
# ====== 全库备份 ======
mongodump --uri="mongodb://admin:password@localhost:27017" --out /backup/mongo/full_$(date +%Y%m%d)
# 备份指定数据库
mongodump --uri="mongodb://sunnyfan:sunnyfan@localhost:27017/sunnyfandb?authSource=sunnyfandb" \
--out /backup/mongo/sunnyfandb_$(date +%Y%m%d)
# 备份指定集合
mongodump --uri="mongodb://sunnyfan:sunnyfan@localhost:27017/sunnyfandb?authSource=sunnyfandb" \
--collection users --out /backup/mongo/users_$(date +%Y%m%d)
# 压缩备份
mongodump --uri="mongodb://admin:password@localhost:27017" --gzip --out /backup/mongo/full_$(date +%Y%m%d).gz
# ====== 全库恢复 ======
mongorestore --uri="mongodb://admin:password@localhost:27017" /backup/mongo/full_20240101
# 恢复指定数据库
mongorestore --uri="mongodb://admin:password@localhost:27017" --db sunnyfandb /backup/mongo/sunnyfandb_20240101/sunnyfandb
# 恢复时覆盖(drop 已有集合)
mongorestore --uri="mongodb://admin:password@localhost:27017" --drop /backup/mongo/full_20240101
# 恢复压缩备份
mongorestore --uri="mongodb://admin:password@localhost:27017" --gzip /backup/mongo/full_20240101.gz
# ====== mongoexport / mongoimport(JSON/CSV 格式) ======
# 导出为 JSON
mongoexport --uri="mongodb://sunnyfan:sunnyfan@localhost:27017/sunnyfandb?authSource=sunnyfandb" \
--collection users --out /backup/users.json
# 导出为 CSV
mongoexport --uri="mongodb://sunnyfan:sunnyfan@localhost:27017/sunnyfandb?authSource=sunnyfandb" \
--collection users --type=csv --fields name,age,email --out /backup/users.csv
# 导入 JSON
mongoimport --uri="mongodb://sunnyfan:sunnyfan@localhost:27017/sunnyfandb?authSource=sunnyfandb" \
--collection users --file /backup/users.json --jsonArray
# 导入 CSV
mongoimport --uri="mongodb://sunnyfan:sunnyfan@localhost:27017/sunnyfandb?authSource=sunnyfandb" \
--collection users --type=csv --headerline --file /backup/users.csv自动备份脚本
#!/bin/bash
# mongodb_backup.sh
# MongoDB 自动备份脚本
set -euo pipefail
# 配置
MONGO_HOST="127.0.0.1"
MONGO_PORT="27017"
MONGO_USER="admin"
MONGO_PASS="AdminPass_2024!"
AUTH_DB="admin"
BACKUP_DIR="/backup/mongodb"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/mongodb/backup.log"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
}
# 创建备份目录
mkdir -p "$BACKUP_DIR"
# 执行备份
log "Starting MongoDB backup..."
mongodump --host="$MONGO_HOST" --port="$MONGO_PORT" \
--username="$MONGO_USER" --password="$MONGO_PASS" \
--authenticationDatabase="$AUTH_DB" \
--gzip --out="${BACKUP_DIR}/${DATE}"
if [ $? -eq 0 ]; then
log "Backup completed: ${BACKUP_DIR}/${DATE}"
else
log "ERROR: Backup failed!"
exit 1
fi
# 清理过期备份
log "Cleaning up backups older than $RETENTION_DAYS days..."
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} +
log "Backup cleanup completed"性能监控
常用监控命令
// ====== 服务器状态 ======
db.serverStatus()
// ====== 数据库状态 ======
db.stats()
// ====== 集合状态 ======
db.users.stats()
// ====== 当前操作 ======
db.currentOp() // 查看当前所有操作
db.currentOp({"active": true}) // 查看活跃操作
db.currentOp({"op": "query"}) // 查看查询操作
// 杀掉长时间运行的操作
db.killOp(opId)
// ====== 慢查询分析 ======
// 查看慢查询设置
db.getProfilingStatus()
db.getProfilingLevel()
// 设置慢查询阈值
db.setProfilingLevel(1, 50) // level 1=慢查询, 50ms
// 查看慢查询日志
db.system.profile.find().sort({ts: -1}).limit(10).pretty()
// ====== 查看连接数 ======
db.serverStatus().connections
// ====== 查看内存使用 ======
db.serverStatus().mem
db.serverStatus().wiredTiger.cache
// ====== 查看锁情况 ======
db.serverStatus().locks
// ====== 查看副本集状态 ======
rs.status()
rs.conf()
rs.printReplicationInfo()
rs.printSlaveReplicationInfo()使用 mongostat 和 mongotop
# ====== mongostat(实时状态监控) ======
mongostat --host 127.0.0.1:27017 -u admin -p password --authenticationDatabase admin
# 每 5 秒刷新一次
mongostat --host 127.0.0.1:27017 -u admin -p password --authenticationDatabase admin 5
# 输出字段说明:
# inserts/s, queries/s, updates/s, deletes/s
# getmore: 游标获取数量
# command: 命令数
# dirty: 脏数据百分比
# used: WiredTiger 缓存使用百分比
# conn: 当前连接数
# ====== mongotop(集合级别读写时间监控) ======
mongotop --host 127.0.0.1:27017 -u admin -p password --authenticationDatabase admin
# 每 5 秒刷新
mongotop --host 127.0.0.1:27017 -u admin -p password --authenticationDatabase admin 5副本集配置
搭建副本集
# ====== 生成密钥文件(所有节点使用相同密钥) ======
openssl rand -base64 756 > /usr/local/mongodb/conf/keyfile
chmod 400 /usr/local/mongodb/conf/keyfile
chown mongod:mongod /usr/local/mongodb/conf/keyfile
# ====== 修改配置文件(所有节点) ======
# 在 mongod.conf 中添加:
security:
authorization: enabled
keyFile: /usr/local/mongodb/conf/keyfile
replication:
replSetName: rs0
oplogSizeMB: 2048
# ====== 启动所有节点 ======
systemctl start mongod
# ====== 初始化副本集 ======
mongo --host 192.168.1.10
rs.initiate({
_id: "rs0",
members: [
{_id: 0, host: "192.168.1.10:27017"},
{_id: 1, host: "192.168.1.11:27017"},
{_id: 2, host: "192.168.1.12:27017", arbiterOnly: true}
]
})
# ====== 查看副本集状态 ======
rs.status()
rs.conf()
# ====== 添加/删除节点 ======
rs.add("192.168.1.13:27017")
rs.addArb("192.168.1.14:27017")
rs.remove("192.168.1.13:27017")
# ====== 连接副本集 ======
mongo "mongodb://host1:27017,host2:27017,host3:27017/admin?replicaSet=rs0"关键知识点
- 部署类主题的核心不是"装成功",而是"稳定运行、可排障、可回滚"。
- 同一个服务通常至少要关注版本、目录、端口、权限、数据、日志和备份。
- Linux 问题经常跨越系统层、网络层、服务层和应用层。
- 先把数据模型、访问模式和执行代价绑定起来理解。
- MongoDB 使用 WiredTiger 存储引擎,支持文档级别并发控制。
- 副本集(Replica Set)提供高可用性,建议至少 3 个节点。
- 生产环境必须开启认证(authorization: enabled)。
- 缓存大小建议设为物理内存的 50%-60%,避免与系统争抢内存。
- kill -9 会导致 MongoDB 数据损坏,务必使用 shutdown 命令。
项目落地视角
- 把安装步骤补成可重复执行的清单,必要时写成脚本或配置文件。
- 把配置目录、数据目录、日志目录和挂载点明确拆开。
- 上线前检查防火墙、SELinux、时区、磁盘、系统服务和健康检查。
- 保留执行计划、样本 SQL、索引定义和优化前后指标。
- 建立定期备份策略,验证备份可恢复性。
- 配置慢查询监控和告警。
常见误区
- 使用 latest 或未固定版本,导致环境不可复现。
- 只验证启动成功,不验证持久化、开机自启和故障恢复。
- 遇到问题先改配置而不是先看日志和依赖链路。
- 脱离真实数据分布设计索引。
- 使用 kill -9 关闭 MongoDB。
- bindIp 设置为 0.0.0.0 但未开启认证。
- 忽略 WiredTiger 缓存大小配置导致内存溢出。
- 不设置 oplog 大小导致主从同步延迟。
进阶路线
- 继续补齐 systemd、性能监控、安全加固和备份恢复。
- 把单机操作升级成 Docker、Kubernetes 或 IaC 方案。
- 建立标准化运维手册,包括巡检、扩容、回滚和灾备演练。
- 继续深入存储引擎、复制机制、归档与冷热分层治理。
- 学习 MongoDB 分片集群(Sharding)配置。
- 研究 MongoDB Change Streams 实现实时数据同步。
适用场景
- 当你准备把《MongoDB》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合单机环境初始化、中间件快速搭建、测试环境验证和生产部署前准备。
- 当服务稳定性依赖端口、权限、目录、网络和系统参数时,这类主题会直接影响成败。
- 适合文档型数据存储、内容管理系统、日志存储等场景。
落地建议
- 固定版本号与镜像标签,避免"latest"带来的不可预期变化。
- 把配置、数据、日志目录拆开管理,并记录恢复步骤。
- 上线前确认端口、防火墙、SELinux、时区和磁盘空间。
- 使用 systemd 管理 MongoDB 服务。
- 配置合适的 WiredTiger 缓存大小和压缩算法。
- 建立索引规范,定期审查慢查询。
排错清单
- 先查 systemctl、容器日志和应用日志,确认失败发生在哪一层。
- 检查端口占用、目录权限、挂载路径和网络连通性。
- 如果是新环境问题,优先对比与已知正常环境的差异。
- 查看 mongod.log 日志文件获取详细错误信息。
- 使用 db.serverStatus() 和 rs.status() 检查运行状态。
- 检查 ulimit -n 是否足够(建议 64000 以上)。
复盘问题
- 如果把《MongoDB》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《MongoDB》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《MongoDB》最大的收益和代价分别是什么?
- MongoDB 副本集的选举机制是什么?如何避免脑裂?
