使用宝塔面板安装MongoDB4.0.10版本,主要是生产环境中一直使用的是这个版本,并不想因为没有经过测试直接使用新版本导致出现不可预测的问题。由于ubuntu24.04不支持MongoDB4.0.10,只能先安装了ubuntu22.04系统。使用该系统安装的MongoDB。

MongoDB数据目录迁移

由于磁盘挂载的目录并不一定是MongoDB指定的目录,挂载的目录MongoDB不一定具有相关权限,而且根据MongoDB的推荐文件系统使用xfs格式,并且xfs文件系统的reflink特性需要关闭掉。故安装了MongoDB之后,需要对安装路径进行实际的调整。

如果我们没有使用xfs系统或者没有对系统参数进行优化则我们登录mongo的时候就会有如下的提示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ mongo
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a1e1abae-c7a3-4088-9d8c-df33826d1d31") }
MongoDB server version: 4.0.10
Server has startup warnings:
2025-06-16T14:04:44.829+0800 I STORAGE [initandlisten]
2025-06-16T14:04:44.829+0800 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2025-06-16T14:04:44.829+0800 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten]
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten]
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten]
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 4096 processes, 1000000 files. Number of processes should be at least 500000 : 0.5 times number of files.
2025-06-16T14:07:50.807+0800 I CONTROL [initandlisten]
  • 关于磁盘挂载的具体流程可以参考:Linux挂载磁盘与扩容,挂载时需要特别注意设置成xfs格式,且reflink特性关闭掉
  • 关于Linux系统参数优化的流程可以参考:Linux系统参数优化
  • 本次实际安装时将目录指定为/data/mongodb。
1
2
# 将/data/mongodb目录的拥有权切换给mongo组和mongo用户,这样MongoDB才能正常启动
$ sudo chown -R mongo.mongo /data/mongodb

MongoDB的配置文件信息如下所示,由于bindIp指示了允许所有ip连接。这是具有风险的。必须搭配ufw防火墙进行实际的ip接入27017限制来保证安全。

1
2
3
4
5
6
7
8
$ sudo ufw status
Status: active

To Action From
-- ------ ----
27017/tcp ALLOW 192.168.0.0/24
27723/tcp ALLOW 192.168.0.0/24
22/tcp ALLOW 192.168.0.0/24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# config.conf
net:
# bindIp: 127.0.0.1
bindIp: 0.0.0.0
port: 27017
processManagement:
fork: true
pidFilePath: /data/mongodb/log/configsvr.pid
security:
authorization: disabled
javascriptEnabled: false
storage:
dbPath: /data/mongodb/data
directoryPerDB: true
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 10
systemLog:
destination: file
logAppend: true
path: /data/mongodb/log/config.log

MongoDB副本集搭建

我们使用内网的192.168.0.37、38、39进行搭建一个一主两副的副本集。搭建副本集的重要过程是在配置文件中加入副本集信息。

  • 配置文件修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# config.conf
net:
# bindIp: 127.0.0.1
bindIp: 0.0.0.0
port: 27017
processManagement:
fork: true
pidFilePath: /data/mongodb/log/configsvr.pid
security:
authorization: disabled
javascriptEnabled: false
storage:
dbPath: /data/mongodb/data
directoryPerDB: true
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 10
systemLog:
destination: file
logAppend: true
path: /data/mongodb/log/config.log
# 此处需要加入副本集相关配置,副本集名称为rs0,副本集中所有MongoDB的配置文件中都需要加入该段信息
replication:
replSetName: rs0

所有的副本集主机配置信息中都加入该信息之后,对所有MongoDB服务进行重启。重启之后登录入37虚拟机的mongo客户端。并配置脚本。

  • 登录mongo客户端
1
2
3
4
5
6
$ mongo
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("be5accfa-763e-400c-8dd1-56c9e1472546") }
MongoDB server version: 4.0.10
>
  • 编写配置文件,在客户端输入配置文件,配置文件中顺带指定了优先级。则37为主机,37故障时39顺延成为主机。
1
2
3
4
5
6
7
8
9
conf=
{
"_id":"rs0",
"members": [
{"_id": 0,"host":"192.168.0.37:27017","priority": 10},
{"_id": 1,"host":"192.168.0.38:27017","priority": 1,},
{"_id": 2,"host":"192.168.0.39:27017","priority": 2,}
]
}

输入配置后客户端的响应,如下代码所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
> conf=
... {
... "_id":"rs0",
... "members": [
... {"_id": 0,"host":"192.168.0.37:27017","priority": 10},
... {"_id": 1,"host":"192.168.0.38:27017","priority": 1,},
... {"_id": 2,"host":"192.168.0.39:27017","priority": 2,}
... ]
... }
{
"_id" : "rs0",
"members" : [
{
"_id" : 0,
"host" : "192.168.0.37:27017",
"priority" : 10
},
{
"_id" : 1,
"host" : "192.168.0.38:27017",
"priority" : 1
},
{
"_id" : 2,
"host" : "192.168.0.39:27017",
"priority" : 2
}
]
}
>
  • rs.initiate(conf) 进行实际配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
> rs.initiate(conf)
{
"ok" : 1,
"operationTime" : Timestamp(1768031398, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1768031398, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
rs0:SECONDARY>
rs0:PRIMARY>

这样就完成了MongoDB副本集的搭建。由于这是在内网中搭建并搭配了防火墙进行实际的限制ip白名单。故并没有设置密码和安全登录等相关操作。使用起来相对简单,安全性则使用防火墙进行限制。具体的密码和安全登录等相关操作,后续会进行补充。

MongoDB副本集操作

副本集成员操作

1
2
3
4
5
6
7
8
9
10
11
12
13
$ mongo
# 增加成员
rs0:PRIMARY>rs.add("ip:port")
# 删除成员
rs0:PRIMARY>rs.remove("ip:port")
# 增加仲裁
rs0:PRIMARY>rs.addArb("ip:port")
# 添加备份成员
>rs.add({"_id":4,"host":"ip:port","priority":0,"hidden":true})
# 先获取配置信息,然后修改成员属性
rs0:PRIMARY> var conf=rs.conf()
rs0:PRIMARY> conf.members[1].priority = 15
rs0:PRIMARY> rs.reconfig(conf)

MongoDB备份与恢复

MongoDB的备份与恢复相比于MySQL来讲是更加方便的。mongodump与mongorestore成对使用,mongoexport与mongoimport成对使用。值得注意的是mongodump的备份更加完善,它附带了每个文档集的索引等元数据信息。mongoexport并没有附带该类信息,使用导出与恢复之后需要手动创建索引等信息。

mongodump - 逻辑备份工具

使用mongodump进行实际数据库导出的时候,务必要根据实际情况指定–numParallelCollections的数量,避免占用过高的CPU影响生产业务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 基础备份
$ mongodump --uri="mongodb://username:password@localhost:27017" --out=/backup/

# 完整参数示例
$ mongodump \
--host="localhost" \
--port=27017 \
--username="admin" \
--password="password" \
--authenticationDatabase="admin" \
--db="mydatabase" \ # 备份单个数据库
--collection="users" \ # 备份单个集合
--out="/backup/$(date +%Y%m%d_%H%M%S)" \
--gzip \ # 压缩备份
--numParallelCollections=4 \ # 并行备份
--verbose

mongorestore - 恢复工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 恢复整个数据库
$ mongorestore --uri="mongodb://localhost:27017" /backup/20240101/

# 选择性恢复
$ mongorestore \
--host="localhost:27017" \
--username="admin" \
--password="password" \
--nsInclude="mydatabase.*" \ # 恢复指定数据库
--nsExclude="mydatabase.logs" \ # 排除特定集合
--gzip \
--numParallelCollections=4 \
--drop \ # 恢复前删除已存在的数据
/backup/mydatabase/

2. 数据导出/导入工具

mongoexport - 导出为JSON/CSV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 导出为JSON
$ mongoexport \
--uri="mongodb://localhost:27017/mydatabase" \
--collection="users" \
--query='{"status": "active"}' \
--fields="_id,name,email,created_at" \
--out="/backup/users.json" \
--jsonArray \ # 输出为JSON数组
--pretty

# 导出为CSV
$ mongoexport \
--db="mydatabase" \
--collection="products" \
--type="csv" \
--fields="name,price,category" \
--out="/backup/products.csv"

mongoimport - 导入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 导入JSON数据
$ mongoimport \
--uri="mongodb://localhost:27017/mydatabase" \
--collection="users" \
--file="/backup/users.json" \
--mode="upsert" \ # 插入或更新
--upsertFields="email" \ # 根据email字段更新
--jsonArray

# 导入CSV数据
$ mongoimport \
--db="mydatabase" \
--collection="products" \
--type="csv" \
--headerline \ # 使用第一行作为字段名
--file="/backup/products.csv"