MongoDB 常用运维指令手册

运维指令手册 39.1 KB 原文

MongoDB 常用运维指令手册

适用版本:MongoDB 6.0 / 7.0 / 8.0 / 8.3 / 9.0(on-premises GA 版本) 约定:# root 或 sudo,$ 普通用户,rs0 [primary]> mongosh 提示符,<xxx> 为占位符。 差异标注:正文用 > **版本差异** 引用块标注跨版本不一致之处。 更新时间:2026-11


目录

  1. 版本与支持周期
  2. 下载地址与安装
  3. 服务启停与配置
  4. mongosh 连接与基本操作
  5. 认证、用户与角色
  6. 库集合与文档操作
  7. 索引管理
  8. 副本集
  9. 分片集群
  10. 备份与恢复
  11. 日志与审计
  12. 性能诊断
  13. 空间与压缩
  14. 升级与迁移
  15. 高频故障速查
  16. 危险命令与避坑清单
  17. 附录:巡检脚本与速查

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 failed 90% 是 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

规则:

  1. 不能跨大版本直跳(6.0 不能直接升 9.0,需逐级)。
  2. 副本集用滚动升级:先升所有从节点,最后 rs.stepDown() 升主节点,全程不停服。
  3. 分片集群顺序:先停均衡器 → 升 config server → 升各 shard → 最后升 mongos。
  4. 升级后必须手动设置 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 才能得到一致快照