MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。——百度百科(懒得写概念了)
做个广告:欢迎大家访问我们持续维护的React组件库react.kingdee.design/
一.MongoDB 常用命令
1.1 数据库启动
命令行启动:
./mongod -dbpath /mongodb/db -logpath /mongodb/log/mongo.log -fork
配置文件启动:
./mongod -f /mongodb/mongo.conf
数据库关闭:
1.直接kill 掉进程
> ps -ef|grep mongo
501 6187 956 0 2:11下午 ttys001 0:36.65 /Users/kux_testMac/soft/mongodb/bin/mongod -f /Users/kux_testMac/soft/mongodb/mongo.conf
501 6221 4299 0 2:11下午 ttys006 0:00.33 ./mongo
501 8797 6232 0 4:19下午 ttys007 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn mongo
kux_testMac@zyquan-2:~/soft/mongodb/bin|
> kill -9 6187
kux_testMac@zyquan-2:~/soft/mongodb/bin|
>
2.使用数据库命令: 注意只有root 角色的用户才可以执行db.shutdowbServer()
> db.shutdownServer()
2020-04-27T08:18:18.950+0000 I NETWORK [js] DBClientConnection failed to receive message from 127.0.0.1:27017 - HostUnreachable: Connection closed by peer
server should be down...
1.2 配置文件
#日志文件位置:改为实际路径
logpath=/root/mongodb/logs/mongo.log
#数据库存储位置:改为实际路径
dbpath=/root/mongodb/data/
#以追加的方式写日志
logappend=true
#端口
port=27017
#是否以守护进程的方式运行
fork=true
#是否以认证方式运行
auth=true
# 启用定期记录CPU利用率和 I/O 等待
#cpu = true
# 详细记录输出
#verbose = true
# Inspect all client data for validity on receipt (useful for
# developing drivers)用于开发驱动程序时验证客户端请求
# objcheck = true
# Enable db quota management
# 启用数据库配额管理
# quota = true
# 设置oplog记录等级
# Set oplogging level where n is
# 0=off (default)
# 1=W
# 2=R
# 3=both
# 7=W+some reads
# diaglog=0
# Diagnostic/debugging option 动态调试项
# nocursors = true
# Ignore query hints 忽略查询提示
# nohints = true
# 禁用http界面,默认为localhost:28017
# nohttpinterface = true
# 关闭服务器端脚本,这将极大的限制功能
# Turns off server-side scripting. This will result in greatly limited
# functionality
# noscripting = true
# 关闭扫描表,任何查询将会是扫描失败
# Turns off table scans. Any query that would do a table scan fails.
# notablescan = true
# 关闭数据文件预分配
# Disable data file preallocation.
# noprealloc = true
# 为新数据库指定.ns文件的大小,单位:MB
# Specify .ns file size for new databases.
# nssize =
# Replication Options 副本集选项
# in replicated mongo databases, specify the replica set name here
# replSet=setname
# maximum size in megabytes for replication operation log
# oplogSize=1024
# path to a key file storing authentication info for connections
# between replica set members
# 指定存储身份验证信息的密钥文件的路径
# keyFile=/path/to/keyfile
1.3 数据库备份与恢复
假设数据库用户名/密码: admin / kux
备份数据库:
./mongodump --username admin --password kux --authenticationDatabase admin
恢复数据库:
注意:E:/test 存放的是上一步备份的数据库文件
./mongorestore -h 127.0.0.1:27017 -u admin -p kux --authenticationDatabase admin -d test E:/test
二. MongoDB 用户授权
2.1 MongoDB 刚刚安装好是不需要授权的可以用mongo 命令直接连接数据库
root@36ec95eccef3:/usr/bin# ./mongo
MongoDB shell version v4.2.6
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("5918b349-a425-4cac-af01-e3cf68e584ad") }
MongoDB server version: 4.2.6
>
2.2 创建admin超级管理员用户
#customDate 为自定义数据,可有可无
#userAdminAnyDatabase 为用户角色
>use admin
db.createUser(
{
user: "admin",
pwd: "admin",
customDate:"xxx", // 自定义数据可有可无
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
2.3 开启访问控制
开启访问控制在mongod 进程启动的时候加上--auth 选项或者在配置文件中加入auth=true。并且重新启动实例
./mongod -dbpath /mongodb/db -logpath /mongodb/log/mongo.log --auth
#是否以认证方式运行
auth=true
2.4 用户验证
可以在mongo shell登录的时候验证用户权限
root@36ec95eccef3:/usr/bin# ./mongo -u admin -p admin --authenticationDatabase admin
MongoDB shell version v4.2.6
connecting to: mongodb://127.0.0.1:27017/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("9f00cee6-d24d-49b0-9437-50a228d2ce38") }
MongoDB server version: 4.2.6
> use admin
switched to db admin
> show users
{
"_id" : "admin.admin",
"userId" : UUID("6cbfae29-0a66-400e-a206-b065e11af182"),
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
>
也可以在进入mongo shell 后使用db.auth 进行验证
> db.auth('admin', 'admin')
1
> show users
{
"_id" : "admin.admin",
"userId" : UUID("6cbfae29-0a66-400e-a206-b065e11af182"),
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
>
2.5 创建普通用户
创建了一个普通用户user1, 另外创建了一个数据库eva。现在user1 对于数据库eva有dbOwner的权限
> db.createUser(
... {
... user: "user1",
... pwd: "pwd1",
... roles: [
... { role: "dbOwner", db: "eva" }
... ]
... }
... )
Successfully added user: {
"user" : "user1",
"roles" : [
{
"role" : "dbOwner",
"db" : "eva"
}
]
}
可以在使用user1的账户访问数据eva, 我们可以测试一下。
root@36ec95eccef3:/usr/bin# ./mongo -u user1 -p pwd1 --authenticationDatabase eva
MongoDB shell version v4.2.6
connecting to: mongodb://127.0.0.1:27017/?authSource=eva&compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("1ebd017b-95d5-4688-b17d-42b3de454964") }
MongoDB server version: 4.2.6
> use eva
switched to db eva
> show dbs
> show users
{
"_id" : "eva.user1",
"userId" : UUID("f38602a6-4578-4c71-b1b1-1c48923946e6"),
"user" : "user1",
"db" : "eva",
"roles" : [
{
"role" : "dbOwner",
"db" : "eva"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
>
Mongodb 创建的用户是放在一个个数据里边,比如admin, 或者自己建的数据库,具体在用户是建在哪个数据库,和db.createUser命令中的数据库无关。是最开始在控制台中use admin 还是use 自己数据有关。
Mongodb 中--authenticationDatabase也指用户的所在的数据库。
use admin
> db.createUser(
... {
... user: "pmtools",
... pwd: "pwd1",
... roles: [
... { role: "dbOwner", db: "pmtools" }
... ]
... }
... )
那授权的时候--authenticationDatabase用的数据库就是admin,但是他对数据库pmtools 有dbOwner 的权限
Mongodb的admin数据库是一个比较特别的数据库
2.6 其他用户操作
查看用户信息
> db.getUser("user1", { showPrivileges: true })
{
"_id" : "eva.user1",
"userId" : UUID("f38602a6-4578-4c71-b1b1-1c48923946e6"),
"user" : "user1",
"db" : "eva",
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
],
"roles" : [
{
"role" : "dbOwner",
"db" : "eva"
}
],
"inheritedRoles" : [
{
"role" : "dbOwner",
"db" : "eva"
}
],
"inheritedPrivileges" : [
{
"resource" : {
"db" : "eva",
"collection" : ""
},
"actions" : [
"bypassDocumentValidation",
"changeCustomData",
"changePassword",
"changeStream",
"collMod",
"collStats",
"compact",
"convertToCapped",
"createCollection",
"createIndex",
"createRole",
"createUser",
"dbHash",
"dbStats",
"dropCollection",
"dropDatabase",
"dropIndex",
"dropRole",
"dropUser",
"emptycapped",
"enableProfiler",
"find",
"grantRole",
"insert",
"killCursors",
"listCollections",
"listIndexes",
"planCacheIndexFilter",
"planCacheRead",
"planCacheWrite",
"reIndex",
"remove",
"renameCollectionSameDB",
"revokeRole",
"setAuthenticationRestriction",
"storageDetails",
"update",
"validate",
"viewRole",
"viewUser"
]
},
{
"resource" : {
"db" : "eva",
"collection" : "system.js"
},
"actions" : [
"changeStream",
"collStats",
"convertToCapped",
"createCollection",
"createIndex",
"dbHash",
"dbStats",
"dropCollection",
"dropIndex",
"emptycapped",
"find",
"insert",
"killCursors",
"listCollections",
"listIndexes",
"planCacheRead",
"remove",
"renameCollectionSameDB",
"update"
]
},
{
"resource" : {
"db" : "eva",
"collection" : "system.profile"
},
"actions" : [
"changeStream",
"collStats",
"convertToCapped",
"createCollection",
"dbHash",
"dbStats",
"dropCollection",
"find",
"killCursors",
"listCollections",
"listIndexes",
"planCacheRead"
]
}
],
"inheritedAuthenticationRestrictions" : [ ]
}
>
为用户添加角色, 注意要使用超级管理员账号操作
> db.grantRolesToUser("user1", [{role: "readWrite", db: "test"}])
> show users
{
"_id" : "admin.admin",
"userId" : UUID("6cbfae29-0a66-400e-a206-b065e11af182"),
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
{
"_id" : "admin.user1",
"userId" : UUID("22d5e21c-1870-4ebd-9b79-28ec5ee1a538"),
"user" : "user1",
"db" : "admin",
"roles" : [
{
"role" : "readWrite",
"db" : "test"
},
{
"role" : "dbOwner",
"db" : "eva"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
>
更新用户信息
> db.updateUser('user1',{roles: [{role: "dbOwner", db: "eva"}]})
> show users
{
"_id" : "admin.admin",
"userId" : UUID("6cbfae29-0a66-400e-a206-b065e11af182"),
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
{
"_id" : "admin.user1",
"userId" : UUID("22d5e21c-1870-4ebd-9b79-28ec5ee1a538"),
"user" : "user1",
"db" : "admin",
"roles" : [
{
"role" : "dbOwner",
"db" : "eva"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
>
> db.runCommand(
{
updateUser: "user1",
roles: [
{ role: "dbOwner", db: "eva" },
]
}
)
收回用户角色
> use admin
> db.revokeRolesFromUser(
"user1",
[
{ role: "read", db: "test" }
]
)
> use admin
> db.runCommand(
{
revokeRolesFromUser: "user1",
roles:
[
{ role: "read", db: "test" }
]
}
)
更改用户密码
> use admin
> db.changeUserPassword("user1", "pwd2")
删除用户
> use admin
> db.dropUser("user1")
> use admin
> db.runCommand({ dropUser: "dbabd_user" })
2.7 MongoDB 内置角色
| 角色分类 | 角色名称 | 角色描述 |
|---|---|---|
| 数据库用户 | read | 允许用户读取指定数据库 |
| 数据库用户 | readWrite | 允许用户读写指定数据库 |
| 数据库管理员 | dbAdmin | 允许用户进行索引创建、删除,查看统计或访问system.profile,但没有角色和用户管理的权限; |
| 数据库管理员 | userAdmin | 提供了在当前数据库中创建和修改角色和用户的能力; |
| 数据库管理员 | dbOwner | 提供对数据库执行任何操作的能力。这个角色组合了readWrite、dbAdmin和userAdmin角色授权的特权; |
| 集群管理角色 | hostManager | 提供监视和管理服务器的能力 |
| 集群管理角色 | clusterManager | 在集群上提供管理和监视操作。可以访问配置和本地数据库,这些数据库分别用于分片和复制; |
| 集群管理角色 | clusterMonitor | 提供对监控工具的只读访问 |
| 集群管理角色 | clusterAdmin | 提供最强大的集群管理访问(副本集、分片、主从等)。组合了clusterManager、clusterMonitor和hostManager角色的能力,还提供了dropDatabase操作 |
| 备份恢复角色 | backup | 提供备份数据所需的能力 |
| 备份恢复角色 | restore | 提供使用mongorestore恢复数据的能力; |
| 所有数据库角色 | readAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读权限 |
| 所有数据库角色 | readWriteAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读写权限 |
| 所有数据库角色 | userAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 |
| 所有数据库角色 | dbAdminAnyDataBase | 只在admin数据库中可用,赋予用户所有数据库的adAdmin权限 |
| 超级用户角色 | root | 超级权限,只能针对admin库; |
| 内部角色 | __system | 提供对数据库中任何对象的任何操作的特权 |
2.8 mongodb 自定义角色
一般情况下mongodb 内置角色是够用的,当内置角色不满足需求的时候可以使用db.createRole()方法来自定义角色。
在创建角色时,必须明确Role的四个特性:
- Scope:角色作用的范围,创建在Admin中的角色,能够在其他DB中使用;在其他DB中创建的角色,只能在当前DB中使用;
- Resource:角色控制的资源,表示授予在该资源上执行特定操作的权限;
- Privilege Actions:定义了User能够在资源上执行的操作,系统定义Action是:Privilege Actions;
- Inherit:角色能够继承其他角色权限
注意的是: 在admin 数据库中创建的角色,Scope是全局的,能够在admin,其他DB和集群中使用,并且能够继承其他DB的Role;而在非admin中创建的角色,Scope是当前数据库,只能在当前DB中使用,只能继承当前数据库的角色。
三. 如何使用docker 运行MongoDB
3.1.docker 的安装
具体安装方法www.runoob.com/docker/maco…
高速下载地址:get.daocloud.io/
安装后修改docker 下载源为国内的地址
安装成功后查看docker 版本
⇒ docker --version
Docker version 19.03.5, build 633a0ea
3.2 下载mongo 镜像
首先搜索mongo 镜像:
> docker search mongo
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mongo MongoDB document databases provide high avai… 6804 [OK]
.
.
.
其中第一个mongo 就是官方的mongo镜像
> docker pull mongo
查看下载的镜像:
⇒ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
mongo latest 3f3daf863757 4 days ago 388MB
ubuntu latest 549b9b86cb8d 4 months ago 64.2MB
hello-world latest fce289e99eb9 16 months ago 1.84kB
3.3 运行容器
最简单的一条命令
#--name 指的容器的名称
# -p 27017:27107 对应的是本机端口:容器端口的映射
# -d 以守护进程运行
# mongo 是对应的mongo容器
⇒ docker run --name mymongo -p 27017:27017 -d mongo
查看对应的镜像
⇒ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dac2ae3b1c4a mongo "docker-entrypoint.s…" 28 seconds ago Up 27 seconds 0.0.0.0:27017->27017/tcp mymongo
开启授权模式,修改容器内运行端口号:
docker run --name mymongo -p 27017:27018 -d mongo --auth --port=27018
停止容器
⇒ docker stop mymongo
mymongo
删除容器
⇒ docker rm mymongo
mymongo
四.MongoDB 副本集(Replica Sets)
4.1 why not 主从复制(master-slave)
主从复制是MongoDB最常用的复制方式,也是一个简单的数据库同步备份的集群技术,这种方式很灵活.可用于备份,故障恢复,读扩展等。最基本的设置方式就是建立一个主节点和一个或多个从节点,每个从节点要知道主节点的地址。采用双机备份后主节点挂掉了后需要手动选择一个从节点接替主机继续服务。所以主从复制不适合生产模式,MongoDB 从3.2 版本以后就移除了主从复制。
副本集已经在大多数场合下替代了主从复制。副本集除了提供主从复制的所有功能之外,还更适合生产使用。
4.2. 副本集原理
副本集是一组维护相同数据集的mongod实例。一个副本集包含几个数据承载节点和一个仲裁器节点(可选)。在数据承载节点中,只有一个成员被视为主要节点,而其他节点则被视为次要节点。
副本集Master故障的时候,副本集可以自动投票,选举出新的Master,并引导其余的Slave服务器连接新的Master,而这个过程对于应用是透明的。可以说MongoDB的副本集是自带故障转移功能的主从复制。
也可以配置一个额外的仲裁节点
4.3 配置副本集
1 启动三个mongo服务(也可以通过配置文件来启动)
# dbpath: 数据库存放地址, --port 端口号, --fork后台运行 --syslog 使用系统日志, replSet副本集名称为kux。
mongod --dbpath=../db1 --port=27018 --fork --syslog --replSet=kux
mongod --dbpath=../db2 --port=27019 --fork --syslog --replSet=kux
mongod --dbpath=../db3 --port=27020 --fork --syslog --replSet=kux
我们预设端口为27018端口的服务是主节点,27019的是从节点,27020是仲裁节点
使用shell 登录27018
mongo localhost:27018
2.初始化副本集/设置本机为主节点
> rs.initiate()
{
"ok" : 0,
"errmsg" : "This node was not started with the replSet option",
"code" : 76,
"codeName" : "NoReplicationEnabled"
}
>
在shell 中回车几次,发现由SECONDARY变为PRIMARY节点
kux:SECONDARY>
kux:PRIMARY>
kux:PRIMARY>
kux:PRIMARY>
也可以查看当前配置
kux:PRIMARY> rs.conf()
{
"_id" : "kux",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "localhost:27018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5eaa3720074889fad47be807")
}
}
kux:PRIMARY>
- 添加27019为从节点
kux:PRIMARY> rs.add('localhost:27019')
{
"ok" : 1,
"operationTime" : Timestamp(1588213805, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1588213805, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
kux:PRIMARY>
4.添加27020为仲裁节点
kux:PRIMARY> rs.addArb('localhost:27020')
{
"ok" : 1,
"operationTime" : Timestamp(1588213864, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1588213864, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
查看现在的副本集状态
kux:PRIMARY> rs.status()
{
"set" : "kux",
"date" : ISODate("2020-04-30T02:31:32.801Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1588213888, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1588213888, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1588213888, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1588213888, 1),
"t" : NumberLong(1)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1588213838, 1),
"members" : [
{
"_id" : 0,
"name" : "localhost:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 457,
"optime" : {
"ts" : Timestamp(1588213888, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-04-30T02:31:28Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1588213536, 2),
"electionDate" : ISODate("2020-04-30T02:25:36Z"),
"configVersion" : 3,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "localhost:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 87,
"optime" : {
"ts" : Timestamp(1588213888, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1588213888, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-04-30T02:31:28Z"),
"optimeDurableDate" : ISODate("2020-04-30T02:31:28Z"),
"lastHeartbeat" : ISODate("2020-04-30T02:31:32.160Z"),
"lastHeartbeatRecv" : ISODate("2020-04-30T02:31:32.160Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "localhost:27018",
"syncSourceHost" : "localhost:27018",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 3
},
{
"_id" : 2,
"name" : "localhost:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 28,
"lastHeartbeat" : ISODate("2020-04-30T02:31:32.160Z"),
"lastHeartbeatRecv" : ISODate("2020-04-30T02:31:32.243Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 3
}
],
"ok" : 1,
"operationTime" : Timestamp(1588213888, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1588213888, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
kux:PRIMARY>
5.验证副本集
首先在主库上建一个test数据库
kux:PRIMARY> use test
switched to db test
kux:PRIMARY> db.test.insert({name: 'zyquan', phonenumber: '1866579xxxx'})
WriteResult({ "nInserted" : 1 })
kux:PRIMARY> db.test.find()
{ "_id" : ObjectId("5eaa3965e5c7a96472a041ce"), "name" : "zyquan", "phonenumber" : "1866579xxxx" }
kux:PRIMARY>
然后杀掉主库进程, mongo 连接localhost:27019 我们发现之前的从库27019已经变为主库,并且test数据库已同步过来了
⇒ ps -ef|grep mongod
501 2100 1 0 10:23上午 ?? 0:03.27 mongod --dbpath=../db1 --port=27018 --fork --syslog --replSet=kux
501 2125 1 0 10:24上午 ?? 0:03.09 mongod --dbpath=../db2 --port=27019 --fork --syslog --replSet=kux
501 2129 1 0 10:24上午 ?? 0:02.42 mongod --dbpath=../db3 --port=27020 --fork --syslog --replSet=kux
501 2243 2208 0 10:36上午 ttys000 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn mongod
501 1514 470 0 10:03上午 ttys008 0:10.27 /Users/kux_testMac/soft/mongodb/bin/mongod -f /Users/kux_testMac/soft/mongodb/mongo.conf
kux_testMac@zyquan-2:~/soft/mongodb/bin|
⇒ kill -9 2100
⇒ mongo localhost:27019
kux:PRIMARY> db.test.find()
{ "_id" : ObjectId("5eaa3965e5c7a96472a041ce"), "name" : "zyquan", "phonenumber" : "1866579xxxx" }
kux:PRIMARY>
4.4 副本集授权验证
4.4.1 keyfile 认证
1.1 要求
(1)通过密钥文件进行身份验证时,副本集中的每个mongo实例都使用密钥文件的内容作为与其他成员进行身份验证的共享密码。只有拥有正确密钥文件的Mongod实例才能加入副本集。
(2)密钥文件的内容必须在6到1024个字符之间,并且对于副本集的所有成员必须是相同的。
1.2 创建
可以使用选择的任何方法生成密钥文件。例如,以下操作用于openssl生成用于密钥文件。
openssl rand -base64 756 > ./keyfile
主要:key的长度必须是6-1024的base64字符,unix下必须相同组权限,windows下不需要。
1.3 更改权限
chmod 600 ./keyfile
1.4 将密钥文件复制到托管副本集成员的每个服务器上。确保运行mongod实例的用户是该文件的所有者,并且可以访问密钥文件。
4.4.2 主库中新建管理员用户
kux:PRIMARY> use admin
switched to db admin
kux:PRIMARY> db.createUser(
... {
... user: "admin",
... pwd: "admin",
... roles: [ { role: "root", db: "admin" } ]
... }
... )
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
kux:PRIMARY>
4.4.3 重新使用auth 方式启动三个数据库
kill 掉原来的三个进程,然后重启启动以下服务
mongod --dbpath=../db1 --port=27018 --fork --syslog --replSet=kux --keyFile=../keyfile --auth
mongod --dbpath=../db2 --port=27019 --fork --syslog --replSet=kux --keyFile=../keyfile --auth
mongod --dbpath=../db3 --port=27020 --fork --syslog --replSet=kux --keyFile=../keyfile --auth
4.4.4 测试
连接主库,使用 db.auth('admin', 'admin')后可查看数据库
⇒ mongo localhost:27018
MongoDB shell version v4.0.11
connecting to: mongodb://localhost:27018/test?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("cc18f704-fe07-465f-b0a8-91bd8b440086") }
MongoDB server version: 4.0.11
kux:PRIMARY> use admin
switched to db admin
kux:PRIMARY> show dbs
kux:PRIMARY> db.auth('admin', 'admin')
1
kux:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
kux:PRIMARY>
杀掉主库进行,连接从库, 发现从库已经自动变为主库,我们执行同样的操作
⇒ mongo localhost:27019
MongoDB shell version v4.0.11
connecting to: mongodb://localhost:27019/test?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("f86278d5-9c9b-485e-a4e2-8e24a0b9257e") }
MongoDB server version: 4.0.11
kux:PRIMARY> use admin
switched to db admin
kux:PRIMARY> show dbs
kux:PRIMARY> db.auth('admin', 'admin')
1
kux:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
kux:PRIMARY>