MongoDB 常用命令和常见问题大全

MongoDB 用起来并不复杂,但实际开发、测试和服务器运维过程中,经常会遇到这样的情况:

text 复制代码
数据库忘了怎么切换
Collection 怎么创建
用户怎么创建
密码怎么修改
索引怎么看
慢查询怎么排查
MongoDB 为什么连不上
27017 为什么没监听
认证为什么失败
磁盘为什么突然满了
怎么备份和恢复
Replica Set 怎么看状态

很多命令其实并不难,但隔一段时间不用就容易忘。

所以这篇文章整理一份比较完整的 MongoDB 常用命令和常见问题速查手册。

适合:

text 复制代码
MongoDB 初学者
后端开发
Go / Java / Python / Node.js 开发
服务器运维
Docker 用户
MongoDB 生产环境排查

文中的命令主要基于:

text 复制代码
mongosh
MongoDB 7.x / 8.x
Linux

来演示。


一、MongoDB 最常用的连接命令

最简单的连接:

bash 复制代码
mongosh

默认连接:

text 复制代码
mongodb://127.0.0.1:27017

也可以明确指定:

bash 复制代码
mongosh mongodb://127.0.0.1:27017

指定服务器:

bash 复制代码
mongosh --host 192.168.1.100

指定端口:

bash 复制代码
mongosh \
  --host 192.168.1.100 \
  --port 27017

二、带用户名和密码连接

例如管理员用户:

text 复制代码
用户名:admin
认证库:admin

执行:

bash 复制代码
mongosh \
  --host 127.0.0.1 \
  --port 27017 \
  -u admin \
  -p \
  --authenticationDatabase admin

执行以后终端会提示输入密码。

这种方式比较推荐,因为不会直接把密码暴露在:

text 复制代码
Shell History
ps
命令日志

中。


三、使用 MongoDB URI 连接

例如:

bash 复制代码
mongosh "mongodb://admin:password@127.0.0.1:27017/admin"

业务数据库:

bash 复制代码
mongosh \
"mongodb://javapub_user:password@127.0.0.1:27017/javapub?authSource=javapub"

如果认证用户创建在 admin

bash 复制代码
mongosh \
"mongodb://javapub_user:password@127.0.0.1:27017/javapub?authSource=admin"

四、密码有特殊字符怎么办?

假设密码:

text 复制代码
abc@123

不能直接:

text 复制代码
mongodb://user:abc@123@127.0.0.1:27017

因为:

text 复制代码
@

本身属于 URI 特殊字符。

应该 URL Encode:

text 复制代码
abc%40123

于是:

text 复制代码
mongodb://user:abc%40123@127.0.0.1:27017

常见特殊字符:

text 复制代码
@   %40
:   %3A
/   %2F
#   %23
?   %3F
%   %25

这是 MongoDB 连接失败里非常常见的一个问题。


五、查看当前数据库

进入 mongosh 后:

javascript 复制代码
db

可能看到:

text 复制代码
test

六、查看所有数据库

javascript 复制代码
show dbs

也可以:

javascript 复制代码
show databases

七、切换数据库

例如:

javascript 复制代码
use javapub

再次:

javascript 复制代码
db

输出:

text 复制代码
javapub

注意:

use javapub 并不意味着数据库已经真正创建。

只有真正插入数据后,MongoDB 才会持久化这个数据库。


八、创建数据库

MongoDB 不需要显式:

sql 复制代码
CREATE DATABASE

直接:

javascript 复制代码
use javapub

插入数据:

javascript 复制代码
db.users.insertOne({
    name: "JavaPub"
})

此时数据库就会真正创建。


九、删除数据库

先切换:

javascript 复制代码
use javapub

执行:

javascript 复制代码
db.dropDatabase()

结果类似:

javascript 复制代码
{
  ok: 1,
  dropped: "javapub"
}

生产环境一定慎用。


十、查看所有 Collection

javascript 复制代码
show collections

也可以:

javascript 复制代码
db.getCollectionNames()

例如:

javascript 复制代码
[
    "users",
    "orders",
    "articles"
]

十一、创建 Collection

通常没必要手动创建。

直接插入:

javascript 复制代码
db.users.insertOne({
    name: "JavaPub"
})

MongoDB 会自动创建:

text 复制代码
users

如果需要显式创建:

javascript 复制代码
db.createCollection("users")

十二、删除 Collection

javascript 复制代码
db.users.drop()

返回:

text 复制代码
true

十三、插入一条数据

javascript 复制代码
db.users.insertOne({
    name: "JavaPub",
    age: 28,
    email: "hello@example.com"
})

十四、插入多条数据

javascript 复制代码
db.users.insertMany([
    {
        name: "Alice",
        age: 20
    },
    {
        name: "Bob",
        age: 25
    },
    {
        name: "Tom",
        age: 30
    }
])

十五、查询全部数据

javascript 复制代码
db.users.find()

格式化查看:

javascript 复制代码
db.users.find().pretty()

十六、查询一条数据

javascript 复制代码
db.users.findOne()

指定条件:

javascript 复制代码
db.users.findOne({
    name: "JavaPub"
})

十七、等值查询

javascript 复制代码
db.users.find({
    name: "JavaPub"
})

多个条件:

javascript 复制代码
db.users.find({
    name: "JavaPub",
    age: 28
})

这相当于:

text 复制代码
name = JavaPub
AND
age = 28

十八、查询大于某个值

javascript 复制代码
db.users.find({
    age: {
        $gt: 18
    }
})

十九、大于等于

javascript 复制代码
db.users.find({
    age: {
        $gte: 18
    }
})

二十、小于

javascript 复制代码
db.users.find({
    age: {
        $lt: 30
    }
})

二十一、小于等于

javascript 复制代码
db.users.find({
    age: {
        $lte: 30
    }
})

二十二、不等于

javascript 复制代码
db.users.find({
    age: {
        $ne: 18
    }
})

二十三、范围查询

查询:

text 复制代码
18 <= age <= 30

执行:

javascript 复制代码
db.users.find({
    age: {
        $gte: 18,
        $lte: 30
    }
})

二十四、IN 查询

类似 SQL:

sql 复制代码
WHERE age IN (18, 20, 25)

MongoDB:

javascript 复制代码
db.users.find({
    age: {
        $in: [18, 20, 25]
    }
})

二十五、NOT IN

javascript 复制代码
db.users.find({
    age: {
        $nin: [18, 20, 25]
    }
})

二十六、OR 查询

javascript 复制代码
db.users.find({
    $or: [
        {
            age: 18
        },
        {
            name: "JavaPub"
        }
    ]
})

相当于:

text 复制代码
age = 18
OR
name = JavaPub

二十七、AND 查询

实际上:

javascript 复制代码
db.users.find({
    name: "JavaPub",
    age: 28
})

默认就是 AND。

也可以写:

javascript 复制代码
db.users.find({
    $and: [
        {
            age: {
                $gte: 18
            }
        },
        {
            age: {
                $lte: 30
            }
        }
    ]
})

二十八、判断字段是否存在

查询有 email 字段的数据:

javascript 复制代码
db.users.find({
    email: {
        $exists: true
    }
})

查询没有 email:

javascript 复制代码
db.users.find({
    email: {
        $exists: false
    }
})

二十九、查询 NULL

javascript 复制代码
db.users.find({
    email: null
})

需要注意:

text 复制代码
email: null

可能匹配:

text 复制代码
email 本身为 null
或者字段不存在

如果只想找真正存在且为 null:

javascript 复制代码
db.users.find({
    email: null,
    email: {
        $exists: true
    }
})

实际项目中可以根据数据结构进一步调整。


三十、模糊查询

例如查名字包含:

text 复制代码
Java

可以:

javascript 复制代码
db.users.find({
    name: /Java/
})

忽略大小写:

javascript 复制代码
db.users.find({
    name: /javapub/i
})

也可以:

javascript 复制代码
db.users.find({
    name: {
        $regex: "javapub",
        $options: "i"
    }
})

三十一、查询数组

例如:

json 复制代码
{
    "name": "JavaPub",
    "tags": [
        "Go",
        "AI",
        "Web3"
    ]
}

查询包含:

text 复制代码
Go
javascript 复制代码
db.users.find({
    tags: "Go"
})

三十二、数组同时包含多个值

javascript 复制代码
db.users.find({
    tags: {
        $all: [
            "Go",
            "AI"
        ]
    }
})

三十三、查询数组长度

javascript 复制代码
db.users.find({
    tags: {
        $size: 3
    }
})

三十四、查询嵌套对象

数据:

json 复制代码
{
    "name": "JavaPub",
    "profile": {
        "city": "Beijing",
        "website": "https://javapub.net.cn"
    }
}

查询:

javascript 复制代码
db.users.find({
    "profile.city": "Beijing"
})

三十五、只返回指定字段

类似 SQL:

sql 复制代码
SELECT name, age FROM users;

MongoDB:

javascript 复制代码
db.users.find(
    {},
    {
        name: 1,
        age: 1
    }
)

默认还会返回:

text 复制代码
_id

如果不想要:

javascript 复制代码
db.users.find(
    {},
    {
        _id: 0,
        name: 1,
        age: 1
    }
)

三十六、排序

年龄升序:

javascript 复制代码
db.users.find().sort({
    age: 1
})

降序:

javascript 复制代码
db.users.find().sort({
    age: -1
})

按照创建时间倒序:

javascript 复制代码
db.users.find().sort({
    created_at: -1
})

三十七、限制返回数量

只查 10 条:

javascript 复制代码
db.users.find().limit(10)

三十八、跳过数据

跳过前 10 条:

javascript 复制代码
db.users.find().skip(10)

三十九、分页查询

例如:

text 复制代码
page = 2
pageSize = 10

执行:

javascript 复制代码
db.users
    .find()
    .skip(10)
    .limit(10)

计算公式:

text 复制代码
skip = (page - 1) * pageSize

四十、统计数量

全部:

javascript 复制代码
db.users.countDocuments({})

统计成年人:

javascript 复制代码
db.users.countDocuments({
    age: {
        $gte: 18
    }
})

四十一、修改一条数据

javascript 复制代码
db.users.updateOne(
    {
        name: "JavaPub"
    },
    {
        $set: {
            age: 29
        }
    }
)

四十二、一次修改多个字段

javascript 复制代码
db.users.updateOne(
    {
        name: "JavaPub"
    },
    {
        $set: {
            age: 29,
            city: "Beijing",
            status: 1
        }
    }
)

四十三、修改多条数据

javascript 复制代码
db.users.updateMany(
    {
        age: {
            $lt: 18
        }
    },
    {
        $set: {
            status: "minor"
        }
    }
)

四十四、自增

年龄加 1:

javascript 复制代码
db.users.updateOne(
    {
        name: "JavaPub"
    },
    {
        $inc: {
            age: 1
        }
    }
)

减少:

javascript 复制代码
db.users.updateOne(
    {
        name: "JavaPub"
    },
    {
        $inc: {
            score: -10
        }
    }
)

四十五、删除字段

javascript 复制代码
db.users.updateOne(
    {
        name: "JavaPub"
    },
    {
        $unset: {
            temp: ""
        }
    }
)

四十六、数组追加元素

javascript 复制代码
db.users.updateOne(
    {
        name: "JavaPub"
    },
    {
        $push: {
            tags: "Docker"
        }
    }
)

四十七、避免数组重复

javascript 复制代码
db.users.updateOne(
    {
        name: "JavaPub"
    },
    {
        $addToSet: {
            tags: "Docker"
        }
    }
)

如果已经存在:

text 复制代码
Docker

就不会重复插入。


四十八、删除数组元素

javascript 复制代码
db.users.updateOne(
    {
        name: "JavaPub"
    },
    {
        $pull: {
            tags: "Docker"
        }
    }
)

四十九、Upsert

如果存在则更新,不存在则创建:

javascript 复制代码
db.users.updateOne(
    {
        email: "hello@example.com"
    },
    {
        $set: {
            name: "JavaPub",
            age: 28
        }
    },
    {
        upsert: true
    }
)

这是非常实用的写法。


五十、删除一条

javascript 复制代码
db.users.deleteOne({
    name: "JavaPub"
})

五十一、删除多条

javascript 复制代码
db.users.deleteMany({
    status: 0
})

五十二、清空 Collection

javascript 复制代码
db.users.deleteMany({})

这会:

text 复制代码
保留 Collection
删除全部 Document

如果:

javascript 复制代码
db.users.drop()

则是:

text 复制代码
Collection 本身也一起删除

五十三、创建普通索引

javascript 复制代码
db.users.createIndex({
    email: 1
})

五十四、创建唯一索引

javascript 复制代码
db.users.createIndex(
    {
        email: 1
    },
    {
        unique: true
    }
)

五十五、创建联合索引

javascript 复制代码
db.users.createIndex({
    status: 1,
    created_at: -1
})

五十六、查看索引

javascript 复制代码
db.users.getIndexes()

五十七、删除索引

先查看:

javascript 复制代码
db.users.getIndexes()

例如:

text 复制代码
email_1

删除:

javascript 复制代码
db.users.dropIndex("email_1")

删除所有非 _id 索引:

javascript 复制代码
db.users.dropIndexes()

五十八、查看查询执行计划

javascript 复制代码
db.users.find({
    email: "hello@example.com"
}).explain()

更加详细:

javascript 复制代码
db.users.find({
    email: "hello@example.com"
}).explain("executionStats")

重点关注:

text 复制代码
winningPlan
executionStats
totalDocsExamined
totalKeysExamined
nReturned
executionTimeMillis

如果:

text 复制代码
totalDocsExamined

特别大,但:

text 复制代码
nReturned

很小,通常说明查询可能缺少合适索引。


五十九、判断是否使用了索引

执行计划里看到:

text 复制代码
IXSCAN

通常表示使用了索引。

如果看到:

text 复制代码
COLLSCAN

表示:

text 复制代码
全表扫描

数据量大时要重点关注。


六十、聚合:最简单的 Group By

假设:

json 复制代码
{
    "status": "paid",
    "amount": 100
}

统计各状态数量:

javascript 复制代码
db.orders.aggregate([
    {
        $group: {
            _id: "$status",
            count: {
                $sum: 1
            }
        }
    }
])

六十一、求和

javascript 复制代码
db.orders.aggregate([
    {
        $group: {
            _id: "$status",
            totalAmount: {
                $sum: "$amount"
            }
        }
    }
])

六十二、平均值

javascript 复制代码
db.orders.aggregate([
    {
        $group: {
            _id: "$status",
            avgAmount: {
                $avg: "$amount"
            }
        }
    }
])

六十三、聚合过滤

javascript 复制代码
db.orders.aggregate([
    {
        $match: {
            status: "paid"
        }
    },
    {
        $group: {
            _id: null,
            total: {
                $sum: "$amount"
            }
        }
    }
])

六十四、查看当前用户

javascript 复制代码
db.runCommand({
    connectionStatus: 1
})

也可以查看认证信息:

javascript 复制代码
db.runCommand({
    connectionStatus: 1,
    showPrivileges: true
})

六十五、查看数据库用户

切换:

javascript 复制代码
use admin

执行:

javascript 复制代码
db.getUsers()

六十六、创建管理员

javascript 复制代码
use admin

执行:

javascript 复制代码
db.createUser({
    user: "mongoAdmin",
    pwd: "YOUR_STRONG_PASSWORD",
    roles: [
        {
            role: "root",
            db: "admin"
        }
    ]
})

六十七、创建业务用户

例如:

javascript 复制代码
use javapub

执行:

javascript 复制代码
db.createUser({
    user: "javapub_app",
    pwd: "YOUR_PASSWORD",
    roles: [
        {
            role: "readWrite",
            db: "javapub"
        }
    ]
})

六十八、创建只读用户

javascript 复制代码
db.createUser({
    user: "javapub_readonly",
    pwd: "YOUR_PASSWORD",
    roles: [
        {
            role: "read",
            db: "javapub"
        }
    ]
})

六十九、修改用户密码

切换到用户所在数据库。

例如:

javascript 复制代码
use javapub

然后:

javascript 复制代码
db.changeUserPassword(
    "javapub_app",
    "NEW_PASSWORD"
)

七十、修改用户权限

javascript 复制代码
db.updateUser(
    "javapub_app",
    {
        roles: [
            {
                role: "readWrite",
                db: "javapub"
            }
        ]
    }
)

七十一、删除用户

javascript 复制代码
db.dropUser("javapub_app")

七十二、查看 MongoDB 服务版本

Linux:

bash 复制代码
mongod --version

mongosh:

bash 复制代码
mongosh --version

Shell 中:

javascript 复制代码
db.version()

七十三、查看 Server 状态

javascript 复制代码
db.serverStatus()

内容非常多。


七十四、查看连接数

javascript 复制代码
db.serverStatus().connections

例如:

javascript 复制代码
{
    current: 20,
    available: 838840,
    totalCreated: 500
}

重点:

text 复制代码
current

表示当前连接数量。


七十五、查看内存情况

javascript 复制代码
db.serverStatus().mem

七十六、查看网络统计

javascript 复制代码
db.serverStatus().network

七十七、查看数据库大小

javascript 复制代码
db.stats()

按照 MB 显示:

javascript 复制代码
db.stats({
    scale: 1024 * 1024
})

某些版本中也可以使用:

javascript 复制代码
db.stats(1024 * 1024)

七十八、查看 Collection 大小

javascript 复制代码
db.users.stats()

七十九、查看当前正在执行的操作

javascript 复制代码
db.currentOp()

只看活跃操作:

javascript 复制代码
db.currentOp({
    active: true
})

八十、终止某个操作

先:

javascript 复制代码
db.currentOp()

找到:

text 复制代码
opid

例如:

text 复制代码
12345

然后:

javascript 复制代码
db.killOp(12345)

生产环境慎用。


八十一、查看 Replica Set 状态

javascript 复制代码
rs.status()

八十二、查看 Replica Set 配置

javascript 复制代码
rs.conf()

八十三、判断当前节点是不是 Primary

javascript 复制代码
db.hello()

关注:

text 复制代码
isWritablePrimary

例如:

javascript 复制代码
{
    isWritablePrimary: true
}

说明当前是 Primary。


八十四、初始化 Replica Set

javascript 复制代码
rs.initiate()

或者:

javascript 复制代码
rs.initiate({
    _id: "rs0",
    members: [
        {
            _id: 0,
            host: "10.0.0.11:27017"
        }
    ]
})

八十五、添加 Replica Set 节点

javascript 复制代码
rs.add(
    "10.0.0.12:27017"
)

再添加:

javascript 复制代码
rs.add(
    "10.0.0.13:27017"
)

八十六、移除节点

javascript 复制代码
rs.remove(
    "10.0.0.13:27017"
)

八十七、查看同步信息

javascript 复制代码
rs.printReplicationInfo()

查看 Secondary:

javascript 复制代码
rs.printSecondaryReplicationInfo()

八十八、主动让 Primary 降级

javascript 复制代码
rs.stepDown()

也可以:

javascript 复制代码
rs.stepDown(60)

表示:

text 复制代码
60 秒内不参与 Primary 竞争

生产环境谨慎执行。


八十九、备份整个 MongoDB

bash 复制代码
mongodump \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/admin"

默认创建:

text 复制代码
dump/

目录。


九十、指定备份目录

bash 复制代码
mongodump \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/admin" \
  --out=/backup/mongodb

九十一、只备份一个数据库

bash 复制代码
mongodump \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/javapub?authSource=admin" \
  --db=javapub \
  --out=/backup/mongodb

九十二、压缩备份

bash 复制代码
mongodump \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/admin" \
  --archive=/backup/mongodb.archive \
  --gzip

九十三、恢复

bash 复制代码
mongorestore \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/admin" \
  /backup/mongodb

九十四、恢复 Archive

bash 复制代码
mongorestore \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/admin" \
  --archive=/backup/mongodb.archive \
  --gzip

九十五、恢复前删除原 Collection

bash 复制代码
mongorestore \
  --drop \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/admin" \
  /backup/mongodb

注意:

text 复制代码
--drop

非常危险。


九十六、导出 JSON

bash 复制代码
mongoexport \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/javapub" \
  --collection=users \
  --out=users.json

九十七、导出 CSV

bash 复制代码
mongoexport \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/javapub" \
  --collection=users \
  --type=csv \
  --fields=name,age,email \
  --out=users.csv

九十八、导入 JSON

bash 复制代码
mongoimport \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/javapub" \
  --collection=users \
  --file=users.json

九十九、导入 JSON Array

如果文件:

json 复制代码
[
    {
        "name": "Alice"
    },
    {
        "name": "Bob"
    }
]

需要:

bash 复制代码
mongoimport \
  --uri="mongodb://USER:PASSWORD@127.0.0.1:27017/javapub" \
  --collection=users \
  --file=users.json \
  --jsonArray

一百、查看 MongoDB 服务状态

Linux:

bash 复制代码
sudo systemctl status mongod

启动:

bash 复制代码
sudo systemctl start mongod

停止:

bash 复制代码
sudo systemctl stop mongod

重启:

bash 复制代码
sudo systemctl restart mongod

开机启动:

bash 复制代码
sudo systemctl enable mongod

取消:

bash 复制代码
sudo systemctl disable mongod

一百零一、查看 MongoDB 日志

Ubuntu / Debian:

bash 复制代码
sudo tail -f \
/var/log/mongodb/mongod.log

最后 200 行:

bash 复制代码
sudo tail -n 200 \
/var/log/mongodb/mongod.log

systemd:

bash 复制代码
sudo journalctl -u mongod

实时:

bash 复制代码
sudo journalctl \
-u mongod \
-f

一百零二、检查 27017 是否监听

bash 复制代码
sudo ss -lntp \
| grep 27017

或者:

bash 复制代码
sudo lsof -i :27017

一百零三、常见问题:MongoDB 启动失败

先执行:

bash 复制代码
sudo systemctl status mongod

然后:

bash 复制代码
sudo journalctl \
-u mongod \
-n 200

最后:

bash 复制代码
sudo tail \
-n 200 \
/var/log/mongodb/mongod.log

MongoDB 启动失败不要第一时间重装。

日志基本都会告诉你原因。


一百零四、常见问题:Unit mongod.service not found

执行:

bash 复制代码
systemctl status mongod

出现:

text 复制代码
Unit mongod.service could not be found

常见原因:

text 复制代码
MongoDB Server 没安装
安装的不是官方 mongodb-org
软件包安装失败

检查:

bash 复制代码
which mongod

再:

bash 复制代码
mongod --version

Ubuntu:

bash 复制代码
dpkg -l | grep mongo

CentOS:

bash 复制代码
rpm -qa | grep mongo

一百零五、常见问题:Connection refused

报错:

text 复制代码
MongoServerSelectionError
ECONNREFUSED
Connection refused

先:

bash 复制代码
sudo systemctl status mongod

再:

bash 复制代码
sudo ss -lntp \
| grep 27017

如果 MongoDB 没启动:

bash 复制代码
sudo systemctl start mongod

如果服务器地址写错,也会出现这个问题。


一百零六、常见问题:本机能连接,远程连不上

检查:

bash 复制代码
sudo ss -lntp \
| grep 27017

如果看到:

text 复制代码
127.0.0.1:27017

说明 MongoDB 只监听本机。

配置:

bash 复制代码
sudo vim /etc/mongod.conf

找到:

yaml 复制代码
net:
  port: 27017
  bindIp: 127.0.0.1

例如修改:

yaml 复制代码
net:
  port: 27017
  bindIp: 127.0.0.1,10.0.0.10

然后:

bash 复制代码
sudo systemctl restart mongod

一百零七、不要随便 bindIp 0.0.0.0

虽然:

yaml 复制代码
bindIp: 0.0.0.0

很方便。

但是意味着:

text 复制代码
所有网卡都监听 27017

如果服务器还有公网 IP,并且安全组开放了:

text 复制代码
27017

那么 MongoDB 很可能直接暴露公网。

推荐:

yaml 复制代码
bindIp: 127.0.0.1,10.0.0.10

只监听:

text 复制代码
本机
内网

一百零八、常见问题:Authentication failed

常见报错:

text 复制代码
Authentication failed

不要第一反应认为密码一定错了。

MongoDB 认证失败最常见的原因之一是:

text 复制代码
authSource 写错

假设用户创建在:

javascript 复制代码
use admin

那么:

text 复制代码
authSource=admin

例如:

text 复制代码
mongodb://user:password@127.0.0.1:27017/javapub?authSource=admin

一百零九、如何确认用户创建在哪个数据库?

分别查看:

javascript 复制代码
use admin
javascript 复制代码
db.getUsers()

然后:

javascript 复制代码
use javapub
javascript 复制代码
db.getUsers()

MongoDB 用户是:

text 复制代码
属于某个数据库的

不是完全独立的全局用户。


一百一十、常见问题:密码没错还是认证失败

检查:

text 复制代码
用户名
密码
authSource
认证机制
URI 特殊字符
用户是否已经创建
用户权限

可以先使用:

bash 复制代码
mongosh \
-u username \
-p \
--authenticationDatabase admin

如果命令行可以登录,但程序不行,就重点检查:

text 复制代码
应用连接字符串
URL Encode

一百一十一、常见问题:not authorized

例如:

text 复制代码
not authorized on javapub to execute command

意味着:

text 复制代码
已经登录成功
但是权限不足

查看用户:

javascript 复制代码
db.getUser("javapub_app")

检查:

text 复制代码
roles

例如应用需要:

javascript 复制代码
{
    role: "readWrite",
    db: "javapub"
}

一百一十二、常见问题:E11000 duplicate key error

经典错误:

text 复制代码
E11000 duplicate key error

通常意味着:

text 复制代码
违反唯一索引

例如:

javascript 复制代码
db.users.createIndex(
    {
        email: 1
    },
    {
        unique: true
    }
)

又插入:

javascript 复制代码
{
    email: "hello@example.com"
}

已有相同值。

查看索引:

javascript 复制代码
db.users.getIndexes()

一百一十三、创建唯一索引时报 E11000

如果原数据已经存在重复:

javascript 复制代码
db.users.createIndex(
    {
        email: 1
    },
    {
        unique: true
    }
)

会失败。

可以先找重复:

javascript 复制代码
db.users.aggregate([
    {
        $group: {
            _id: "$email",
            count: {
                $sum: 1
            },
            ids: {
                $push: "$_id"
            }
        }
    },
    {
        $match: {
            count: {
                $gt: 1
            }
        }
    }
])

先清洗数据,再建唯一索引。


一百一十四、常见问题:查询很慢

第一步:

javascript 复制代码
db.users.find({
    email: "hello@example.com"
}).explain("executionStats")

重点看:

text 复制代码
COLLSCAN

如果数据量大,并且频繁按照:

text 复制代码
email

查询,就应该考虑:

javascript 复制代码
db.users.createIndex({
    email: 1
})

一百一十五、不是所有字段都应该建索引

索引不是越多越好。

因为索引会增加:

text 复制代码
磁盘占用
写入成本
更新成本
内存消耗

一般重点考虑:

text 复制代码
高频查询字段
排序字段
联合查询字段
唯一字段

而不是每个字段都加索引。


一百一十六、联合索引顺序很重要

例如:

javascript 复制代码
db.orders.createIndex({
    user_id: 1,
    created_at: -1
})

更适合:

javascript 复制代码
db.orders.find({
    user_id: 10001
}).sort({
    created_at: -1
})

索引设计需要围绕:

text 复制代码
实际查询模式

而不是单纯看字段。


一百一十七、常见问题:磁盘突然满了

检查:

bash 复制代码
df -h

MongoDB 数据:

bash 复制代码
du -sh /var/lib/mongodb

或者:

bash 复制代码
du -sh /data/mongodb

日志:

bash 复制代码
du -sh /var/log/mongodb

继续:

bash 复制代码
du -ah /var/log/mongodb \
| sort -h \
| tail

一百一十八、不要直接删除 MongoDB 数据文件

不要看到:

text 复制代码
/var/lib/mongodb

很大,就直接:

bash 复制代码
rm -rf /var/lib/mongodb/*

这相当于:

直接物理删除数据库。

正常删除应该通过:

javascript 复制代码
db.dropDatabase()

或者:

javascript 复制代码
db.collection.drop()

并提前备份。


一百一十九、常见问题:日志文件太大

查看:

bash 复制代码
ls -lh /var/log/mongodb

通常应该配合:

text 复制代码
logrotate

查看:

bash 复制代码
ls /etc/logrotate.d/

可以根据实际部署方式配置日志轮转。

不要让:

text 复制代码
mongod.log

无限增长。


一百二十、常见问题:MongoDB 内存占用高

MongoDB 高内存使用并不一定代表:

text 复制代码
内存泄漏

数据库通常会主动利用内存做:

text 复制代码
缓存
WiredTiger Cache
索引

先看:

javascript 复制代码
db.serverStatus().wiredTiger.cache

再结合:

bash 复制代码
free -h

判断。

不要只看到 MongoDB 占用几个 GB 就立刻认为异常。


一百二十一、查看 WiredTiger Cache

javascript 复制代码
db.serverStatus().wiredTiger.cache

重点可以观察:

text 复制代码
maximum bytes configured
bytes currently in the cache
pages read into cache
pages written from cache

一百二十二、常见问题:Too many connections

先:

javascript 复制代码
db.serverStatus().connections

如果:

text 复制代码
current

非常高,要检查应用程序是否正确使用连接池。

例如错误模式:

text 复制代码
每个 HTTP 请求
创建一次 MongoClient
然后不关闭

这是非常危险的。

正确方式通常是:

text 复制代码
整个应用共享 MongoClient
使用驱动连接池

一百二十三、Go 项目不要每次请求都 Connect

错误思路:

go 复制代码
func Handler() {

    client, err := mongo.Connect(...)

    // 每个请求都创建 client
}

更合理:

text 复制代码
程序启动
   ↓
创建 Mongo Client
   ↓
建立连接池
   ↓
Handler / Service 共享
   ↓
程序退出再 Disconnect

一百二十四、常见问题:Server selection timeout

Go / Node 等驱动常见:

text 复制代码
server selection timeout

常见原因:

text 复制代码
MongoDB 服务没启动
IP 写错
27017 不通
bindIp 错误
防火墙拦截
安全组没开
Replica Set 配置错误
DNS 无法解析

首先:

bash 复制代码
nc -vz 10.0.0.10 27017

一百二十五、使用 nc 测试 MongoDB 端口

bash 复制代码
nc -vz 127.0.0.1 27017

远程:

bash 复制代码
nc -vz 10.0.0.10 27017

成功:

text 复制代码
Connection succeeded

失败:

text 复制代码
Connection refused

说明服务或监听有问题。

如果:

text 复制代码
timed out

则通常重点排查:

text 复制代码
防火墙
安全组
网络路由

一百二十六、检查防火墙

Ubuntu:

bash 复制代码
sudo ufw status

CentOS:

bash 复制代码
sudo firewall-cmd --list-all

云服务器还要检查:

text 复制代码
AWS Security Group
阿里云安全组
腾讯云安全组
Cloud Firewall
VPC ACL

一百二十七、常见问题:MongoDB 配置改了不生效

修改:

text 复制代码
/etc/mongod.conf

以后一定要:

bash 复制代码
sudo systemctl restart mongod

再看:

bash 复制代码
sudo systemctl status mongod

以及:

bash 复制代码
sudo ss -lntp \
| grep 27017

不能只修改配置却不重启。


一百二十八、常见问题:修改配置后 MongoDB 起不来

通常是:

text 复制代码
YAML 缩进错误
字段拼错
目录不存在
目录权限错误
bindIp 配错

看日志:

bash 复制代码
sudo journalctl \
-u mongod \
-n 100

YAML 最容易出现的问题就是:

yaml 复制代码
security:
authorization: enabled

错误。

正确:

yaml 复制代码
security:
  authorization: enabled

一百二十九、常见问题:Permission denied

如果自定义:

text 复制代码
/data/mongodb

需要:

bash 复制代码
sudo chown \
-R mongodb:mongodb \
/data/mongodb

日志:

bash 复制代码
sudo chown \
-R mongodb:mongodb \
/data/logs/mongodb

查看:

bash 复制代码
ls -ld /data/mongodb

一百三十、常见问题:Address already in use

报错:

text 复制代码
Address already in use

检查:

bash 复制代码
sudo lsof -i :27017

或:

bash 复制代码
sudo ss -lntp \
| grep 27017

可能是:

text 复制代码
旧 MongoDB
Docker MongoDB
另一个 mongod
其他程序

一百三十一、检查 Docker 是否占用端口

bash 复制代码
docker ps \
--format \
'table {{.Names}}\t{{.Ports}}'

如果看到:

text 复制代码
0.0.0.0:27017->27017/tcp

说明 Docker 已经占用 27017。


一百三十二、Docker 查看 MongoDB 日志

bash 复制代码
docker logs mongodb

实时:

bash 复制代码
docker logs \
-f mongodb

最后 100 行:

bash 复制代码
docker logs \
--tail 100 \
mongodb

一百三十三、Docker 进入 MongoDB

bash 复制代码
docker exec \
-it mongodb \
mongosh

认证:

bash 复制代码
docker exec \
-it mongodb \
mongosh \
-u mongoAdmin \
-p \
--authenticationDatabase admin

一百三十四、Docker 重启 MongoDB

bash 复制代码
docker restart mongodb

查看:

bash 复制代码
docker ps

一百三十五、Docker Compose 常用命令

启动:

bash 复制代码
docker compose up -d

停止:

bash 复制代码
docker compose stop

启动:

bash 复制代码
docker compose start

重启:

bash 复制代码
docker compose restart

删除:

bash 复制代码
docker compose down

日志:

bash 复制代码
docker compose logs -f mongodb

查看:

bash 复制代码
docker compose ps

一百三十六、不要随便 docker compose down -v

普通:

bash 复制代码
docker compose down

和:

bash 复制代码
docker compose down -v

差别非常大。

-v 会删除相关 Volume。

如果数据库使用 Docker Volume 存储,很可能相当于:

把 MongoDB 数据一起删了。

生产环境慎用。


一百三十七、常见问题:Replica Set 不是 Primary

可能看到:

text 复制代码
not primary

或者:

text 复制代码
not writable primary

执行:

javascript 复制代码
rs.status()

再:

javascript 复制代码
db.hello()

确认当前节点角色。

应用程序最好连接:

text 复制代码
Replica Set

而不是死连某一个节点并假设它永远是 Primary。


一百三十八、Replica Set 一直 STARTUP2

执行:

javascript 复制代码
rs.status()

如果 Secondary 长时间:

text 复制代码
STARTUP2

可以检查:

text 复制代码
节点之间网络
27017 是否互通
hostname 是否可解析
数据量是否很大
同步是否正在进行
日志错误
认证 KeyFile
磁盘空间

一百三十九、Replica Set 节点互相测试

例如:

bash 复制代码
nc -vz \
mongo2 \
27017

或者:

bash 复制代码
nc -vz \
10.0.0.12 \
27017

Replica Set 不只是:

text 复制代码
客户端 → MongoDB

能通。

还要求:

text 复制代码
MongoDB 节点之间

能够通信。


一百四十、MongoDB 服务快速健康检查

我经常使用:

bash 复制代码
mongosh \
--quiet \
--eval \
'db.adminCommand({ping:1})'

正常:

javascript 复制代码
{
  ok: 1
}

Docker Healthcheck 也可以使用这个思路。


一百四十一、Linux 一条命令检查 MongoDB

bash 复制代码
systemctl is-active mongod

输出:

text 复制代码
active

查看是否开机启动:

bash 复制代码
systemctl is-enabled mongod

一百四十二、快速检查脚本

可以创建:

bash 复制代码
vim check-mongodb.sh

写入:

bash 复制代码
#!/bin/bash

echo "=== MongoDB Service ==="

systemctl status mongod \
--no-pager


echo

echo "=== MongoDB Port ==="

ss -lntp \
| grep 27017


echo

echo "=== MongoDB Version ==="

mongod --version \
| head


echo

echo "=== MongoDB Ping ==="

mongosh \
--quiet \
--eval \
'db.adminCommand({ping:1})'


echo

echo "=== Disk ==="

df -h


echo

echo "=== MongoDB Data Size ==="

du -sh \
/var/lib/mongodb \
2>/dev/null

授权:

bash 复制代码
chmod +x check-mongodb.sh

执行:

bash 复制代码
./check-mongodb.sh

一百四十三、MongoDB 排错推荐顺序

遇到:

text 复制代码
MongoDB 用不了

不要一上来改一堆配置。

推荐按照这个顺序:

text 复制代码
1. 服务有没有启动
2. 端口有没有监听
3. 本机能不能连接
4. 用户认证是否正常
5. bindIp 是否正确
6. 远程端口是否能通
7. 防火墙是否放行
8. 云安全组是否放行
9. authSource 是否正确
10. 用户权限是否足够
11. Replica Set 是否正常
12. 看 MongoDB 日志

对应命令:

bash 复制代码
systemctl status mongod
bash 复制代码
ss -lntp | grep 27017
bash 复制代码
mongosh
bash 复制代码
nc -vz IP 27017
bash 复制代码
tail -n 200 /var/log/mongodb/mongod.log

这套流程能解决绝大多数 MongoDB 连接问题。


一百四十四、MongoDB 常用命令速查表

数据库:

javascript 复制代码
show dbs
javascript 复制代码
use javapub
javascript 复制代码
db
javascript 复制代码
db.dropDatabase()

Collection:

javascript 复制代码
show collections
javascript 复制代码
db.createCollection("users")
javascript 复制代码
db.users.drop()

插入:

javascript 复制代码
db.users.insertOne({})
javascript 复制代码
db.users.insertMany([])

查询:

javascript 复制代码
db.users.find()
javascript 复制代码
db.users.findOne()

修改:

javascript 复制代码
db.users.updateOne()
javascript 复制代码
db.users.updateMany()

删除:

javascript 复制代码
db.users.deleteOne()
javascript 复制代码
db.users.deleteMany()

索引:

javascript 复制代码
db.users.createIndex()
javascript 复制代码
db.users.getIndexes()
javascript 复制代码
db.users.dropIndex()

统计:

javascript 复制代码
db.users.countDocuments({})

状态:

javascript 复制代码
db.serverStatus()
javascript 复制代码
db.currentOp()

Replica Set:

javascript 复制代码
rs.status()
javascript 复制代码
rs.conf()
javascript 复制代码
db.hello()

一百四十五、Linux MongoDB 常用命令速查

服务:

bash 复制代码
systemctl status mongod
bash 复制代码
systemctl start mongod
bash 复制代码
systemctl stop mongod
bash 复制代码
systemctl restart mongod

日志:

bash 复制代码
journalctl -u mongod -f
bash 复制代码
tail -f /var/log/mongodb/mongod.log

端口:

bash 复制代码
ss -lntp | grep 27017

版本:

bash 复制代码
mongod --version
bash 复制代码
mongosh --version

连接:

bash 复制代码
mongosh

测试:

bash 复制代码
nc -vz 127.0.0.1 27017

磁盘:

bash 复制代码
df -h
bash 复制代码
du -sh /var/lib/mongodb

一百四十六、最后总结

MongoDB 真正经常使用的命令其实并没有想象中那么多。

开发阶段重点掌握:

text 复制代码
use
show dbs
show collections
find
insertOne
updateOne
deleteOne
aggregate
createIndex
explain

运维阶段重点掌握:

text 复制代码
mongosh
systemctl
journalctl
ss
mongodump
mongorestore
serverStatus
currentOp
rs.status

排查 MongoDB 问题时,则始终记住:

text 复制代码
服务
  ↓
端口
  ↓
网络
  ↓
认证
  ↓
权限
  ↓
索引
  ↓
磁盘
  ↓
Replica Set
  ↓
日志

MongoDB 很多所谓的"数据库故障",最后其实都是:

text 复制代码
服务没启动
bindIp 错了
防火墙拦了
authSource 错了
权限不够
索引没建
磁盘满了

因此相比死记所有命令,更重要的是形成一套自己的排错顺序。

最后把最值得记住的几条命令留下:

bash 复制代码
systemctl status mongod
bash 复制代码
ss -lntp | grep 27017
bash 复制代码
mongosh
javascript 复制代码
show dbs
javascript 复制代码
show collections
javascript 复制代码
db.serverStatus()
javascript 复制代码
db.currentOp()
javascript 复制代码
db.users.getIndexes()
javascript 复制代码
db.users.find({}).explain("executionStats")
javascript 复制代码
rs.status()
bash 复制代码
mongodump
bash 复制代码
mongorestore

基本已经覆盖了日常开发和绝大部分 MongoDB 排错场景。


现在是最好的时代。中国有全世界最高性价比的制造业,有发达的网络和全球物流。

只要你愿意,你几乎可以买到这个世界上任何地方生产的、任何你想要的商品。你可以用很低的成本,撬动全球的资源为你服务。

不过,真正稀缺的,从来不是商品,而是注意力、判断力,以及把事情做成的能力。

所以,这是最好的时代,也是最坏的时代。

我是王仕宇,关注 AI、Web3 与开源,持续探索如何把技术做成产品,把产品转化为真实价值。

相关推荐
Dovis(誓平步青云)3 小时前
从Redis指标采集到异常告警:redis_exporter + Prometheus 完整实战
服务器·数据库·人工智能·redis·架构·prometheus·vibe coding
城管不管10 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
倔强的石头10610 小时前
向量数据库从相似度检索走向融合数据底座
数据库
今天AI了吗11 小时前
Python 基础语法(一):常量、变量、输入输出与运算符
开发语言·数据库·人工智能·python·sql·深度学习·机器学习
lilian23313 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos
皮卡丘不断更13 小时前
手机优先的 Personal Ledger:把账目、学习和复盘放到同一个入口
数据库·sqlite·fastapi·开源项目·个人效率
保卫大狮兄14 小时前
设备管理从台账到报废,完整生命周期一次讲清
数据库·设备管理·设备
数据安全技术观察14 小时前
数据动态脱敏:让脱敏策略跟着数据目录走
大数据·网络·数据库
小席是个热心肠15 小时前
Redis的自我学习
数据库·redis·学习