MongoDB集群部署与基本操作以及错误处理
文档整理:孟祥新(2021-9-25)
一. MongoDB概述
MongoDB是NoSQL中面向文档的数据库,是介于关系型和非关系型数据库之间的产品。它支持的数据结构非常松散,类似于JSON的BSON格式,因此可以存储比较复杂的数据类型。它的查询语言功能强大,几乎可以实现类似于关系数据库查询的绝大部分功能,而且还支持对数据建立索引。
二. MongoDB逻辑结构
MongoDB逻辑结构示意:

三. MongoDB基本概念
MongoDB | 相当于MySQL中的概念 | 说明 |
database | database | 数据库 |
collection | table | 表/集合 |
document | row | 记录行/文档 |
field | column | 字段/域 |
index | index | 索引 |
primary key | primary key | 主键 MongoDB自动将_id字段设置为主键 |
四. 常规物理机环境MongoDB的安装与服务启停
1. MongoDB的安装
以下在CentOS7环境下安装MongoDB 4.4.6单实例服务为例:
(1) 下载MongoDB安装包:MongoDB官方网址https://www.mongodb.com/download-center
(2) 解压安装包:tar -zxvf mongodb-linux-x86_64-rhel70-4.4.6.tgz
(3) 解压目录一般修改为:/usr/local/mongodb/
(4) 设置环境变量:export PATH=/usr/local/mongodb/bin:$PATH
(5) 创建MongoDB运行目录:
mkdir -p /usr/local/mongodb/db1/conf
mkdir -p /usr/local/mongodb/db1/logs
mkdir -p /usr/local/mongodb/db1/data
(6) 创建MongoDB服务配置文件:
vi /usr/local/mongodb/db1/conf/mongod.conf
配置文件内容如下:
systemLog:
destination: file
path: "/usr/local/mongodb/db1/logs/mongod.log"
logAppend: true
storage:
dbPath: "/usr/local/mongodb/db1/data"
journal:
enabled: true
processManagement:
fork: true
net:
bindIp: 0.0.0.0
port: 27017
maxIncomingConnections: 100
常见的配置参数说明如下:
配置参数名 | 参数说明 |
destination | 指定日志输出类型,可以指定为 “file” 或者“syslog”,如果不指定,则会输出到标准输出中。 |
logAppend | 如果为rue,当服务重启后,将在现有日志的尾部继续添加日志。否则,将会备份当前日志文件,然后创建一个新的日志文件。 |
dbPath | 用于指定数据存储数据目录的位置 |
journal | 是否开启journal日志持久存储,journal日志用于数据恢复。 |
fork | true指定服务进程运行在后台 |
bindIp | 允许被服务监听到的IP地址。如果要绑定到多个地址,之间用逗号分隔。 bindIp: 0.0.0.0表示监听所有IP,在3.6及以后版本中,也可以用bindIpAll: true来指定。 |
maxIncomingConnections | 允许的最大连接数,默认值65536。 |
authorization | disabled 或者 enabled,表示是否开启用户访问控制(Access Control),即客户端可以通过用户名和密码认证的方式访问系统的数据,默认为 “disabled”,即客户端不需要密码即可访问数据库数据。 |
keyFile | 当 clusterAuthMode为“keyFile”时,此参数用于指定 keyfile 的位置,并且mongodb 需要有访问此文件的权限。 |
setParameter | 允许指定一些的 Server 端参数,这些参数不依赖于存储引擎和交互机制,只是微调系统的运行状态,比如 “认证机制”、“线程池参数” 等。 |
关于配置文件和参数的更详细说明,详见:
https://docs.mongodb.com/manual/reference/configuration-options
https://docs.mongodb.com/manual/reference/parameters/
2. 启动MongoDB服务
在OS环境,执行如下命令:
mongod -f 配置文件全名
例如:mongod -f /usr/local/mongodb/db1/conf/mongod.conf
启动成功,回显信息:child process started successfully, parent exiting
确认MongoDB服务已经启动,可以通过ps命令查看mongod进程。
3. 进入MongoDB shell环境
进入在OS环境,执行如下命令:
mongo
4. 登录指定的MongoDB
命令例如:
mongo --host 127.0.0.1 --port 27017 -u "admin" -p "123456" --authenticationDatabase "admin"
以上命令的参数说明如下:
--host 指定登录的主机,
--port 指定登录端口
-u 指定登录用户
-p 指定用户登录密码
--authenticationDatabase 指定认证的数据库
5. 关闭MongoDB服务
有三种方法:
(1) 方法一:
进入mongo shell环境,执行如下:
use admin
db.shutdownServer()
(2) 方法二:
在OS环境,执行:mongod --shutdown --dbpath 数据目录
例如:mongod --shutdown --dbpath /usr/local/mongodb/db1/data
(3) 方法三:
在OS环境,通过ps找到mongod服务的PID,然后执行:kill PID
五. 常规物理机环境创建MongoDB管理员账户
1. 说明:
MongoDB默认情况下,没有管理员账户,为了便于管理,一般在安装完成后,需要创建类似于MySQL中root的管理员账户
2. 创建管理员账户
(1) 进入mongo shell,执行:
use admin
db.createUser({ user: "root", pwd: "password", roles: [ { role: "root", db: "admin"} ]})
(2) 关闭mongod服务:db.shutdownServer()
(3) 修改mongod服务配置文件,开启认证模式,加入如下内容:
security:
authorization: enabled
(4) 启动mongod服务
(5) 登录验证:
mongo -u root -p password --authenticationDatabase admin
show dbs
六. MongoDB基本操作
以下基本操作,如无特殊说明,均在MongoDB的shell环境中执行:
1. 显示所有数据库列表
show dbs
或者:
show databases
2. 创建数据库
无需创建数据库,直接进入(use)即可。
3. 进入指定数据库
use dbname
4. 查看当前数据库名
db.getName()
或者:
db
5. 删除当前数据
db.dropDatabase()
6. 显示数据库版本
db.version()
7. 查看当前数据库中的角色
show roles
8. 查看当前数据库中的用户
show users
9. 创建用户
db.createUser(
{
user: "用户名",
pwd: "用户密码",
roles: [ { role: "readWrite" , db: "数据库名" } ]
}
)
10. 删除用户
(1) 删除指定的用户:db.dropUser("用户名")
(2) 删除当前库中的所有用户:db.dropUser
11. 查看指定用户的信息
db.getUser("用户名")
12. 查看当前库中所有用户的信息
db.getUsers()
13. 修改用户密码
db.changeUserPassword("用户名","密码")
14. 查看当前数据库的统计信息
db.stats()
15. 查看mongod服务所在主机名
db.serverStatus().host
16. 显示当前的存储引擎
db.serverStatus().storageEngine
17. 查看mongod服务内存使用情况
db.serverStatus().mem
此命令的作用,相当于OS的top命令。
命令结果类似如下:
{ "bits" : 64, "resident" : 81, "virtual" : 1521, "supported" : true }
命令结果解释如下:
bits:表示MongoDB实例是64位还是32位体系
resident:数据库进程当前使用的RAM(MB)。
virtual:显示mongod进程使用的虚拟内存的数量(MB)。
supported:表示系统是否支持扩展内存。
18. 查看服务器连接状态的信息,使用这些值来评估服务器的当前负载
db.serverStatus().connections
19. 查看MongoDB网络的使用情况
db.serverStatus().network
返回结果解释说明:
bytesIn:数据库接收的网络通信量的字节数。
bytesOut:数据库发送的网络通信量的字节数。
numRequests:服务器已接收的不同请求的总数。
20. 查看服务全局锁的情况
db.serverStatus().globalLock
返回的结果类似如下:
{
"totalTime" : NumberLong("19246725000"),
"currentQueue" : {
"total" : 0,
"readers" : 0,
"writers" : 0
},
"activeClients" : {
"total" : 254,
"readers" : 3,
"writers" : 1
}
}
以上结果,解释如下:
totalTime:自数据库上次启动并创建globalLock以来的时间(以微秒为单位)。
currentQueue:提供有关由于锁而排队的信息
total:排队等待锁的操作总数
readers:当前排队等待读锁的操作数。
writers:当前排队等待写锁的操作数。
activeClients:有关连接的客户端的数量以及这些客户端执行的读写操作的信息。
total:到数据库的活动客户端连接的总数
readers:执行读取操作的活动客户端连接数
writers:执行写操作的活动客户端连接数
21. 显示每个锁的类型和数据模式
db.serverStatus().locks
返回结果解释说明:
Global:表示全局锁
Database:表示数据库锁
Collection:表示集合锁
Metadata:表示元数据锁
oplog:表示oplog上的锁
acquireCount:在指定模式下获取锁的次数。
acquireWaitCount:锁等待的次数
timeAcquiringMicros:锁获取的累计等待时间(微秒)
R:表示共享锁 Shared (S) lock.
W:表示独占锁Exclusive (X) lock.
r:表示Intent Shared (IS) lock.
w:表示Intent Exclusive (IX) lock.
22. 查看服务器操作计数
db.serverStatus().opcounters
返回结果类似如下:
{
"insert" : NumberLong(0),
"query" : NumberLong(4),
"update" : NumberLong(2),
"delete" : NumberLong(0),
"getmore" : NumberLong(0),
"command" : NumberLong(28)
}
23. 显示当前数据库中的集合列表
show collections
或者:
show tables
或者:
db.getCollectionNames()
24. 创建集合(相当于创建表)
由于MongoDB在命令中首次引用集合时,会隐式创建集合,因此无需创建表,直接插入数据即可。
当然也可以显示的执行创建集合命令:
db.createCollection(name)
25. 删除集合(相当于删除表)
db.tablename.drop()
26. 向集合中插入数据(相当于向表中插入数据)
db.tablename.insert( )
或:
db.tablename.save( )
两者区别:
insert: 若新增数据的主键已经存在,则会报以下异常:
“org.springframework.dao.DuplicateKeyException”
表示主键重复,不保存当前数据。
save: 若新增数据的主键已经存在,则会对当前已经存在的数据进行修改操作。
27. 删除集合中的数据(相当于删除表中的数据)
db.tablename.remove( )
28. 修改集合中的数据(相当于修改表中的数据)
db.tablename.update( )
29. 查看集合中数据(相当于查看表中的数据)
db.tablename.find()
30. 查看集合中的一条数据
db.tablename.findOne()
31. 查看集合中的前两条数据
db.tablename.find().limit(2)
32. 查询第2条以后的所有数据
db.Tablename.find().skip(2)
33. 查询第2条之后的3条数据
db.Tablename.find().limit(3).skip(2)
34. 查看集合中的数据量(相当于查询表中记录数)
db.tablename.count()
35. 去重查询
db.tablename.distinct( )
36. 创建索引(相当于为表创建索引)
db.tablename.ensureIndex(keys, options)
例如:db.table01.ensureIndex({'title':1, 'info':-1})
1表示升序,-1表示降序。
37. 重建索引
db.tablename.reIndex()
注意:此命令删除集合上的所有索引并重新创建它们。对于具有大量数据和/或大量索引的集合,此操作可能代价高昂。
38. 查看集合的索引(相当于查看指定表的索引)
db.tablename.getIndexes()
39. 删除索引创建
(1) 删除指定索引:db.tablename.dropIndex(索引名)
(2) 删除集合的所有索引:db.Tablename.dropIndexes()
40. 查看集合的数据量(以字节为单位)
db. Tablename.dataSize()
41. 查看分配给集合用于文档存储的空间(以字节为单位)
db. Tablename.storageSize()
42. 查看分配给集合以及集合所有索引的存储空间(以字节为单位)
db. Tablename.totalSize()
七. MongoDB副本集
1. 副本集的构成
(1) 副本集结构示意图

(2) 副本集构成说明
副本集(Replica Set)是一组MongoDB实例组成的集群,由一个主服务器节点(Primary)和多个副本服务器节点(Secondary)构成。副本服务器通过应用来自于主服务器的操作日志(oplog),来保持与主服务器数据库的同步。副本集中,只有Primary节点能够接受写操作。通过集群中冗余的数据库副本节点,能够实现数据的异地备份,读写分离和自动故障转移。
2. 集群的故障转移
集群的高可用性,主要体现在自动故障转移,其过程大致如下:当主服务器出现故障,集群中的其他节点检测不到来自于主服务器的心跳,这时将触发选举,选举出新的主节点。过程示意如下:

3. 副本集的同步过程
MongoDB副本集数据同步主要包含2个步骤:
第一步:intial sync,即初始的全量同步
第二步:replication,应用oplog,为增量同步
Primary节点写入数据,Secondary通过读取Primary的oplog得到复制信息,如果某个副本节点发生故障,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog。
4. oplog简介
oplog是local库下的一个固定集合,Secondary就是通过查看Primary 的oplog这个集合来进行复制的。每个节点都有oplog,记录这从主节点复制过来的信息,这样每个成员都可以作为同步源给其他节点。
5. 查看副本集的状态
(1) 检查集群状态
rs.status();
节点状态说明如下:
状态 | 说明 |
PRIMARY | 副本集主节点,可以读写数据 |
SECONDARY | 副本集从节点,可以读数据 |
ARBITER | 仲裁节点,不复制数据,仅投票 |
STARTUP | 没有任何活跃节点,所有节点在此状态下启动,解析副本集的配置 |
STARTUP2 | 节点已经加入集群,并运行初始同步 |
RECOVERING | 可以投票,成员执行启动自检,或完成回滚或重新同步 |
DOWN | 对于其他节点,此节点不可达 |
ROLLBACK | 此节点正在执行回滚,不能读取数据 |
REMOVED | 此节点已被删除 |
UNKNOWN | 对于其他节点,此节点未知 |
(2) 查看副本集的配置
rs.conf()
(3) 查看当前节点副本集的状态
db.adminCommand( { replSetGetStatus : 1 } )
(4) 查看是否为主节点
db.isMaster()
(5) 查看同步的情况
db.printSlaveReplicationInfo()
(6) 查看oplog的相关信息
db.getReplicationInfo()
结果类似如下:
{
"logSizeMB" : 3234.986083984375,
"usedMB" : 0.01,
"timeDiff" : 292817,
"timeDiffHours" : 81.34,
"tFirst" : "Thu Dec 17 2020 07:33:08 GMT+0800 (CST)",
"tLast" : "Sun Dec 20 2020 16:53:25 GMT+0800 (CST)",
"now" : "Mon Dec 21 2020 01:12:36 GMT+0800 (CST)"
}
logSizeMB:返回oplog的总大小(MB)。这是指分配给oplog的空间总量,而不是oplog中存储的操作的当前大小。
usedMB:返回oplog使用的总空间量(MB)。这是指oplog中存储的操作当前使用的空间总量,而不是分配的空间总量。
timeDiff:返回oplog中第一个和最后一个操作之间的差,以秒为单位。
timeDiffHours:返回oplog中第一个和最后一个操作之间的差值,四舍五入并以小时表示。
tFirst:返回oplog中第一个(即最早的)操作的时间戳。
tLast:返回oplog中最后一次(即最近一次)操作的时间戳。
now:返回反映当前时间的时间戳。
八. MongoDB的常用工具
工具作用 | MongoDB工具 | 相当于MySQL的工具 |
客户端工具 | mongo | mysql |
逻辑备份工具 | mongodump | mysqldump |
逻辑还原工具 | mongorestore | mysql |
数据导出工具 | mongoexport | mysqldump |
数据导入工具 | mongoimport | source |
九. MongoDB备份恢复操作
1. 备份所有库
mongodump
说明:默认备份目录及数据文件格式为:./dump/数据库名/集合名.bson
2. 备份指定库
mongodump -d 库名
3. 备份指定库中的指定集合
mongodump -d 库名 -c 集合名
4. 恢复所有库
mongorestore --drop
说明:将备份的所有数据库恢复到数据库,--drop指定恢复数据之前删除原来数据库数据,否则会造成回复后的数据中数据重复。
5. 恢复指定库
mongorestore -d 库名 --drop
说明:将备份的库的数据恢复到数据库中。
6. 恢复指定库中指定集合中的数据
mongorestore -d 库名 -c 集合名 --drop
说明:将备份的库的集合的数据恢复到数据库。
十. MongoDB监控
1. 通过MongoDB shell命令
db.serverStatus()
(1) 锁信息:
db.serverStatus().globalLock
db.serverStatus().locks
(2) 内存使用情况:
db.serverStatus().mem
(3) 连接情况:
db.serverStatus().connections
(4) 网络情况:
db.serverStatus().network
(5) 索引情况:
db.serverStatus().indexCounters
(6) 记录状态:
db.serverStatus().recordStats
(7) 服务指标:
db.serverStatus().metrics
2. Mongostat
按类型捕获并返回数据库操作的count
命令执行类似如下:
mongostat --host 10.27.29.183:27017 --username root --password password --authenticationDatabase admin

3. Mongotop
跟踪并报告MongoDB实例的当前读写活动,并按集合报告这些统计信息
命令执行类似如下:
mongotop --host 10.27.29.183:27017 --username root --password password --authenticationDatabase admin

4. 利用OS工具监控
(1) vmstat:监控虚拟内存的使用情况
(2) sar:周期性获取系统的趋势数据并存储下来方便分析
(3) iostat:查看存储子系统使用情况
(4) netstat:监控网络状态
5. 采用第三方监控工具
例如:Zabbix
十一. MongoDB常见错误及处理
1. 错误情况1:
ERROR: child process failed ,exited with error number 1
错误原因及处理:dbpath文件的权限问题,增加写权限即可。
2. 错误情况2:
ERROR: child process failed, exited with error number 100
原因及处理:mongod服务非正常关闭,重启后会报此错误。删除mongod.lock件即可。
3. 错误情况3:
mongod服务启动时报错,无法启动
处理:检查启动动的config文件内容,确认其中所对应的目录均存在。
4. 错误情况4:
mongo登录时报错如下:
“WARNING: You are running this process as the root user, which is not recommended.”
处理:不要在root用户下启动服务进程,建议先在操作系统级创建mongod用户,然后再mongod用户启动服务进程。
5. 错误情况5:
mongo登录时报错如下:
WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.We suggest setting it to 'never'
WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.We suggest setting it to 'never'
处理:
sudo echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
sudo echo "never" > /sys/kernel/mm/transparent_hugepage/defrag
然后重启mongod
6. 错误情况6:
mongo登录时报错如下:
WARNING: soft rlimits too low. rlimits set to 4096 processes, 65535 files. Number of processes should be at least 32767.5 : 0.5 times number of files.
处理:
# vi /etc/security/limits.conf
添加一下几行
mongod soft nofile 64000
mongod hard nofile 64000
mongod soft nproc 32000
mongod hard nproc 32000




