MongoDB 安全与认证、主从复制

目录

安全与认证

安全认证简述

准备工作

db.help( )

db.createUser( userDocument)

安全认证流程

创建管理员

创建普通用户

MongoDB 安全认证方式启动

客户端普通用户登录

客户端管理员登录

可视化工具登录

主从复制(主从集群 )

配置流程


安全与认证

安全认证简述

1、Mysql 数据库安装的时候会强制设置管理员账号与密码,如默认的是 root : root,而 MongoDB 默认是没有账号的,可以直接连接,无须身份验证

2、如《 MongoDB》整个系列的文章,前面的章节学习时都是直接连接,没有进行密码认证的,好处是学习时方便,但实际项目中肯定是要权限验证的,否则后果不堪设想。

3、虽然 Linux 可以使用防火墙来关闭 MongoDB 的访问端口,如默认的 27017,但这毕竟治根不治本。

4、所以本文将详细介绍 MongoDB 的安全认证,演示版本为  MongoDB 4.0.2,未安装的可以参考《MongoDB 下载_安装_配置 及 启动与连接

准备工作

1、本文演示的是《 MongoDB 下载_安装_配置 及 启动与连接》安装好的 MongoDB 4.0.2 版本

2、首先 开启 MongoDB 服务端,然后使用 MongoDB 客户端连接成功,不清楚的可以参考《《 MongoDB 下载_安装_配置 及 启动与连接》》,如下所示,MongoDB 服务端启动成功,MongoDB 客户端连接成功!

db.help( )

1、可以在客户端使用命令 " db.help() " 方法进行查看客户端能调用的所有方法,不同的 MongoDB 版本能调用的方法可能略有不同,如下所示:

2、 db.createUser(userDocument):用于创建 MongoDB 登录用户以及分配权限

3、 db.auth(username, password):当 MongoDB 服务端开启安全检查时,客户端登录后可以通过此方法进行验证,只要验证通过才能进行数据库操作

4、其余方法可以自行学习,如 db.shutdownServer() 关闭 MongoDB 数据库 等等!

> db.help();
DB methods:
        db.adminCommand(nameOrDocument) - switches to 'admin' db, and runs command [just calls db.runCommand(...)]
        db.aggregate([pipeline], {options}) - performs a collectionless aggregation on this database; returns a cursor
        db.auth(username, password)
        db.cloneDatabase(fromhost) - deprecated
        db.commandHelp(name) returns the help for the command
        db.copyDatabase(fromdb, todb, fromhost) - deprecated
        db.createCollection(name, {size: ..., capped: ..., max: ...})
        db.createView(name, viewOn, [{$operator: {...}}, ...], {viewOptions})
        db.createUser(userDocument)
        db.currentOp() displays currently executing operations in the db
        db.dropDatabase()
        db.eval() - deprecated
        db.fsyncLock() flush data to disk and lock server for backups
        db.fsyncUnlock() unlocks server following a db.fsyncLock()
        db.getCollection(cname) same as db['cname'] or db.cname
        db.getCollectionInfos([filter]) - returns a list that contains the names and options of the db's collections
        db.getCollectionNames()
        db.getLastError() - just returns the err msg string
        db.getLastErrorObj() - return full status object
        db.getLogComponents()
        db.getMongo() get the server connection object
        db.getMongo().setSlaveOk() allow queries on a replication slave server
        db.getName()
        db.getPrevError()
        db.getProfilingLevel() - deprecated
        db.getProfilingStatus() - returns if profiling is on and slow threshold
        db.getReplicationInfo()
        db.getSiblingDB(name) get the db at the same server as this one
        db.getWriteConcern() - returns the write concern used for any operations on this db, inherited from server object if set
        db.hostInfo() get details about the server's host
        db.isMaster() check replica primary status
        db.killOp(opid) kills the current operation in the db
        db.listCommands() lists all the db commands
        db.loadServerScripts() loads all the scripts in db.system.js
        db.logout()
        db.printCollectionStats()
        db.printReplicationInfo()
        db.printShardingStatus()
        db.printSlaveReplicationInfo()
        db.dropUser(username)
        db.repairDatabase()
        db.resetError()
        db.runCommand(cmdObj) run a database command.  if cmdObj is a string, turns it into {cmdObj: 1}
        db.serverStatus()
        db.setLogLevel(level,<component>)
        db.setProfilingLevel(level,slowms) 0=off 1=slow 2=all
        db.setWriteConcern(<write concern doc>) - sets the write concern for writes to the db
        db.unsetWriteConcern(<write concern doc>) - unsets the write concern for writes to the db
        db.setVerboseShell(flag) display extra information in shell output
        db.shutdownServer()
        db.stats()
        db.version() current version of the server
>

db.createUser( userDocument)

1、db.createUser(userDocument):用于创建 MongoDB 登录用户以及分配权限的方法

2、MongoDB 整个安全认证主要就是依靠这个方法进行的,创建用户以及分配权限的格式如下:

db.createUser(
  {
    user: "用户账号",
    pwd: "用户密码",
    roles: [ 
    { role: "角色", db: "安全认证的数据库" },
    { role: "角色", db: "安全认证的数据库" } 
             ]
  }
)

user:创建的用户名称,如 zhangSan、root .......

pwd:用户登录的密码

roles:为用户分配的角色,不同的角色拥有不同的权限,参数是数组,可以同时设置多个

role:角色,MonngoDB 已经约定好的角色,不同的角色对应不同的权限,内置的权限如下:

read:允许用户读取指定数据库

readWrite:允许用户读写指定数据库

dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile

userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户

clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。

readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限

readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限

userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。

root:只在admin数据库中可用。超级账号,超级权限

 ----------------------------------------------------------------------------------------------------------------------------------------------

数据库用户角色:read、readWrite;

数据库管理角色:dbAdmin、dbOwner、userAdmin;

集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;

备份恢复角色:backup、restore;

所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase

超级用户角色:root // 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)

db:数据库实例名称,如 MongoDB 4.0.2 默认自带的有 admin、local、config、test 等,即为哪个数据库实例设置用户。

安全认证流程

创建管理员

1、MongoDB 服务端开启安全检查之前,至少需要有一个管理员账号,admin 数据库中的用户都被视为管理员

2、如果 admin 库没有任何用户的话,即使在其他数据库中创建了用户,启用身份验证,默认的连接方式依然会有超级权限,即仍然可以不验证账号密码照样能进行 CRUD,安全认证相当于无效。

3、如下所示,先切换到 admin 数据库,然后 db.createUser 创建管理员账号,用户名 roor,密码 root,权限也是 root 角色。

> use admin
switched to db admin
> db
admin
> db.createUser(
... {
... user:"root",
... pwd:"root",
... roles:[{role:"root",db:"admin"}]
... })
Successfully added user: {
        "user" : "root",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
>

创建普通用户

1、如下所示 mydb1 、mydb2 是自己新建的数据库,没安全认证之前可以随意 CRUD,其余的都是 mongoDB 4.0.2 自带的数据库

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
mydb1   0.000GB
mydb2   0.186GB
> use mydb1
switched to db mydb1
> show tables
c1
c2
> db.c1.find()
{ "_id" : ObjectId("5b98bc379253fbe383c9f051"), "name" : "zhangSan4", "age" : 4 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f04f"), "name" : "zhangSan2", "age" : 2 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f04e"), "name" : "zhangSan1", "age" : 1 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f050"), "name" : "zhangSan3", "age" : 3 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f053"), "name" : "zhangSan6", "age" : 6 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f052"), "name" : "zhangSan5", "age" : 5 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f055"), "name" : "zhangSan8", "age" : 8 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f054"), "name" : "zhangSan7", "age" : 7 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f056"), "name" : "zhangSan9", "age" : 9 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f057"), "name" : "zhangSan10", "age" : 10 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f058"), "name" : "zhangSan11", "age" : 11 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05b"), "name" : "zhangSan14", "age" : 14 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05a"), "name" : "zhangSan13", "age" : 13 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05c"), "name" : "zhangSan15", "age" : 15 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05d"), "name" : "zhangSan16", "age" : 16 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05e"), "name" : "zhangSan17", "age" : 17 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05f"), "name" : "zhangSan18", "age" : 18 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f059"), "name" : "zhangSan12", "age" : 12 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f063"), "name" : "zhangSan22", "age" : 22 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f060"), "name" : "zhangSan19", "age" : 19 }
Type "it" for more
>

2、为 admin 库创建管理员之后,现在来为 普通数据库创建普通用户,以 mydb1 为例,方式与创建管理员一致,切换到指定数据库进行创建即可。

3、如下所示,为 mydb1 数据库创建了两个用户,zhangSan 拥有读写权限,liSi 拥有只读权限,密码都是 123456.

> use mydb1
switched to db mydb1
> db
mydb1
> db.createUser({
... user:"zhangSan",
... pwd:"123456",
... roles:[{role:"readWrite",db:"mydb1"}]
... })
Successfully added user: {
        "user" : "zhangSan",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "mydb1"
                }
        ]
}
> db.createUser({
... user:"liSi",
... pwd:"123456",
... roles:[{role:"read",db:"mydb1"}]
... })
Successfully added user: {
        "user" : "liSi",
        "roles" : [
                {
                        "role" : "read",
                        "db" : "mydb1"
                }
        ]
}
>

4、接着从客户端关闭 MongoDB 服务端,之后服务端会以安全认证方式进行启动

> use admin
switched to db admin
> db.shutdownServer()
server should be down...
2018-09-13T16:56:37.394+0800 I NETWORK  [js] trying reconnect to 127.0.0.1:27017 failed
2018-09-13T16:56:38.434+0800 I NETWORK  [js] reconnect 127.0.0.1:27017 failed failed
>

MongoDB 安全认证方式启动

1、mongod --dbpath=D:\MongoDB\Data 启动 MongoDB 数据库,这是无安全认证方式启动,即启动之后 MongoDB 客户端可以随意连接任意操作,没有任何约束

2、mongod --dbpath=D:\MongoDB\Data  --auth:加上参数 --auth 则表示已安全认证方式启动,再访问具有安全认证的数据库时必须进行安全检测。

3、如下所示,启动成功,默认端口为 27017.

C:\Users\Administrator.SC-201707281232>mongod --dbpath=D:\MongoDB\Data  --auth
2018-09-13T17:01:44.807+0800 I CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2018-09-13T17:01:45.781+0800 I CONTROL  [initandlisten] MongoDB starting : pid=10368 port=27017 dbpath=D:\MongoDB\Data 64-bit host=SC-201707281232
2018-09-13T17:01:45.781+0800 I CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2018-09-13T17:01:45.781+0800 I CONTROL  [initandlisten] db version v4.0.2-rc0
2018-09-13T17:01:45.781+0800 I CONTROL  [initandlisten] git version: fc1573ba18aee42f97a3bb13b67af7d837826b47
2018-09-13T17:01:45.781+0800 I CONTROL  [initandlisten] allocator: tcmalloc
2018-09-13T17:01:45.782+0800 I CONTROL  [initandlisten] modules: none
2018-09-13T17:01:45.782+0800 I CONTROL  [initandlisten] build environment:
2018-09-13T17:01:45.782+0800 I CONTROL  [initandlisten]     distmod: 2008plus-ssl
2018-09-13T17:01:45.782+0800 I CONTROL  [initandlisten]     distarch: x86_64
2018-09-13T17:01:45.782+0800 I CONTROL  [initandlisten]     target_arch: x86_64
2018-09-13T17:01:45.782+0800 I CONTROL  [initandlisten] options: { security: { authorization: "enabled" }, storage: { dbPath: "D:\MongoDB\Data" } }
2018-09-13T17:01:45.787+0800 I STORAGE  [initandlisten] Detected data files in D:\MongoDB\Data created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2018-09-13T17:01:45.787+0800 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=3552M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),statistics_log=(wait=0),verbose=(recovery_progress),
2018-09-13T17:01:46.203+0800 I STORAGE  [initandlisten] WiredTiger message [1536829306:203475][10368:140730388790352], txn-recover: Main recovery loop: starting at 11/101760
2018-09-13T17:01:46.347+0800 I STORAGE  [initandlisten] WiredTiger message [1536829306:347392][10368:140730388790352], txn-recover: Recovering log 11 through 12
2018-09-13T17:01:46.493+0800 I STORAGE  [initandlisten] WiredTiger message [1536829306:492562][10368:140730388790352], txn-recover: Recovering log 12 through 12
2018-09-13T17:01:46.565+0800 I STORAGE  [initandlisten] WiredTiger message [1536829306:565538][10368:140730388790352], txn-recover: Set global recovery timestamp: 0
2018-09-13T17:01:47.018+0800 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2018-09-13T17:01:48.208+0800 I CONTROL  [initandlisten]
2018-09-13T17:01:48.208+0800 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2018-09-13T17:01:48.210+0800 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2018-09-13T17:01:48.210+0800 I CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP
2018-09-13T17:01:48.210+0800 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2018-09-13T17:01:48.211+0800 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2018-09-13T17:01:48.211+0800 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2018-09-13T17:01:48.212+0800 I CONTROL  [initandlisten]
2018-09-13T17:01:51.076+0800 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory 'D:/MongoDB/Data/diagnostic.data'
2018-09-13T17:01:51.087+0800 I NETWORK  [initandlisten] waiting for connections on port 27017

客户端普通用户登录

1、现在仍然像以前一样进行登录,如下所示直接登录进入 mydb1 数据库中,登录是成功的,只是登录后日志少了很多东西,而且执行 show dbs 命令,以及 show tables 等命令都是失败的,即使没有被安全认证的数据库,用户同样操作不了,这都是因为权限不足,一句话:用户只能在自己权限范围内的数据库中进行操作。

C:\Users\Administrator.SC-201707281232>mongo localhost:27017/mydb1
MongoDB shell version v4.0.2-rc0
connecting to: mongodb://localhost:27017/mydb1
MongoDB server version: 4.0.2-rc0
> show dbs
2018-09-13T17:07:44.617+0800 E QUERY    [js] Error: listDatabases failed:{
        "ok" : 0,
        "errmsg" : "command listDatabases requires authentication",
        "code" : 13,
        "codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:67:1
shellHelper.show@src/mongo/shell/utils.js:876:19
shellHelper@src/mongo/shell/utils.js:766:15
@(shellhelp2):1:1
> db
mydb1
> show tables
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus
>

2、如下所示,登录之后必须使用 db.auth("账号","密码") 方法进行安全认证,认证通过,才能进行权限范围内的操作,show dbs 已经看不到其它未拥有操作权限的数据库了,显然它也操作不了其它未授权的数据库

3、因为创建的用户 zhangSan 拥有对 mydb1 的读写权限,所以如下所示 读写正常

4、db.auth("账号","密码") 返回 1 表示验证成功,0 表示验证失败

5、注意 db.auth 认证必须在对应的数据库下进行,比如为 db1 数据库单独创建的用户 dbUser,不能在 db2 数据库下执行 db.auth 验证操作,否则是失败的,只能到 db1 下去验证。

> db.auth("zhangSan","123456")
1
> show dbs
mydb1  0.000GB
> show tables
c1
c2
> db.c2.find().count()
100
> db.c2.insert({name:"huaAn",desc:"华安"} )
WriteResult({ "nInserted" : 1 })
> db.c2.find().count()                   })
101
> db.c2.find()
{ "_id" : ObjectId("5b98bc379253fbe383c9f050"), "name" : "zhangSan3", "age" : 3 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f051"), "name" : "zhangSan4", "age" : 4 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f04f"), "name" : "zhangSan2", "age" : 2 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f04e"), "name" : "zhangSan1", "age" : 1 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f052"), "name" : "zhangSan5", "age" : 5 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f053"), "name" : "zhangSan6", "age" : 6 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f054"), "name" : "zhangSan7", "age" : 7 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f056"), "name" : "zhangSan9", "age" : 9 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f055"), "name" : "zhangSan8", "age" : 8 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f057"), "name" : "zhangSan10", "age" : 10 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05b"), "name" : "zhangSan14", "age" : 14 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f058"), "name" : "zhangSan11", "age" : 11 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05a"), "name" : "zhangSan13", "age" : 13 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05c"), "name" : "zhangSan15", "age" : 15 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05d"), "name" : "zhangSan16", "age" : 16 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05e"), "name" : "zhangSan17", "age" : 17 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05f"), "name" : "zhangSan18", "age" : 18 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f060"), "name" : "zhangSan19", "age" : 19 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f059"), "name" : "zhangSan12", "age" : 12 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f062"), "name" : "zhangSan21", "age" : 21 }
Type "it" for more
>

6、除了登录后再使用 db.auth("账号","密码")  方法进行验证之外,也可以像 Mysql 一样,在登录的同时指定 账号与密码

7、如下所示:

 mongo localhost:27017/mydb1 :表示登录本地 27017 端口的 MongoDB 服务端,注意必须同时指定用户进入的数据库,与后面的 --authenticationDatabase 指定一致即可

-u :指定登录用户名

-p:指定登录密码

--authenticationDatabase "mydb1":数据库认证,接安全认证的数据库实例

8、因为 liSi 用户在创建的时候只赋予 读 权限,所以如下所示,可以读,但不能写,删除操作就更加不能了。

C:\Users\Administrator.SC-201707281232>mongo localhost:27017/mydb1 -u "liSi" -p "123456" --authenticationDatabase "mydb1"
MongoDB shell version v4.0.2-rc0
connecting to: mongodb://localhost:27017/mydb1
MongoDB server version: 4.0.2-rc0
> show tables
c1
c2
> db.c1.find().count()
100
> db.c1.insert({name:"huaAn",desc:"华安"})
WriteCommandError({
        "ok" : 0,
        "errmsg" : "not authorized on mydb1 to execute command { insert: \"c1\", ordered: true, lsid: { id: UUID(\"8533fbc6-f7de-46b3-8052-733c7136b6fd\") }, $db: \"mydb1\" }",
        "code" : 13,
        "codeName" : "Unauthorized"
})
> db.c1.find()
{ "_id" : ObjectId("5b98bc379253fbe383c9f051"), "name" : "zhangSan4", "age" : 4 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f04f"), "name" : "zhangSan2", "age" : 2 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f04e"), "name" : "zhangSan1", "age" : 1 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f050"), "name" : "zhangSan3", "age" : 3 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f053"), "name" : "zhangSan6", "age" : 6 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f052"), "name" : "zhangSan5", "age" : 5 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f055"), "name" : "zhangSan8", "age" : 8 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f054"), "name" : "zhangSan7", "age" : 7 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f056"), "name" : "zhangSan9", "age" : 9 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f057"), "name" : "zhangSan10", "age" : 10 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f058"), "name" : "zhangSan11", "age" : 11 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05b"), "name" : "zhangSan14", "age" : 14 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05a"), "name" : "zhangSan13", "age" : 13 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05c"), "name" : "zhangSan15", "age" : 15 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05d"), "name" : "zhangSan16", "age" : 16 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05e"), "name" : "zhangSan17", "age" : 17 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f05f"), "name" : "zhangSan18", "age" : 18 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f059"), "name" : "zhangSan12", "age" : 12 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f063"), "name" : "zhangSan22", "age" : 22 }
{ "_id" : ObjectId("5b98bc379253fbe383c9f060"), "name" : "zhangSan19", "age" : 19 }
Type "it" for more
>

客户端管理员登录

如下所示 管理员 root 登录,安全认证通过后,拥有对所有数据库的所有权限,不再累述。

C:\Users\Administrator.SC-201707281232>mongo localhost:27017
MongoDB shell version v4.0.2-rc0
connecting to: mongodb://localhost:27017/test
MongoDB server version: 4.0.2-rc0
> use admin
switched to db admin
> db.auth("root","root")
1
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
mydb1   0.000GB
mydb2   0.186GB
> use mydb1
switched to db mydb1
> show tables
c1
c2
> db.c1.drop()
true
> show tables
c2
>

可视化工具登录

此时使用《 MongoDB 可视化工具 Robomongo 使用介绍》等第三方可视化工具进行连接时,同样需要指定 账号与密码,连接成功之后,也只能在自己权限范围内的数据库中进行活动。

主从复制(主从集群 )

1、集群:多台计算机同时对外提供服务,从而达到负载均衡,理论概念可以参考《Nginx》

2、主从复制是 MongoDB 最常用的复制方式,非常灵活,可用于备份、故障恢复、读扩展 等 。

3、最基本的设置方式就是建立一个主节点 和 一个及以上的从节点,每个从节点要知道主节点的地址(IP 与 端口)。

4、MongoDB 的复制至少需要两个服务器或者节点,其中一个作为主节点,负责处理客户端请求,其它的都作为从节点,负责映射主节点的数据,始终保持与主节点数据一致。

5、主节点记录在其上执行的所有操作(增删改查),从节点定期轮询主节点获得这些操作,然后对自己的数据副本执行这些操作,由于和主节点执行了相同的操作,从节点就能保持与主节点的数据同步。

6、主节点的操作记录成为 oplog(operation log),oplog 存储在特殊的数据库——lcoal 中,oplog 就在其中的 oplog.$main 集合里面,oplog 中的每个文档都代表主节点上执行的一个操作。

7、需要强调的是 oplog 只记录改变数据库状态的操作,即增删改,而查询不会存储在 oplog 中,因为 oplog 只是作为从节点与主节点保持数据同步的机制。

8、主节点与多个从节点可以是同一个 MongoDB 上,即通过端口不同,可以新建多个 MongoDB 实例,让其中一个作为主节点,其余作为从节点

9、主节点与多个从节点也可以在不同的机器上,如 服务器 A 的 MongoDB 作为 主节点,服务器 B、C 上面的 MongoDB 作为从节点。

10、MongoDB 的最新版本已不再推荐此方案,比如安装的 MongoDB 4.0.2 版本这个功能已经没有了。

配置流程

1、因为 MongoDB 的最新版本已经不再支持主从复制,比如安装的 MongoDB 4.0.2 版本这个功能已经没有了,所以只做简要描述:

2、MongoDB 低版本还是可以使用的,windows 上操作流程如下:

  1. 在任意位置创建两个数据库存储目录,如 D:\MongoDB\Mater 、 D:\MongoDB\Slave,master(主人) 目录作为主节点的数据文件的目录,slave(奴隶) 目录作为从节点的数据文件的目录。(目录名称自定义即可,主从节点需要指定不同的端口进行启动)
  2. 启动主节点:mongod --dbpath D:\MongoDB\Mater --port 27018 --master,(如果是安全认证启动,则再加上 --auth )
  3. 启动从节点:mongod --dbpath D:\MongoDB\Slave --port 27019 --slave --source localhost:27018,( 从节点需要指定主节点的 IP 与端口 )

3、启动成功后就可以连接主节点进行操作(增删改查)了,而这些操作(增删改)会同步到从节点,以保证所有节点数据一致

4、然后可以对从节点进行查询操作,注意从节点只能查询!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚩尤后裔-汪茂雄

芝兰生于深林,不以无人而不芳。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值