MongoDB 上手简记
chenzuoqing Lv3

安装和配置

官网获取当前稳定版本 4.0.3

配置文件示例

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
systemLog: # 日志文件路径
destination: file
logAppend: true
path: /usr/local/mongodb/logs/mongodb.log

storage:
# 数据文件路径
dbPath: /usr/local/mongodb/data/
journal:
enabled: true

processManagement:
# 执行mongod启动后在后台创建守护进程运行mongo
fork: true
# pid文件路径
pidFilePath: /usr/local/mongodb/logs/mongod.pid

net:
# 监听地址
port: 27017
bindIp: 0.0.0.0
#security: # 创建管理用户后开启
# authorization: enabled # 登陆认证
# # 多用于replication时节点间的认证`openssl rand -base64 756`生成
# keyFile: /usr/local/mongodb/etc/security.key

#replication: # 开启复制集功能
# replSetName: rs0 # 设置复制名称

启动mongo服务,这里第一次启动没加认证,创建用户后加上 --auth 启动用户认证

1
2
3
4
5
6
shell> cd /usr/local/mongodb
shell> ./bin/mongod -f mongod.yml
about to fork child process, waiting until server is ready for connections.
forked process: 16090 # fork子进程为mongo的守护进程

child process started successfully, parent exiting

停止 mongo

1
2
shell> cd /usr/local/mongodb
shell> ./bin/mongod -f mongod.yml --shutdown

mongo 的日志轮转,旧的日志会重命名成日志名加时间的文件。

1
2
3
4
5
6
# 系统命令方式
shell> kill –SIGUSR1 [PID]

# mongo shell命令方式
> db.runCommand({logRotate:1})

Mongo的使用

连接mongo

1
2
3
4
5
# 连接单节点
shell> mongo 127.0.0.1:28001/admin -u admin -p 111111 --authenticationDatabase admin

# 连接副本集,需要用mogno url字符串的方式,可以带上用户名密码,不带将提示输入密码
shell> mongo mongodb://user:[email protected]:27001,10.10.10.16:27002,10.10.10.17:27000/mydbname?replicaSet=replicaSet1

CUDR操作

创建 db 和 collection 并插入数据。

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# 进入mongo终端
shell> mongo

> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB

# 新建一个db,直接use即可
> use ac
switched to db ac

# use之后若没存储数据,是不会保存的
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB

# 在当前db创建一个me的collection(类似于关系型数据库的表的意思)
> db.me.insert({name: 'abc'})
WriteResult({ "nInserted" : 1 })
> db.me.insert({name: 'EFG'})
WriteResult({ "nInserted" : 1 })

# 保存后有db已经可以show出来
> show dbs
ac 0.000GB
admin 0.000GB
config 0.000GB
local 0.000GB

# 查看当前db的collection
> show collections
me

# 多条插入
> db.me.insertMany([{name: 'hij'},{name: 'lmn'}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5bbd5c530c08adaa73c5d5ef"),
ObjectId("5bbd5c530c08adaa73c5d5f0")
]
}

# 查看collection me中的数据,若只取一条可db.me.find().limit(1)
> db.me.find()
db.me.find()
{ "_id" : ObjectId("5bbd55750c08adaa73c5d5ed"), "name" : "abc" }
{ "_id" : ObjectId("5bbd5c030c08adaa73c5d5ee"), "name" : "EFG" }
{ "_id" : ObjectId("5bbd5c530c08adaa73c5d5ef"), "name" : "hij" }
{ "_id" : ObjectId("5bbd5c530c08adaa73c5d5f0"), "name" : "lmn" }

# 过滤name='abc'的数据
> db.me.find({name: 'abc'})
{ "_id" : ObjectId("5bbd55750c08adaa73c5d5ed"), "name" : "abc" }

# 更新数据,第一个参数是filter条件,第二个为更新动作的内容,也有Many操作。
> db.me.update({name:'abc'}, {$set: { age: 20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.me.find({name:'abc'})
{ "_id" : ObjectId("5bbd55750c08adaa73c5d5ed"), "name" : "abc", "age" : 20 }

# 删除记录,传入过滤条件
> db.me.deleteOne({age: 20})
{ "acknowledged" : true, "deletedCount" : 1 }
> db.me.find()
{ "_id" : ObjectId("5bbd5c030c08adaa73c5d5ee"), "name" : "EFG" }
{ "_id" : ObjectId("5bbd5c530c08adaa73c5d5ef"), "name" : "hij" }
{ "_id" : ObjectId("5bbd5c530c08adaa73c5d5f0"), "name" : "lmn" }

# 删除collection me
> db.me.drop()

# 删除当前库ac,因为之前已经use进了ac才可以这样删除ac
> db.dropDatabase()

用户管理

内置角色说明 参考官档

  • 数据库用户角色(Database User Roles):

    • read:授予 User 只读数据的权限
    • readWrite:授予 User 读写数据的权限
  • 数据库管理角色(Database Administration Roles):

    • dbAdmin:在当前 DB 中执行管理操作
    • dbOwner:在当前 DB 中执行任意操作
    • userAdmin:在当前 DB 中管理 User
  • 备份和还原角色(Backup and Restoration Roles):

    • backup
    • restore
  • 跨库角色(All-Database Roles):

    • readAnyDatabase:授予在所有数据库上读取数据的权限
    • readWriteAnyDatabase:授予在所有数据库上读写数据的权限
    • userAdminAnyDatabase:授予在所有数据库上管理User的权限
    • dbAdminAnyDatabase:授予管理所有数据库的权限
  • 集群管理角色(Cluster Administration Roles):

    • clusterAdmin:授予管理集群的最高权限
    • clusterManager:授予管理和监控集群的权限,A user with this role can access the config and local databases, which are used in sharding and replication, respectively.
    • clusterMonitor:授予监控集群的权限,对监控工具具有readonly的权限
    • hostManager:管理 Server
  • 超级用户角色

    • root:提供对 readWriteAnyDatabase、dbAdminAnyDatabase、userAdminAnyDatabase、clusterAdmin、restore 和 backup 组合的操作和所有资源的访问。

操作示例

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# 创建管理用户,对所有db有管理权限(按角色分配,userAdminAnyDatabase有所有库的userAdmin权限,也就是可以给其他用户授权)
> use admin;
> db.createUser({user: 'admin', pwd:'111111', roles: [{role: "userAdminAnyDatabase", db: "admin"}]})
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}

# 查看用户集合
> db.system.users.find().pretty()
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "nf7YX8afzXgn/tbDKW6Pig==",
"storedKey" : "2k9Lf+yv77NuKMZkVCahgPBrI4M=",
"serverKey" : "DKuwSPYry4sqDtano2o+ttVVRJE="
},
"SCRAM-SHA-256" : {
"iterationCount" : 15000,
"salt" : "MmKYC+wSetKmZXTYt5DH4nx9ncyDei6obz/xzA==",
"storedKey" : "GnlHlaE2mHt5HjyLjv3oMvtSEuzt7MYqD3LTmV03f7c=",
"serverKey" : "jrfiEghGv44JdRyc0LRgQaCV05WQiNdtA7fiGHVH9VQ="
}
},
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}

# 重启mongod,配置文件开启authentication,换admin用户登录
shell> ./bin/mongo -u admin -p 111111 --authenticationDatabase admin
> use ac
> db.me.find() # 这里admin用户对ac库没有权限,需要创建
Error: error: {
"ok" : 0,
"errmsg" : "not authorized on ac to execute command { find: \"me\", filter: {}, lsid: { id: UUID(\"aa798cc9-a036-4733-adbf-861e9c51a446\") }, $db: \"ac\" }",
"code" : 13,
"codeName" : "Unauthorized"
}

# 创建在ac库下创建an00用户,角色是ac的属主
> db.createUser({user: 'an00', pwd:'111111', roles: [{role: 'dbOwner', db: 'ac'}]})

# 换an00用户登录ac库,查看me集合的内容
shell> ./bin/mongo -u an00 -p 111111 --authenticationDatabase ac
> show dbs
ac 0.000GB
> use ac
switched to db ac
> show collections
me
> db.me.find()
{ "_id" : ObjectId("5bbd5c030c08adaa73c5d5ee"), "name" : "EFG", "age" : 20 }
{ "_id" : ObjectId("5bbd5c530c08adaa73c5d5ef"), "name" : "hij" }
{ "_id" : ObjectId("5bbd5c530c08adaa73c5d5f0"), "name" : "lmn" }
> show users
{
"_id" : "ac.an00",
"user" : "an00",
"db" : "ac",
"roles" : [
{
"role" : "dbOwner",
"db" : "ac"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}

# 创建root用户,使用内置的root角色
> use admin
> db.createUser({user: 'root', pwd:'111111', roles: [{role: "root", db: "admin"}]})

备份和恢复

mongodump备份,-h 指定主机地址,-d 指定 database,-c 指定 collection,-o 指定备份文件保存路径

1
./bin/mongodump -u an00 -p '111111' --authenticationDatabase ac -h 127.0.0.1:27017 -d ac -o dump/

恢复备份,–drop 表示先删除数据,然后恢复备份,慎用。-d 指定 database,最后跟上有 bson、json 备份数据的路径
(有副本集时指定PRIMARY节点)

1
./bin/mongorestore -u an00 -p '111111' --authenticationDatabase ac -h 127.0.0.1:27018 -d ac dump/ac/

副本集

若 mongo 提供给非本机连接,副本集的成员 IP 不应该设成 127.0.0.1,当客户端连接副本集时,使用的是副本集中配置的 IP,127.0.0.1 会导致客户端连接自己本地的端口

使用文章最开始的配置文件,打开注释

副本集成员配置可以用 rs.config() 查看,配置中的 members 是一个列表,可以包含多个成员。
副本集成员常用的配置选项如下,参考官档

  • _id 数值,0-255之间,副本集中每个成员的标识符,不可重复,设置后不可修改

  • host 字符串,通常是 IP 或 IP 加指定端口的形式,如:”192.168.1.2:28011”

  • priority 数值,选举 primary 时的优先级,值为0时该成员不会被选举成 primary 节点

  • hidden 布尔值,对客户端隐藏,通常给延时节点和仲裁节点配上

  • slaveDelay 数值,设置此成员落后 primary 的秒数,成员成为延时节点

  • arbiterOnly 布尔值,为 true 时,节点将不存数据,只用于选举时投票用

  • votes 数值,表示成员选举时的票数,通常是 0 或 1,当为 0 时不具备选举权(无选举权的成员必须priority=0),一个副本集最多有 7 个投票选举的成员,如果超过 7 个可以将部分成员此值设为 0

配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> cfg = rs.conf()   // 获取当前配置对象,修改成员ip,重设成员列表

> cfg.members = [{"_id":2,"host" : "192.168.10.234:27017"}, {"_id": 3,"host" : "192.168.10.234:27018"}, {"_id": 4,"host" : "192.168.10.234:27019"}]

> rs.reconfig(cfg, {force: true}) // 修改后重设副本集

# 或者使用 rs.add 增加成员,
> rs.add({'_id' : 10, 'priority':2, 'host' : '192.168.10.235:27017'})

# 添加仲裁节点
> rs.addArb('11.22.33.44:27017')

> rs.status() // 查看副本集状态,状态正常客户端重新连接即可正常
> rs.config() // 再次查看配置
 Comments