MongoDB 初学者必备管理命令

掌握使用 `mongosh` shell 进行 MongoDB 管理的基本命令。本指南涵盖初学者的基本任务,包括数据库切换、集合创建/删除、带角色的用户管理以及关键的系统健康检查(如 `serverStatus`)。学习安全管理 NoSQL 环境所需的基本命令。

MongoDB 初学者必备管理命令

MongoDB 管理从 mongosh 开始,但目标不是记住每个命令。目标是知道如何安全地查看、确认当前位置、有意识地做出小改动,并避免在错误的数据库上执行破坏性命令。

如果你是 MongoDB 新手,请先在本地实例或可丢弃的开发数据库上练习这些命令。本指南中的某些命令,如 dropDatabase()drop(),会永久删除数据。MongoDB 会执行你的指令;它不会知道你的本意是在其他地方运行该命令。

使用 mongosh 连接

对于默认端口上的本地 MongoDB 实例,使用以下命令连接:

mongosh

对于远程服务器,使用管理员或托管提供商提供的连接字符串:

mongosh "mongodb://[email protected]:27017/admin"

对于 TLS、副本集或 MongoDB Atlas,URI 将包含更多选项。尽可能避免将密码粘贴到 shell 历史记录中。使用提示、特定于环境的秘密处理或平台的凭据工具。

连接后,检查你所在的位置:

db

这将打印当前数据库上下文。许多错误始于假设 shell 指向一个数据库,而实际上它指向另一个。

列出和切换数据库

显示可见的数据库:

show dbs

如果你的用户缺少权限,你可能看不到所有数据库。这在安全环境中是正常的。

使用 use 切换数据库上下文:

use myAppDB

运行 use 时,MongoDB 不会立即创建数据库。它会在首次写入数据时创建,例如插入文档或显式创建集合时。

再次检查当前数据库:

db

对于脚本,最好使用显式的数据库句柄,这样代码就不太依赖于 shell 上下文:

const appdb = db.getSiblingDB("myAppDB")
appdb.getCollectionNames()

集合:列出、创建、检查、删除

列出当前数据库中的集合:

show collections

或者使用 JavaScript:

db.getCollectionNames()

当你需要验证、限制行为或集群/索引选择等选项时,显式创建集合(这些选项取决于你的 MongoDB 版本):

db.createCollection("logs")

大多数应用程序集合会在首次插入时自动创建,但对于管理设置,显式创建更清晰。

检查集合统计信息:

db.orders.stats()

查看索引:

db.orders.getIndexes()

删除集合是破坏性的:

db.logs.drop()

在任何共享环境中运行之前,请确认数据库和集合:

db
db.getCollectionNames()
db.logs.countDocuments({})

对于非常大的集合,countDocuments({}) 可能代价高昂。在这种情况下,请使用元数据、抽样或操作仪表板,而不是在高峰流量期间运行广泛的计数。

插入测试文档并查询

即使是管理员也需要一些基本的 CRUD 操作来进行验证。插入一个小文档:

db.healthcheck.insertOne({ source: "admin-test", createdAt: new Date() })

读回它:

db.healthcheck.find({ source: "admin-test" }).sort({ createdAt: -1 }).limit(5)

仅删除测试文档:

db.healthcheck.deleteMany({ source: "admin-test" })

使用特定的过滤器。在学习时避免广泛的删除。像 deleteMany({}) 这样的命令会删除集合中的每个文档。

用户管理基础

用户命令针对定义用户的数据库运行。管理用户通常在 admin 中创建。应用程序用户可以在应用程序数据库中创建,具体取决于你的安全模型。

切换到 admin

use admin

使用提示密码创建管理用户:

db.createUser({
  user: "appAdmin",
  pwd: passwordPrompt(),
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" }
  ]
})

对于普通应用程序,请使用更窄的权限。例如,一个只读写 myAppDB 的应用程序不应获得广泛的管理角色:

use myAppDB

db.createUser({
  user: "myAppUser",
  pwd: passwordPrompt(),
  roles: [
    { role: "readWrite", db: "myAppDB" }
  ]
})

列出当前数据库中的用户:

show users

小心更新角色:

db.grantRolesToUser("myAppUser", [ { role: "read", db: "reporting" } ])

同样谨慎地删除角色:

db.revokeRolesFromUser("myAppUser", [ { role: "read", db: "reporting" } ])

最安全的习惯是最小权限:只给用户工作所需的数据库和角色。

服务器状态和当前操作

serverStatus 返回一个包含计数器和运行时信息的大型文档:

db.serverStatus()

初学者通常不需要整个文档。提取你关心的部分:

db.serverStatus().connections
db.serverStatus().mem
db.serverStatus().opcounters

当前操作可以在某些事情卡住或缓慢时提供帮助:

db.currentOp()

在繁忙的服务器上,过滤它:

db.currentOp({ active: true, secs_running: { $gte: 5 } })

不要随意终止操作。如果你需要终止一个操作,请先检查它,并了解它是用户查询、索引构建、备份、迁移还是内部复制工作。

副本集检查

如果你的部署是副本集,这些命令很常见:

rs.status()
rs.conf()

rs.status() 显示成员、健康状态、状态、optime 信息以及哪个节点是主节点。当应用程序报告写入失败、节点重启或怀疑复制延迟时,运行它。

为了快速检查读取偏好,询问当前节点它认为自己是哪个节点:

db.hello()

较旧的示例可能使用 isMaster()。较新的 MongoDB 版本支持 hello;你可能仍然会在现有脚本中看到旧命令。

危险命令需要仪式

对于破坏性工作,放慢速度。一个简单的仪式可以防止实际的中断:

db
show collections
// 在终端提示或笔记中确认主机名或连接字符串
// 如果是生产环境,确认备份或恢复计划
db.collectionName.drop()

对于数据库删除:

use databaseToRemove
db.dropDatabase()

该命令删除当前数据库。危险不在于语法;危险在于处于错误的上下文中。

初学者友好的管理检查清单

当你连接到 MongoDB 环境时,习惯这个顺序:

db
show dbs
use myAppDB
show collections
db.orders.getIndexes()
db.serverStatus().connections
db.currentOp({ active: true })

这些命令告诉你你在哪里、存在什么、基本访问是否有效,以及现在是否有任何明显的事情发生。

当你首先将 mongosh 视为检查工具,其次才是更改工具时,MongoDB 管理会变得不那么令人生畏。查看、确认、然后行动。使用窄角色、提示密码、过滤查询和显式数据库名称。这个习惯比记住一长串命令更重要。

仔细阅读数据库和集合大小

初学者经常使用 show dbs 作为调整大小的工具,但这只是一个起点。存储引擎、压缩、索引和已删除的空间可能会使大小数字令人惊讶。当你需要更多细节时,使用集合统计信息:

db.orders.stats()

也要查看索引大小:

db.orders.totalIndexSize()

索引不是免费的。它们加速读取和某些排序,但每个索引都会增加写入开销和存储。如果一个集合有很多索引并且写入很慢,列出它们并询问哪些查询实际使用了它们:

db.orders.getIndexes()
db.orders.find({ customerId: "c123" }).explain("executionStats")

不要在生产环境中随意删除索引。一个看起来未使用的索引可能支持月度报告或很少使用的管理屏幕。在删除之前,检查查询日志、应用程序所有者和监控。

基本备份意识

命令行管理应始终与备份习惯相关联。在进行破坏性维护之前,了解数据库的备份方式以及恢复测试的方式。在自管理的 MongoDB 中,你可能会看到用于逻辑备份的 mongodumpmongorestore

mongodump --uri "mongodb://user@host:27017/myAppDB" --out ./backup

对于大型生产系统,文件系统快照、云提供商快照、Ops Manager 或 Atlas 备份可能更合适。初学者的要点很简单:除非你有经过测试的恢复路径,否则不要将 dropdeleteMany 或角色更改视为可逆的。

你从未恢复过的备份只是一个假设。练习在非生产环境中恢复,以便在发生事件之前了解凭据、网络访问和版本兼容性。

当命令不够时检查日志

mongosh 显示服务器响应,但它不能替代日志。如果用户报告查询缓慢、身份验证失败或连接波动,请检查 MongoDB 日志和平台日志。在自管理的 Linux 部署中,日志可能位于 /var/log/mongodb/ 下,具体取决于包和配置。在容器中,使用容器运行时日志。在 Atlas 中,使用 Atlas UI 和可下载的日志。

一个常见的初学者错误是盯着 serverStatus(),而真正的线索是 MongoDB 外部的日志中的身份验证失败、DNS 问题、TLS 不匹配或应用程序连接池耗尽。

了解数据库角色和操作系统访问之间的区别

MongoDB 用户不是 Linux 用户。在 MongoDB 中创建 myAppUser 不会创建 shell 帐户。授予某人数据库服务器的 SSH 访问权限不会自动授予他们数据库权限,尽管如果服务器配置不当,可能会给他们带来危险的间接访问。

保持这些层分开:

Linux 用户:控制对主机和文件的访问
MongoDB 用户:控制数据库身份验证和授权
网络策略:控制谁可以访问 MongoDB 端口
TLS:保护流量并可以支持基于证书的身份

一个安全的部署需要考虑所有这些因素。如果数据库在没有防火墙规则的情况下公开监听,那么强 MongoDB 密码是不够的。如果每个应用程序都使用管理员角色,那么私有网络也是不够的。

生产 shell 的更安全习惯

在生产环境中工作时,使提示和连接显而易见。一些团队使用终端颜色、shell 别名或只读用户进行检查。至少,在连接后运行一些身份检查:

db.runCommand({ connectionStatus: 1 })
db
db.hello()

connectionStatus 显示经过身份验证的用户和角色。db 显示上下文。hello 提供拓扑信息。这三个检查可以防止大量令人惊讶的错误。

对于例行检查,使用只读帐户。仅在特定的更改窗口切换到特权帐户。这种小的摩擦是有用的。它迫使你注意到你即将做一些可以更改数据的事情。

何时停下来寻求帮助

有些 MongoDB 命令对初学者友好;有些则不是。对副本集重新配置、分片元数据、强制重新配置、终止操作、压缩集合以及在实时系统上更改身份验证设置要谨慎。这些操作可能会影响可用性。

如果命令更改集群拓扑或删除数据,请暂停并获得第二次审查。最好的管理员不是打字最快的人。他们是知道何时命令需要备份、维护窗口和另一双眼睛的人。

在高层次上理解读关注和写关注

初学者不需要在第一天调整读关注和写关注,但他们应该知道这些设置存在。写关注控制 MongoDB 在写入后给出的确认。更强的写关注可以等待复制到更多成员。较弱的写关注可能更快返回,但在故障时对持久性的保证较少。

读关注控制读取请求的数据一致性级别。在许多简单的应用程序中,默认值是可以的,但在副本集和分布式系统中,这些设置会影响应用程序在故障转移或复制延迟期间可以安全地假设什么。

管理课程是实用的:当有人报告“MongoDB 丢失了写入”或“应用程序读取了过时数据”时,不要只看插入命令。检查驱动程序设置、写关注、读偏好、读关注、副本集健康和应用程序重试行为。

小心从互联网复制的示例

MongoDB 语法随着时间的推移发生了变化。较旧的博客文章可能使用旧的 mongo shell 而不是 mongosh、旧的辅助名称或仍然有效但不再首选的命令。一些示例还在禁用身份验证的情况下运行,这不是一个安全的生产假设。

复制命令时,问三个问题:

这是为哪个 MongoDB 版本编写的?
它在哪个数据库上下文中运行?
连接的用户需要什么权限?

如果命令是破坏性的,添加第四个问题:如果出现问题,我如何恢复?

在不放弃 shell 的情况下使用 Compass 和 Atlas

图形工具很有用。MongoDB Compass 可以帮助检查文档、索引和查询计划。Atlas 为托管集群提供监控、备份、警报和用户管理。这些工具通常比原始 shell 输出更容易进行视觉检查。

尽管如此,还是要学习 shell 命令。在事件、自动化、仅 SSH 环境或文档审查期间,精确的 mongosh 命令比“单击 UI 中的第三个选项卡”更容易共享。最好的工作流程不是 shell 与 GUI。使用 GUI 进行探索,使用 shell 清晰地表达可重复的操作。