MongoDB 常用运维指令手册
MongoDB 常用运维指令手册
适用版本:MongoDB 6.0 / 7.0 / 8.0 / 8.3 / 9.0(on-premises GA 版本) 约定:
#root 或 sudo,$普通用户,rs0 [primary]>mongosh 提示符,<xxx>为占位符。 差异标注:正文用> **版本差异**引用块标注跨版本不一致之处。 更新时间:2026-11
目录
- 版本与支持周期
- 下载地址与安装
- 服务启停与配置
- mongosh 连接与基本操作
- 认证、用户与角色
- 库集合与文档操作
- 索引管理
- 副本集
- 分片集群
- 备份与恢复
- 日志与审计
- 性能诊断
- 空间与压缩
- 升级与迁移
- 高频故障速查
- 危险命令与避坑清单
- 附录:巡检脚本与速查
1. 版本与支持周期
1.1 发布模型(关键)
MongoDB 有两类版本,只有 GA Major Release 允许自建部署:
| 类型 | 版本 | 说明 |
|---|---|---|
| GA Major(可用于生产自建) | 7.0、8.0、8.3、9.0 | 支持 30 个月 |
| Rapid Release(仅 Atlas) | 8.1、8.2、… | 每个季度发一次,不支持 on-premises |
| 版本 | GA 时间 | 支持截止 | 状态 |
|---|---|---|---|
| 6.0 | 2022-07 | 2025-07 | 已 EOL |
| 7.0 | 2023-08 | 2027-08 | 维护中 |
| 8.0 | 2024-10 | 2029-10 | 广泛使用 |
| 8.3 | 2026-05 | 2029-10 | 维护中 |
| 9.0 | 2026-09-29 | 2031-10 | 当前推荐 |
| 8.1 / 8.2 | 2025 | 已结束 | 仅 Atlas,不可自建 |
重要:看到 8.2 不要想着下载自建——Rapid Release 只在 Atlas 提供。自建服务器只能在 7.0 / 8.0 / 8.3 / 9.0 之间选。这是 MongoDB 与 MySQL/PG 最容易被误解的版本策略。
1.2 9.0 的主要变化
- 查询性能提升(官方称 find-one 快 35%、update-one 快 30%、大实例吞吐翻倍)。
- Queryable Encryption 支持前缀/后缀/子串搜索。
- 原生 OpenTelemetry 集成增强。
- IWM(Intelligent Workload Management)仅 Atlas 提供,自建实例没有。
自建环境升级到 9.0 的主要收益是性能与加密查询,运维命令与 8.0 基本一致。
1.3 版本识别
mongod --version
mongos --version
mongosh --version
db.version()
db.adminCommand({buildInfo:1})
db.adminCommand({getCmdLineOpts:1}) // 实际加载的配置与参数
2. 下载地址与安装
2.1 官方入口总表
| 用途 | 地址 |
|---|---|
| Community Server 下载 | https://www.mongodb.com/try/download/community |
| 全部产品下载 | https://www.mongodb.com/try/download |
| MongoDB Shell(mongosh) | https://www.mongodb.com/try/download/shell |
| Database Tools(mongodump 等) | https://www.mongodb.com/try/download/database-tools |
| MongoDB Compass(图形客户端) | https://www.mongodb.com/try/download/compass |
| 官方文档 | https://www.mongodb.com/docs/ |
| YUM/APT 仓库说明 | https://www.mongodb.com/docs/manual/administration/install-on-linux/ |
| Docker 镜像 | https://hub.docker.com/r/mongodb/mongodb-community-server 或 mongo |
| Percona Backup for MongoDB | https://www.percona.com/software/mongodb/percona-backup-mongodb |
国内镜像(同步 rpm/deb 包,路径以镜像站为准):
https://mirrors.tuna.tsinghua.edu.cn/mongodb/
https://mirrors.aliyun.com/mongodb/
2.2 RHEL / Rocky / Alma:YUM 安装
# 1) 配置仓库(9.0 示例,改版本号即可装 8.0/8.3)
cat > /etc/yum.repos.d/mongodb-org-9.0.repo <<'EOF'
[mongodb-org-9.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/9.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://pgp.mongodb.com/server-9.0.asc
EOF
# 2) 安装
dnf install -y mongodb-org
# 3) 启动
systemctl enable --now mongod
systemctl status mongod
# 4) 安装工具
dnf install -y mongodb-mongosh mongodb-database-tools
包结构:
| 包 | 内容 |
|---|---|
mongodb-org-server |
mongod |
mongodb-org-mongos |
mongos(分片路由) |
mongodb-org-shell |
老版 mongo shell(已由 mongosh 取代) |
mongodb-org-tools |
mongodump / mongorestore / mongoexport / mongoimport / mongostat / mongotop |
mongodb-mongosh |
新版 shell |
2.3 Ubuntu / Debian:APT 安装
curl -fsSL https://www.mongodb.org/static/pgp/server-9.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-9.0.gpg --dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-9.0.gpg ] \
https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/9.0 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-9.0.list
sudo apt update
sudo apt install -y mongodb-org
sudo systemctl enable --now mongod
避坑:Ubuntu 官方源里也有
mongodb包,但那是很老的版本(通常 3.x/4.x)。必须确认装的是mongodb-org,apt install mongodb会装到错的东西。
2.4 通用二进制(tgz)
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel90-9.0.0.tgz
tar -xzf mongodb-linux-x86_64-rhel90-9.0.0.tgz -C /opt
ln -s /opt/mongodb-linux-x86_64-rhel90-9.0.0 /opt/mongodb
useradd -r -s /bin/false mongodb
mkdir -p /data/mongodb/{data,log}
chown -R mongodb:mongodb /data/mongodb
/opt/mongodb/bin/mongod --dbpath /data/mongodb/data \
--logpath /data/mongodb/log/mongod.log \
--fork --port 27017 --bind_ip 0.0.0.0
2.5 Docker 部署
# 单机
docker run -d --name mongo9 \
--restart unless-stopped \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD='Str0ng#Pass2026' \
-v /data/mongo9:/data/db \
-v /data/mongo9_conf:/data/configdb \
mongo:9.0
docker logs -f mongo9
docker exec -it mongo9 mongosh -u admin -p 'Str0ng#Pass2026' --authenticationDatabase admin
注意:设置了
MONGO_INITDB_ROOT_USERNAME后,镜像会自动开启authorization,之后的连接必须认证。没设则默认无认证,不要暴露到公网。
2.6 安装后必做
// 1) 建管理员
use admin
db.createUser({
user: "admin",
pwd: "Str0ng#Pass2026",
roles: [{ role: "root", db: "admin" }]
})
// 2) 确认版本与存储引擎
db.version()
db.serverStatus().storageEngine
// 3) 确认认证已生效
db.adminCommand({getCmdLineOpts:1}).parsed.security
# /etc/mongod.conf 生产基线
security:
authorization: enabled
keyFile: /etc/mongo/keyfile # 副本集/分片必须
net:
port: 27017
bindIp: 10.0.0.11,127.0.0.1 # 不要 0.0.0.0 裸奔
# keyFile 权限要求严格
openssl rand -base64 756 > /etc/mongo/keyfile
chmod 400 /etc/mongo/keyfile
chown mongodb:mongodb /etc/mongo/keyfile
3. 服务启停与配置
3.1 systemd
systemctl start mongod
systemctl stop mongod
systemctl restart mongod
systemctl status mongod
systemctl enable mongod
journalctl -u mongod -n 200 --no-pager
3.2 配置文件(YAML,2.6 起)
# /etc/mongod.conf
storage:
dbPath: /var/lib/mongo
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 16 # 建议 (内存-1G)*50%~60%
directoryForIndexes: false
collectionConfig:
blockCompressor: zstd # 4.2+ 支持 zstd,默认 snappy
indexConfig:
prefixCompression: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
logRotate: reopen # 配合 logrotate 用 reopen
net:
port: 27017
bindIp: 10.0.0.11,127.0.0.1
maxIncomingConnections: 65536
processManagement:
timeZoneInfo: /usr/share/zoneinfo
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100
security:
authorization: enabled
keyFile: /etc/mongo/keyfile
replication:
replSetName: rs0
oplogSizeMB: 51200
setParameter:
enableLocalhostAuthBypass: false
# 语法检查(启动前)
mongod --config /etc/mongod.conf --configExpand none --fork --logpath /tmp/test.log --dbpath /tmp/testdb
3.3 停止方式
// 推荐:走正常关闭,刷盘并清理
use admin
db.shutdownServer()
// 强制关闭(可能需 repair,慎用)
db.adminCommand({shutdown: 1, force: true})
# 命令行
mongod --dbpath /var/lib/mongo --shutdown
systemctl stop mongod
危险:
kill -9 mongod后 WiredTiger 需要做恢复,大库可能启动很久,且未落盘的写入会丢。必须停止时优先db.shutdownServer()。
3.4 多实例
每个实例独立 dbPath、port、logpath、配置文件:
mongod -f /etc/mongod_27018.conf --fork
mongod -f /etc/mongod_27019.conf --fork
分片集群的典型进程分布:
| 角色 | 端口约定 | 说明 |
|---|---|---|
| mongos | 27017 | 应用连接入口 |
| config server | 27019 | 3 节点副本集 |
| shard | 27018 | 每个分片是副本集 |
4. mongosh 连接与基本操作
4.1 连接
mongosh # 本机默认
mongosh "mongodb://admin:pass@10.0.0.11:27017/?authSource=admin"
mongosh --host 10.0.0.11 --port 27017 -u admin -p 'pass' --authenticationDatabase admin
mongosh "mongodb+srv://user:pass@cluster.example.com/" # Atlas
mongosh --tls --tlsCAFile /etc/ssl/ca.pem "mongodb://..."
mongosh --eval "db.version()" mongodb://localhost:27017
mongosh --quiet --file script.js
推荐连接串:
mongodb://user:pass@h1:27017,h2:27017,h3:27017/appdb?replicaSet=rs0&authSource=admin&readPreference=primaryPreferred&retryWrites=true
4.2 常用 shell 辅助
show dbs
show collections
show users
show roles
show profile
use appdb
db
db.getName()
db.getMongo().getDBNames()
db.help()
db.orders.help()
// 切换库并认证
db = db.getSiblingDB("admin")
db.auth("admin", "pass")
4.3 导入导出
# 导出集合(JSON / CSV)
mongoexport --uri="mongodb://admin:pass@localhost:27017/appdb?authSource=admin" \
--collection=orders --out=/backup/orders.json
mongoexport --uri="..." --collection=orders --type=csv \
--fields=id,user_id,amount --out=/backup/orders.csv
# 导入
mongoimport --uri="..." --collection=orders --file=/backup/orders.json
mongoimport --uri="..." --collection=orders --type=csv --headerline --file=/backup/orders.csv
# 只导查询结果
mongoexport --uri="..." --collection=orders --query='{"status":1}' --out=st.json
区别:
mongoexport导的是 JSON/CSV 文本,会丢失类型信息(日期变字符串、ObjectId 变$oid结构);备份恢复一律用mongodump(BSON,类型无损)。
5. 认证、用户与角色
5.1 建用户
use admin
db.createUser({
user: "app",
pwd: "App#Str0ng2026",
roles: [
{ role: "readWrite", db: "appdb" },
{ role: "read", db: "reportdb" }
],
customData: { owner: "team-a" }
})
// 应用账号加最小权限
db.createUser({ user: "ro", pwd: "RO#2026", roles: [{ role: "read", db: "appdb" }] })
// 管理员
db.createUser({ user: "dba", pwd: "Dba#2026", roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "clusterAdmin", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" }
]})
5.2 内置角色
| 角色 | 权限 |
|---|---|
read / readWrite |
库级读写 |
dbAdmin / dbOwner |
库管理(索引、统计、校验) |
userAdmin |
库内用户管理 |
clusterAdmin |
副本集/分片/集群管理 |
root |
超级用户(admin 库) |
backup / restore |
备份恢复专用 |
readAnyDatabase / readWriteAnyDatabase |
跨库 |
hostManager |
监控、killOp、shutdown |
5.3 维护命令
// 改密
db.changeUserPassword("app", "New#2026")
// 授权/回收
db.grantRolesToUser("app", [{ role: "read", db: "logdb" }])
db.revokeRolesFromUser("app", [{ role: "read", db: "logdb" }])
// 删除
db.dropUser("app")
// 查看
db.getUser("app")
db.getUsers({ showCredentials: false })
db.getRoles({ showBuiltinRoles: true })
5.4 认证要点
// 认证数据库很关键:用户建在哪个库,就必须用哪个库认证
// admin 库用户
mongosh "mongodb://admin:pass@host:27017/?authSource=admin"
// appdb 库用户
mongosh "mongodb://app:pass@host:27017/appdb?authSource=appdb"
最常见故障:
Authentication failed90% 是authSource写错。用户建在appdb,连接串却写authSource=admin,必然失败。
5.5 安全基线
security:
authorization: enabled
keyFile: /etc/mongo/keyfile
javascriptEnabled: false # 禁服务端 JS,降低攻击面(3.4+ 可用)
net:
bindIp: 10.0.0.11,127.0.0.1
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/ca.pem
// 确认授权已开
db.adminCommand({getCmdLineOpts:1}).parsed.security.authorization
// 确认没有无密码用户
db.system.users.find({}, {user:1, db:1, roles:1}).toArray()
6. 库集合与文档操作
6.1 库与集合
use appdb
db.createCollection("orders", {
validator: { $jsonSchema: {
bsonType: "object",
required: ["user_id", "amount", "created_at"],
properties: {
user_id: { bsonType: "long" },
amount: { bsonType: ["double", "decimal"] },
created_at: { bsonType: "date" }
}
}},
validationLevel: "moderate",
validationAction: "warn"
})
db.createCollection("logs", { capped: true, size: 1073741824, max: 1000000 })
show collections
db.getCollectionNames()
db.orders.stats()
db.dropCollection("orders") // 危险
db.dropDatabase() // 危险,整库删
6.2 增删改查
db.orders.insertOne({ user_id: NumberLong(100), amount: 99.5, status: 1, created_at: new Date() })
db.orders.insertMany([{...}, {...}], { ordered: false })
db.orders.find({ user_id: NumberLong(100) }).limit(10)
db.orders.find({ status: 1 }, { _id: 0, user_id: 1, amount: 1 }).sort({ created_at: -1 }).limit(20)
db.orders.findOne({ _id: ObjectId("...") })
db.orders.updateOne({ _id: ObjectId("...") }, { $set: { status: 2 } })
db.orders.updateMany({ status: 0 }, { $set: { status: 1 } }, { upsert: false })
db.orders.replaceOne({ _id: ... }, { ... })
db.orders.deleteOne({ _id: ... })
db.orders.deleteMany({ created_at: { $lt: ISODate("2025-01-01") } }) // 危险
db.orders.countDocuments({ status: 1 })
db.orders.estimatedDocumentCount()
db.orders.distinct("status")
6.3 聚合
db.orders.aggregate([
{ $match: { created_at: { $gte: ISODate("2026-01-01") } } },
{ $group: { _id: "$status", total: { $sum: "$amount" }, cnt: { $sum: 1 } } },
{ $sort: { total: -1 } },
{ $limit: 10 }
], { allowDiskUse: true })
注意:聚合默认内存上限 100MB,超了报
Exceeded memory limit for $group。加{ allowDiskUse: true }让它落盘,但会慢,更好的做法是优化$match与索引。
6.4 批量与大集合操作
// 分批删除,避免长事务与 oplog 暴涨
let batch = 0;
while (true) {
const ids = db.logs.find({ created_at: { $lt: ISODate("2025-01-01") } }, { _id: 1 }).limit(5000).toArray();
if (ids.length === 0) break;
db.logs.deleteMany({ _id: { $in: ids.map(d => d._id) } });
batch++;
sleep(100);
}
print("batches: " + batch);
// 大批量更新
db.orders.find({ status: 0 }).forEach(function(doc) {
db.orders.updateOne({ _id: doc._id }, { $set: { status: 1 } });
});
7. 索引管理
7.1 创建与查看
db.orders.createIndex({ user_id: 1, created_at: -1 })
db.orders.createIndex({ status: 1 }, { name: "idx_status" })
db.orders.createIndex({ sku: 1 }, { unique: true })
db.orders.createIndex({ tags: 1 }, { sparse: true })
db.orders.createIndex({ desc: "text", title: "text" }, { default_language: "none" })
db.orders.createIndex({ expire_at: 1 }, { expireAfterSeconds: 0 }) // TTL 索引
db.orders.createIndex({ "addr.city": 1 }, { partialFilterExpression: { status: 1 } })
db.orders.getIndexes()
db.orders.getIndexKeys()
db.orders.getIndexSpecs()
db.orders.totalIndexSize()
db.orders.dropIndex("idx_status")
db.orders.dropIndexes() // 删除除 _id 外所有索引,危险
版本差异:4.2 起
background: true选项被忽略——索引构建默认采用混合模式,只在对目标集合加排他锁的极短时间窗口内阻塞写入。老教程强调的"必须 background"已不适用,但大集合建索引仍要走低峰,因为会消耗大量 IO 与 cache。
7.2 索引使用分析
db.orders.aggregate([{ $indexStats: {} }])
// 关注 ops 为 0 的索引:完全没被用过
db.orders.find({ user_id: 100 }).explain("executionStats")
// 关键字段:
// winningPlan.stage: COLLSCAN 表示全表扫,IXSCAN 表示走索引
// totalDocsExamined vs nReturned: 比值接近 1 才健康
// totalKeysExamined
// executionTimeMillis
// 查询计划缓存
db.orders.getPlanCache().list()
db.orders.getPlanCache().clear()
7.3 索引设计原则
| 原则 | 说明 |
|---|---|
| ESR 规则 | Equality → Sort → Range 顺序建复合索引 |
| 前缀可用 | {a:1,b:1} 可支持 {a:1},不支持 {b:1} |
| 覆盖查询 | 只查索引列时用 .explain() 看 totalDocsExamined=0 |
| 单集合索引数 | 建议 ≤ 10,每个索引都放大写入成本 |
| 低选择性字段 | 不要单独建索引(如 status 只有 3 个值) |
| 数组字段 | 多键索引,注意一个文档会生成多个索引项 |
8. 副本集
8.1 初始化(三节点)
三个节点都先起 mongod(同一 replSetName、各自 keyFile),然后在任一节点执行:
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "10.0.0.11:27017", priority: 2 },
{ _id: 1, host: "10.0.0.12:27017", priority: 1 },
{ _id: 2, host: "10.0.0.13:27017", priority: 1 }
]
})
// 用主机名而不是 IP 更利于切换(所有成员的 /etc/hosts 要一致)
rs.initiate()
rs.add("10.0.0.12:27017")
rs.addArb("10.0.0.14:27017") // 仲裁节点,只投票不存数据
rs.remove("10.0.0.13:27017")
注意:成员
host必须能被所有节点解析。用 IP 时如果换了网段,整个副本集要rs.reconfig修改。生产建议用可解析的域名。
8.2 状态查看
rs.status()
rs.status().members.forEach(m => print(m.name, m.stateStr, m.health))
rs.conf()
rs.isMaster() // 看 primary 与 optimes
db.hello() // 5.0+ 推荐替代 isMaster
// 复制延迟
rs.printReplicationInfo() // primary 上的 oplog 窗口
rs.printSecondaryReplicationInfo() // 各 secondary 落后多少秒
// oplog 窗口
use local
db.oplog.rs.stats().maxSize
db.oplog.rs.find().sort({ $natural: -1 }).limit(1)
stateStr 取值:PRIMARY、SECONDARY、ARBITER、STARTUP2、RECOVERING、ROLLBACK、REMOVED、(not reachable/healthy)。
8.3 故障切换
// 主动降级(计划内维护)
rs.stepDown(60) // 60 秒内不再竞选
// 冻结某节点不参与选举
rs.freeze(120)
// 查看选举结果
rs.status().members
db.hello().primary
// 强制重配(多数派不可用时的最后手段)
cfg = rs.conf()
cfg.members = [cfg.members[0]]
rs.reconfig(cfg, { force: true })
危险:
rs.reconfig(..., {force:true})会绕过多数派校验,可能造成数据回滚(原 primary 的未复制写入被丢弃)。只在灾难恢复时用,事后必须全量校验数据。
8.4 读写关注
// 写关注:多数派确认,最多等 5 秒
db.orders.insertOne({...}, { writeConcern: { w: "majority", wtimeout: 5000, j: true } })
// 读关注:线性一致
db.orders.find({...}).readConcern("majority")
db.orders.find({...}).readPref("secondaryPreferred")
// 全局默认
db.adminCommand({ setDefaultRWConcern: 1,
defaultWriteConcern: { w: "majority" },
defaultReadConcern: { level: "local" } })
| 写关注 | 含义 | 场景 |
|---|---|---|
w:1 |
主节点确认 | 可容忍少量丢失 |
w:"majority" |
多数派落盘 | 生产默认 |
w:0 |
不等待 | 日志类,几乎不用 |
j:true |
等 journal 落盘 | 金融级 |
8.5 重新同步节点
// 从节点数据异常时,让它重新全量同步
rs.remove("10.0.0.13:27017")
// 清空该节点 dbPath(停库后操作)
// 重新加入
rs.add("10.0.0.13:27017")
# 停库 → 清数据 → 起库 → 加入
systemctl stop mongod
rm -rf /var/lib/mongo/*
systemctl start mongod
mongosh --eval 'rs.add("10.0.0.13:27017")'
注意:
rs.syncFrom()只是临时指定同步源,不解决数据损坏。真正的修复是清空重同步。
9. 分片集群
9.1 架构
应用 → mongos(可多个)→ config server 副本集(3 节点)
→ shard1 副本集 / shard2 副本集 / ...
| 组件 | 要求 |
|---|---|
| config server | 必须是副本集(3.4 起),存集群元数据 |
| mongos | 无状态,可多个,应用连 mongos |
| shard | 每个分片是一个副本集,至少 2 分片才有意义 |
9.2 部署顺序
# 1) 三个 config server(同一 replSetName: cfgRS)
mongod --configsvr --replSet cfgRS --port 27019 --dbpath /data/config --bind_ip 0.0.0.0 --fork --logpath /data/config.log
# 2) 初始化 config 副本集
mongosh --port 27019 --eval 'rs.initiate({_id:"cfgRS",configsvr:true,members:[
{_id:0,host:"10.0.0.11:27019"},{_id:1,host:"10.0.0.12:27019"},{_id:2,host:"10.0.0.13:27019"}]})'
# 3) 各分片(同一 shardsvr,各自 replSetName)
mongod --shardsvr --replSet shard1 --port 27018 --dbpath /data/shard1 --fork --logpath /data/shard1.log
mongosh --port 27018 --eval 'rs.initiate({_id:"shard1",members:[{_id:0,host:"10.0.0.11:27018"}]})'
# 4) mongos
mongos --configdb cfgRS/10.0.0.11:27019,10.0.0.12:27019,10.0.0.13:27019 \
--port 27017 --fork --logpath /data/mongos.log
# 5) 加 shard
mongosh --port 27017
sh.addShard("shard1/10.0.0.11:27018")
sh.addShard("shard2/10.0.0.12:27018")
9.3 分片配置
// 对库启用分片(不是立刻分,只是允许)
sh.enableSharding("appdb")
// 集合分片:必须先在分片键上建索引
db.orders.createIndex({ user_id: "hashed" })
sh.shardCollection("appdb.orders", { user_id: "hashed" })
// 范围分片
db.logs.createIndex({ created_at: 1 })
sh.shardCollection("appdb.logs", { created_at: 1 })
// 复合分片键
sh.shardCollection("appdb.events", { tenant_id: 1, created_at: 1 })
// 查看
sh.status()
sh.status({ verbose: true })
db.orders.getShardDistribution()
9.4 均衡器
sh.getBalancerState()
sh.isBalancerRunning()
sh.stopBalancer()
sh.startBalancer()
sh.setBalancerState(false)
// 均衡窗口(避免业务高峰迁移 chunk)
use config
db.settings.updateOne({ _id: "balancer" },
{ $set: { activeWindow: { start: "02:00", stop: "05:00" } } }, { upsert: true })
注意:分片键一旦选定不可更改(MongoDB 5.0 起支持
reshardCollection但成本极高)。选错分片键(如单调递增的_id)会导致所有写入集中到最后一个 chunk,形成热点。生产上优先考虑哈希分片或带租户维度的复合键。
9.5 分片运维
// 迁移 chunk
sh.moveChunk("appdb.orders", { user_id: "abc" }, "shard2")
// 拆分 chunk
sh.splitAt("appdb.orders", { user_id: 5000 })
// 查看 chunk 分布
use config
db.chunks.aggregate([{ $group: { _id: "$shard", n: { $sum: 1 } } }])
// 查看分片状态
db.adminCommand({ listShards: 1 })
10. 备份与恢复
10.1 方案对比
| 方案 | 类型 | 一致性 | 适用 |
|---|---|---|---|
mongodump / mongorestore |
逻辑(BSON) | 单库/单集合级 | 中小库、跨版本迁移 |
| 文件系统快照 | 物理 | 需停库或 fsyncLock |
云盘、LVM、大库 |
| Percona Backup for MongoDB(PBM) | 物理 + oplog | 集群级 PITR | 副本集/分片生产首选 |
| MongoDB Ops Manager / Atlas | 托管 | 完整 | 商业版 |
mongoexport |
文本 | 无 | 数据交换,不做备份 |
重要:分片集群不能用 mongodump 直接做整集群一致性备份(各分片备份时间点不同)。分片环境必须用 PBM 或 Ops Manager,或先停均衡器再逐分片备份并记录 oplog。
10.2 mongodump
# 全实例(压缩归档,单文件)
mongodump --uri="mongodb://admin:pass@localhost:27017/?authSource=admin" \
--gzip --archive=/backup/mongo_$(date +%F).gz
# 单库
mongodump --uri="mongodb://admin:pass@localhost:27017/appdb?authSource=admin" \
--gzip --archive=/backup/appdb.gz
# 单集合
mongodump --uri="..." --collection=orders --gzip --archive=/backup/orders.gz
# 副本集:从从节点读,减轻主节点压力
mongodump --uri="mongodb://admin:pass@h2:27017/?authSource=admin&readPreference=secondary" \
--gzip --archive=/backup/mongo.gz
# 目录形式(可并行恢复)
mongodump --uri="..." --out=/backup/dump_dir --gzip
关键参数:
| 参数 | 作用 |
|---|---|
--gzip |
压缩 |
--archive=file |
单文件归档,便于传输 |
--oplog |
记录备份期间的 oplog,得到时间点一致快照(副本集必须加) |
--numParallelCollections |
并行导出集合数 |
--readPreference=secondary |
从从节点读 |
--query |
条件导出 |
--excludeCollection |
排除集合 |
# 带 oplog 的一致性备份(副本集)
mongodump --uri="mongodb://admin:pass@localhost:27017/?authSource=admin&replicaSet=rs0" \
--oplog --gzip --archive=/backup/mongo_oplog.gz
10.3 mongorestore
# 全量恢复(drop 已有数据)
mongorestore --uri="mongodb://admin:pass@localhost:27017/?authSource=admin" \
--gzip --archive=/backup/mongo_2026-11-05.gz --drop
# 单库恢复
mongorestore --uri="..." --gzip --archive=/backup/appdb.gz --nsInclude="appdb.*" --drop
# 恢复到另一个库名
mongorestore --uri="..." --gzip --archive=/backup/appdb.gz --nsFrom="appdb.*" --nsTo="appdb_new.*"
# 带 oplog 重放(PITR)
mongorestore --uri="..." --gzip --archive=/backup/mongo_oplog.gz --oplogReplay
mongorestore --uri="..." --gzip --archive=/backup/mongo_oplog.gz --oplogReplay \
--oplogLimit "1780000000:1" # 恢复到指定时间戳
# 只恢复索引定义不建索引(先导数据后建索引更快)
mongorestore --uri="..." --gzip --archive=/backup/appdb.gz --noIndexRestore
注意:
--drop会先删除目标库中同名集合再恢复。不加--drop则是合并(同_id会报 duplicate key)。生产恢复前务必确认目标库。
10.4 文件系统快照(物理)
// 1) 锁定写入(副本集环境不推荐,会阻塞)
db.fsyncLock()
// 2) 做 LVM/云盘快照
// 3) 解锁
db.fsyncUnlock()
# 更安全的做法:停一个从节点,做快照,再启动
systemctl stop mongod
# LVM snapshot 或云平台快照
systemctl start mongod
10.5 Percona Backup for MongoDB
# 安装后配置存储(本地或 S3)
pbm config --set storage.type=filesystem
pbm config --set storage.filesystem.path=/backup/pbm
# 全量备份
pbm backup --type=full
# 增量(oplog 持续备份)
pbm backup --type=incremental
# 查看
pbm list
pbm status
# 恢复
pbm restore <backup-name>
pbm restore <backup-name> --time "2026-11-05T10:15:00+08:00"
# 开启 oplog 持续备份(PITR 前提)
pbm config --set pitr.enabled=true
pbm config --set pitr.oplogSpanMin=10
推荐:副本集与分片集群的生产备份用 PBM,理由:物理备份快、支持集群级一致性、支持任意时间点恢复、对业务影响小。
mongodump适合单库迁移与中小规模场景。
10.6 备份策略
| 库类型 | 全备 | 增量/Oplog | 保留 |
|---|---|---|---|
| 核心业务 | 每日 1 次 | 持续 oplog(PBM PITR) | 30 天 |
| 一般业务 | 每日 1 次 | 每小时 | 14 天 |
| 日志/埋点 | 每周 1 次 | 不需要 | 7 天 |
11. 日志与审计
11.1 日志配置
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
logRotate: reopen # reopen:配合 logrotate;rename:mongod 自己改名
verbosity: 0 # 0 默认,1~5 递增(调试用,生产别开)
component:
query:
verbosity: 1
storage:
verbosity: 0
// 运行时调整
db.setLogLevel(1) // 全局
db.setLogLevel(2, "query") // 指定组件
db.getLogComponents()
// 手工轮转
db.adminCommand({ logRotate: 1 })
db.adminCommand({ logRotate: "reopen" })
# logrotate 配置
cat > /etc/logrotate.d/mongod <<'EOF'
/var/log/mongodb/mongod.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
/usr/bin/mongosh --quiet --eval 'db.adminCommand({logRotate:"reopen"})' > /dev/null 2>&1 || true
endscript
}
EOF
11.2 日志解读
tail -f /var/log/mongodb/mongod.log
grep -i -E '"s":"E"|"s":"F"' /var/log/mongodb/mongod.log | tail -30 # 错误与致命
grep -i 'Slow query' /var/log/mongodb/mongod.log | tail -20
grep -i -E 'election|replSet' /var/log/mongodb/mongod.log | tail -30
JSON 日志关键字段:
| 字段 | 含义 |
|---|---|
s |
严重级别:I 信息、W 警告、E 错误、F 致命 |
c |
组件(NETWORK、STORAGE、REPL、QUERY、INDEX) |
id |
消息 ID(查文档用) |
ctx |
上下文 |
msg |
描述 |
attr |
附加属性(耗时、命名空间、planSummary) |
11.3 慢查询分析
// 开启 profiler(0 关、1 慢查询、2 全部)
db.setProfilingLevel(1, { slowms: 100 })
db.getProfilingStatus()
// 查最近的慢操作
db.system.profile.find({ millis: { $gt: 500 } }).sort({ ts: -1 }).limit(10).pretty()
// 按命名空间聚合
db.system.profile.aggregate([
{ $match: { millis: { $gt: 100 } } },
{ $group: { _id: "$ns", cnt: { $sum: 1 }, avgMs: { $avg: "$millis" }, maxMs: { $max: "$millis" } } },
{ $sort: { cnt: -1 } }, { $limit: 10 }
])
// 看执行计划摘要
db.system.profile.find({ millis: { $gt: 500 } }, { ns:1, millis:1, planSummary:1, docsExamined:1, keysExamined:1 }).limit(5)
注意:profiler 级别 2 会记录所有操作,生产上会明显增加 IO 与日志量。常规做法是级别 1 +
slowms: 100,仅排障时临时调低。
11.4 审计(企业版)
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.json
filter: '{ atype: { $in: ["authCheck","createUser","dropUser","dropDatabase"] } }'
社区版没有内置审计,需用
$currentOp+ 外部日志采集,或升级企业版。
12. 性能诊断
12.1 实时命令
mongostat --uri="mongodb://admin:pass@localhost:27017/?authSource=admin" 1
mongotop --uri="mongodb://admin:pass@localhost:27017/?authSource=admin" 1
# 关键列:insert/query/update/delete(每秒)、dirty%、used%、conn、qr|qw(读写队列)
db.serverStatus()
db.serverStatus().connections // current / available / totalCreated
db.serverStatus().opcounters
db.serverStatus().wiredTiger.cache // 缓存使用与淘汰
db.serverStatus().globalLock
db.serverStatus().mem
db.currentOp()
12.2 当前操作与慢操作
// 运行超过 5 秒的操作
db.currentOp({ "secs_running": { $gt: 5 }, "active": true })
// 详细字段
db.currentOp({ "secs_running": { $gt: 5 } }).inprog.forEach(op => {
print(op.opid, op.ns, op.secs_running, op.planSummary, op.desc)
})
// 杀掉操作
db.killOp(opid)
// 只杀特定类型的(如全表扫的查询)
db.currentOp({ "planSummary": "COLLSCAN", "secs_running": { $gt: 10 } }).inprog.forEach(o => db.killOp(o.opid))
12.3 WiredTiger 缓存
const c = db.serverStatus().wiredTiger.cache
print("cache used MB:", (c["bytes currently in the cache"]/1024/1024).toFixed(0))
print("cache max MB:", (c["maximum bytes configured"]/1024/1024).toFixed(0))
print("dirty MB:", (c["tracked dirty bytes in the cache"]/1024/1024).toFixed(0))
print("evictions:", c["pages evicted by application threads"])
// 关注:
// dirty > 20% cache → 刷脏压力大
// "pages evicted by application threads" 持续增长 → 缓存不足,应用线程被迫做淘汰
// 缓存命中率
const s = db.serverStatus().wiredTiger.cache
const hit = s["pages read into cache"] || 0
const req = s["pages requested from the cache"] || 0
print("read into cache:", hit, "requested:", req)
12.4 副本集延迟
rs.printSecondaryReplicationInfo()
rs.printReplicationInfo()
// 精确查看各节点 oplog 位置
db.adminCommand({ replSetGetStatus: 1 }).members.forEach(m =>
print(m.name, m.stateStr, m.optimeDate, m.optime))
// oplog 窗口不足是延迟的常见根因
use local
const first = db.oplog.rs.find().sort({ $natural: 1 }).limit(1).next()
const last = db.oplog.rs.find().sort({ $natural: -1 }).limit(1).next()
print("oplog hours:", ((last.ts.t - first.ts.t)/3600).toFixed(1))
12.5 分片集群诊断
sh.status()
db.orders.getShardDistribution()
db.adminCommand({ connPoolStats: 1 })
db.adminCommand({ shardConnPoolStats: 1 })
// 哪个分片是热点
db.orders.aggregate([{ $indexStats: {} }])
// 检查是否有孤立文档(分片迁移残留)
db.adminCommand({ cleanupOrphaned: "appdb.orders" })
13. 空间与压缩
13.1 空间查询
db.stats(1024*1024) // 库级,单位 MB
db.orders.stats({ scale: 1024*1024 }) // 集合级
// 关键字段:size(未压缩逻辑大小)、storageSize(压缩后磁盘占用)、indexSize、totalIndexSize
db.orders.stats().wiredTiger // 块级细节
db.orders.stats().wiredTiger.creationString
// 各集合占用排行
db.getCollectionNames().map(name => {
const s = db.getCollection(name).stats({ scale: 1024*1024 })
return { name, sizeMB: Math.round(s.size), storageMB: Math.round(s.storageSize), idxMB: Math.round(s.totalIndexSize) }
}).sort((a,b) => b.storageMB - a.storageMB)
# 磁盘层
df -h
du -sh /var/lib/mongo/*
ls -lh /var/lib/mongo | sort -k5 -h | tail
13.2 压缩
// 集合级压缩(建集合时指定,或对已有集合重建)
db.createCollection("logs", { storageEngine: { wiredTiger: { configString: "block_compressor=zstd" } } })
// 已有集合改压缩:需要重建(先导出再导入,或用 $out 到新集合)
db.logs.aggregate([{ $match: {} }, { $out: "logs_new" }])
// 然后改名切换
db.logs_new.renameCollection("logs", true)
| 压缩算法 | CPU | 压缩率 | 适用 |
|---|---|---|---|
none |
最低 | 1x | 极少用 |
snappy |
低 | 2~3x | 默认,通用 |
zlib |
中 | 3~4x | 平衡 |
zstd |
中 | 4~6x | 推荐,4.2+ |
13.3 空间回收
// 删除文档不会立刻释放磁盘(WiredTiger 复用 free list)
db.orders.deleteMany({ created_at: { $lt: ISODate("2025-01-01") } })
db.orders.stats().storageSize // 可能不变,这是正常现象
// 真正回收:compact(会锁库,需在维护窗口或从节点操作)
db.runCommand({ compact: "orders" })
db.runCommand({ compact: "orders", force: true }) // 4.4+ 允许在主节点强制
关键:
compact对副本集是逐节点操作。推荐流程:先对从节点 compact → 主从切换 → 再对新从节点 compact。主节点直接 compact 会阻塞该库的读写。
13.4 TTL 与容量治理
// TTL 索引,到期自动删(后台线程每 60 秒扫一次)
db.logs.createIndex({ created_at: 1 }, { expireAfterSeconds: 86400 * 30 })
// 确认 TTL 生效
db.orders.getIndexes().filter(i => i.expireAfterSeconds !== undefined)
// TTL 删除有延迟,不能当成精确的定时任务
14. 升级与迁移
14.1 升级路径
6.0 → 7.0 → 8.0 → 8.3 → 9.0
规则:
- 不能跨大版本直跳(6.0 不能直接升 9.0,需逐级)。
- 副本集用滚动升级:先升所有从节点,最后
rs.stepDown()升主节点,全程不停服。 - 分片集群顺序:先停均衡器 → 升 config server → 升各 shard → 最后升 mongos。
- 升级后必须手动设置
featureCompatibilityVersion。
14.2 滚动升级(副本集)
// 0) 记录当前状态与 FCV
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })
rs.status()
# 1) 逐个升级从节点(替换二进制后重启)
systemctl stop mongod
# 安装新版本包
systemctl start mongod
mongosh --eval 'rs.status().members.forEach(m=>print(m.name, m.stateStr))'
# 等该节点从 STARTUP2/RECOVERING 变回 SECONDARY 再操作下一个
// 2) 主节点降级,让它变成从节点后升级
rs.stepDown(120)
# 3) 升级原主节点
systemctl stop mongod && systemctl start mongod
// 4) 全部节点升完后,提升 FCV
db.adminCommand({ setFeatureCompatibilityVersion: "9.0", confirm: true })
// 5) 验证
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })
重要:
setFeatureCompatibilityVersion是单向的,一旦提升到新版本,回退需要恢复备份。升级前必须做全量备份,并确认驱动/ORM 兼容新版本。
14.3 升级前检查
// 1) 版本与 FCV
db.version()
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })
// 2) 副本集健康
rs.status().members.forEach(m => print(m.name, m.stateStr, m.health))
// 3) 是否有失败的索引构建
db.getSiblingDB("admin").system.indexBuilds.find()
// 4) 弃用特性警告(日志里搜 "Deprecation")
// 5) 磁盘与 oplog 余量
db.stats(1024*1024*1024)
# 6) 备份
mongodump --uri="..." --oplog --gzip --archive=/backup/pre_upgrade_$(date +%F).gz
14.4 迁移(跨实例/跨云)
| 方式 | 适用 | 停机 |
|---|---|---|
mongodump + mongorestore |
中小库、跨版本 | 中 |
| 副本集加节点再摘除 | 大库、低停机 | 极短 |
| PBM 备份恢复 | 大库、集群 | 中 |
mongoexport / mongoimport |
数据交换 | 长 |
# 低停机迁移:把目标端作为新节点加入源副本集,同步完成后提升为主,再摘掉旧节点
# 1) 目标端 mongod 配置相同 replSetName 与 keyFile
# 2) 加入
mongosh --eval 'rs.add("new-host:27017")'
# 3) 同步完成后切换
mongosh --eval 'rs.stepDown(60)'
注意:跨大版本不能用"加节点"方式(副本集要求同版本)。跨版本必须先升级源集群,或走 dump/restore。
15. 高频故障速查
15.1 连不上
| 现象 | 排查 |
|---|---|
Connection refused |
mongod 未起 / bindIp 不含该地址 / 防火墙 |
Authentication failed |
authSource 写错 / 密码错 / 用户不在该库 |
not authorized on admin to execute command |
角色不足,需 clusterAdmin 等 |
Server selection timeout |
副本集名称不匹配 / 成员不可达 / 多数派不可用 |
No suitable servers found |
读偏好与节点状态冲突(如 secondary 但无从节点) |
MongoServerError: command insert requires authentication |
没带认证信息 |
mongosh --host 10.0.0.11 --port 27017 --eval 'db.adminCommand({ping:1})'
ss -lntp | grep 27017
tail -100 /var/log/mongodb/mongod.log | grep -i -E 'error|refused|bind'
// 确认用户与认证库
use admin
db.system.users.find({ user: "app" }, { user:1, db:1, roles:1 })
15.2 副本集无主(No primary)
rs.status()
// 看 stateStr 与 health,多数节点不可达时无法选出主
// 常见原因与处理
// 1) 多数派挂掉 → 恢复节点网络,不要急着 force reconfig
// 2) 配置版本冲突 → 检查 rs.conf().version
// 3) 时钟不同步 → 检查 NTP
// 4) 磁盘满导致节点 crash → 清空间后重启
// 最后手段(可能丢数据)
cfg = rs.conf()
cfg.members = [cfg.members[0]]
rs.reconfig(cfg, { force: true })
15.3 复制延迟
rs.printSecondaryReplicationInfo()
| 原因 | 处理 |
|---|---|
| oplog 窗口太小(写入量大时从节点追不上) | 加大 oplogSizeMB,需重启或 replSetResizeOplog |
| 从节点磁盘/CPU 不足 | 扩容或降读压力 |
| 大事务/批量写 | 拆批,降低单次写入量 |
| 索引构建 | 低峰建索引,或先摘节点再建 |
| 网络带宽 | 检查链路 |
// 在线调整 oplog 大小(4.0+,不用重启)
db.adminCommand({ replSetResizeOplog: 1, size: 102400 }) // MB
15.4 磁盘满
df -h
du -sh /var/lib/mongo/*
// 1) 看谁占空间
db.getCollectionNames().map(n => ({ n, mb: Math.round(db.getCollection(n).stats().storageSize/1048576) }))
.sort((a,b) => b.mb - a.mb).slice(0,10)
// 2) 清日志类集合(先确认可删)
db.logs.deleteMany({ created_at: { $lt: ISODate("2025-11-01") } })
// 3) 检查是否有巨大索引
db.orders.stats().totalIndexSize
// 4) 清理残留的临时文件
db.adminCommand({ compact: "logs" })
急救顺序:删可清理的集合数据 → 清理日志文件 → 扩容磁盘。磁盘 100% 时 mongod 会进入只读甚至崩溃,必须留 10% 余量。
15.5 连接数打满
db.serverStatus().connections
// { current: 900, available: 100, totalCreated: 50000 }
db.currentOp({ active: true }).inprog.length
// 找出连接来源
db.currentOp(true).inprog.forEach(o => print(o.client, o.appName, o.secs_running))
处理:确认应用连接池配置(通常 maxPoolSize 过大)→ 清理空闲连接 → 提高 net.maxIncomingConnections(但这只是缓解)。
15.6 慢查询
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find({ millis: { $gt: 500 } })
.sort({ ts: -1 }).limit(5)
.forEach(p => print(p.ns, p.millis, p.planSummary,
"examined:", p.docsExamined, "returned:", p.nreturned))
// 全表扫的查询
db.system.profile.find({ planSummary: "COLLSCAN", millis: { $gt: 100 } }).count()
对策:补索引、改查询条件顺序(ESR 规则)、避免 $regex 前缀通配、避免对大集合 $lookup。
15.7 分片热点
sh.status()
db.orders.getShardDistribution()
// 检查 chunk 分布是否均匀
use config
db.chunks.aggregate([
{ $group: { _id: { shard: "$shard", coll: "$ns" }, n: { $sum: 1 } } },
{ $sort: { n: -1 } }
])
热点根因多为单调递增分片键(如时间戳、自增 ID)。处理:改用哈希分片,或建复合分片键(租户 + 时间)。
15.8 数据损坏
// 校验集合
db.orders.validate({ full: true })
// 输出会提示 invalid BSON、missing index 等
// 处理优先级:
// 1) 从备份恢复该集合
// 2) 从其他副本集成员重新同步(清空该节点数据后重新加入)
// 3) db.repairDatabase()(4.4 起不推荐,优先重新同步)
注意:
validate({full:true})会锁集合且耗时,大集合务必在从节点执行。
16. 危险命令与避坑清单
| 命令 | 后果 | 防护 |
|---|---|---|
db.dropDatabase() |
整库消失 | 收回 dbAdmin 权限;操作前 dump |
db.collection.drop() |
集合与索引全丢 | 同上 |
deleteMany({}) |
全集合清空,oplog 暴涨 | 先 countDocuments 确认 |
updateMany({}, {...}) |
全集合改写 | 先查条件命中数 |
rs.reconfig(cfg, {force:true}) |
可能数据回滚 | 只在多数派不可用时用 |
rs.stepDown() 频繁调用 |
反复选举,服务抖动 | 间隔 ≥ 60 秒 |
db.runCommand({compact}) 在主节点 |
阻塞该库读写 | 逐从节点做 + 切换 |
db.fsyncLock() 后忘记 unlock |
写入永久阻塞 | 用 fsyncUnlock,并设超时提醒 |
kill -9 mongod |
崩溃恢复,可能丢未落盘数据 | 用 db.shutdownServer() |
setFeatureCompatibilityVersion 提升 |
不可逆 | 升级前全备 + 测试驱动兼容 |
| 分片键选单调递增值 | 写入热点,集群失衡 | 用哈希或复合键 |
mongodump 不带 --oplog 备副本集 |
备份点不一致 | 副本集备份必加 --oplog |
用 mongoexport 做备份 |
类型丢失,无法完整恢复 | 用 mongodump |
社区版开 --noauth 暴露公网 |
数据被勒索(历史高发) | 强制 authorization: enabled + bindIp 内网 |
特别提醒:MongoDB 历史上是勒索软件的重点目标,大量事故源于"监听 0.0.0.0 + 无认证"。任何对公网可及的实例都必须开认证与 TLS,且不要用默认 27017 端口暴露。
16.1 变更前检查清单
// 1) 确认连的是哪个实例/角色
db.hello().me
db.hello().isWritablePrimary
rs.status().members.forEach(m => print(m.name, m.stateStr))
// 2) 备份
// mongodump --oplog --gzip --archive=/backup/pre_change.gz
// 3) 看集合规模
db.orders.stats({ scale: 1024*1024 })
// 4) 看当前操作与慢查询
db.currentOp({ secs_running: { $gt: 3 }, active: true })
// 5) 看复制延迟
rs.printSecondaryReplicationInfo()
// 6) 变更(大集合操作分批)
17. 附录:巡检脚本与速查
17.1 巡检脚本(mongosh)
// 用法:mongosh "mongodb://admin:pass@localhost:27017/?authSource=admin" --file health.js
print("========== 版本 ==========");
print("version: " + db.version());
print("uptime h: " + (db.serverStatus().uptime / 3600).toFixed(1));
print("\n========== 连接 ==========");
const conn = db.serverStatus().connections;
printjson({ current: conn.current, available: conn.available, totalCreated: conn.totalCreated });
print("\n========== 副本集 ==========");
try {
const st = rs.status();
st.members.forEach(m => print(m.name + " " + m.stateStr + " health=" + m.health));
print("primary: " + db.hello().primary);
} catch (e) { print("非副本集: " + e.message); }
print("\n========== 复制延迟 ==========");
try { rs.printSecondaryReplicationInfo(); } catch (e) {}
print("\n========== 操作计数 ==========");
printjson(db.serverStatus().opcounters);
print("\n========== WiredTiger 缓存 ==========");
const c = db.serverStatus().wiredTiger.cache;
print("used MB: " + (c["bytes currently in the cache"]/1048576).toFixed(0));
print("max MB: " + (c["maximum bytes configured"]/1048576).toFixed(0));
print("dirty MB: " + (c["tracked dirty bytes in the cache"]/1048576).toFixed(0));
print("app-thread evictions: " + c["pages evicted by application threads"]);
print("\n========== 各库大小 ==========");
db.adminCommand({ listDatabases: 1, nameOnly: false }).databases
.sort((a,b) => b.sizeOnDisk - a.sizeOnDisk)
.slice(0, 10)
.forEach(d => print(d.name + " " + (d.sizeOnDisk/1048576).toFixed(0) + " MB"));
print("\n========== 运行超过 3 秒的操作 ==========");
db.currentOp({ secs_running: { $gt: 3 }, active: true }).inprog
.forEach(o => print(o.opid + " " + o.ns + " " + o.secs_running + "s " + o.planSummary));
print("\n========== 慢查询数(profiler) ==========");
try { printjson(db.getProfilingStatus()); } catch (e) {}
17.2 单行命令速查
mongod --version
mongosh --eval "db.version()"
mongostat --uri="..." 1
mongotop --uri="..." 1
mongodump --uri="..." --oplog --gzip --archive=/backup/x.gz
mongorestore --uri="..." --gzip --archive=/backup/x.gz --drop
mongoexport --uri="..." --collection=c --out=c.json
mongoimport --uri="..." --collection=c --file=c.json
mongosh --eval "rs.status()"
mongosh --eval "db.adminCommand({logRotate:1})"
mongosh --eval "db.shutdownServer()"
17.3 关键命令速查(mongosh)
| 命令 | 作用 |
|---|---|
db.hello() |
当前节点角色、主节点信息 |
rs.status() |
副本集成员状态 |
rs.conf() |
副本集配置 |
rs.printReplicationInfo() |
oplog 窗口 |
rs.printSecondaryReplicationInfo() |
从节点延迟 |
sh.status() |
分片集群状态 |
db.currentOp() |
当前操作 |
db.killOp(opid) |
终止操作 |
db.serverStatus() |
实例状态 |
db.stats() |
库统计 |
db.coll.stats() |
集合统计 |
db.coll.explain() |
执行计划 |
db.coll.validate() |
数据校验 |
db.setProfilingLevel() |
慢查询开关 |
db.adminCommand({compact}) |
回收空间 |
db.adminCommand({listDatabases:1}) |
库清单 |
db.adminCommand({replSetGetStatus:1}) |
副本集状态(同 rs.status) |
db.adminCommand({setFeatureCompatibilityVersion}) |
升级后开特性 |
17.4 关键路径与端口
| 项 | 值 |
|---|---|
| 默认端口 | 27017(mongos 也用这个) |
| config server 常用端口 | 27019 |
| shard 常用端口 | 27018 |
| 配置文件 | /etc/mongod.conf |
| 数据目录 | /var/lib/mongo(RPM)/ /var/lib/mongodb(DEB) |
| 日志 | /var/log/mongodb/mongod.log |
| keyFile | /etc/mongo/keyfile(权限 400) |
| 诊断命令 | mongostat、mongotop、mongosh --eval |
附:与工作区其他手册的配合
- 操作系统层见
CentOS-7-10-常规运维指令手册.md/Ubuntu-常用运维指令手册.md - 放行端口:
firewall-cmd --add-port=27017/tcp --permanent - 内存规划:WiredTiger cache 建议
(物理内存 - 1GB) × 50%~60%,剩余留给文件系统缓存与连接开销 - 与其他数据库的核心差异:无固定 schema、索引构建默认不长时间锁表、副本集是基本部署单元(单机等于 1 节点副本集)、oplog 是所有复制的核心、
mongodump必须配--oplog才能得到一致快照