一、MongoDB数据操作

1.基本操作

2.插入数据

#插入单条数据
> db.table.insertOne({name:"qiudao",age:88})

#插入多条数据
> db.table.insertMany({name:"qiudao",age:88},{name:"zengdao",age:99})

3.查询数据

4.修改数据

> db.table.updateOne({_id:ObjectId("5ece09a33230a0c32e8509b8")},{$set:{age:38}})

5.索引

1)查看执行计划

> db.table.find({age:{$lt:30}}).explain()
{    #查询计划
    "queryPlanner" : {
        #查询计划版本
        "plannerVersion" : 1,
        #被查询的库和集合
        "namespace" : "database.table",
        #查询索引设置
        "indexFilterSet" : false,
        #查询条件
        "parsedQuery" : {
            "age" : {
                "$lt" : 30
            }
        },
        #成功的执行计划
        "winningPlan" : {
            #使用了全表扫描,没走索引
            "stage" : "COLLSCAN",
            #查询条件
            "filter" : {
                "age" : {
                    "$lt" : 30
                }
            },
            #查询方向
            "direction" : "forward"
        },
        #拒绝的计划
        "rejectedPlans" : [ ]
    },
    #服务器信息
    "serverInfo" : {
        "host" : "redis03",
        "port" : 27017,
        "version" : "3.6.13",
        "gitVersion" : "db3c76679b7a3d9b443a0e1b3e45ed02b88c539f"
    },
    "ok" : 1
}

2)创建索引

> db.table.createIndex({age:1},{background:true})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

当创建索引时,键后面的数字表明了索引的方向,取值为1或者-1,1表示升序,-1表示降序。升序或者降序在随机访问的时候关系不大,当时在做排序或者范围查询的时候就很重要了。

3)查看索引

> db.table.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "database.table"
    },
    {
        "v" : 2,
        "key" : {
            "age" : 3
        },
        "name" : "age_3",
        "ns" : "database.table",
        "background" : true
    },
    {
        "v" : 2,
        "key" : {
            "name" : 100
        },
        "name" : "name_100",
        "ns" : "database.table"
    }
]

4)再次查看执行计划

> db.table.find({age:{$lt:30}}).explain()
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                #走了索引
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "age" : 3
                },

6.删除

1)删除数据

#删除单条数据
> db.table.deleteOne({name:"qiudao"})
{ "acknowledged" : true, "deletedCount" : 1 }

#删除多条数据
> db.table.deleteMany({name:"qiudao"})
{ "acknowledged" : true, "deletedCount" : 2 }

2)删除索引

> db.table.dropIndex({age:-1})
{ "nIndexesWas" : 4, "ok" : 1 }

> db.table.dropIndex({age:3})
{ "nIndexesWas" : 3, "ok" : 1 }

#删除ID以外的所有索引(很危险)
> db.table.dropIndexes()
{
    "nIndexesWas" : 2,
    "msg" : "non-_id indexes dropped for collection",
    "ok" : 1
}

3)删除集合(删除表)

> show tables
table

#删除集合
> db.table.drop()
true

> show tables

4)删除库

#进入到要删除的库下面
> use database
> db.dropDatabase()
{ "dropped" : "database", "ok" : 1 }

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

二、mongo的工具

mongo            #登录命令
mongod            #进程管理
mongodump        #备份,全备,在备份的时候进行压缩(单纯的备份)
mongorestore    #dump备份的恢复
mongoexport        #备份,支持导出json格式和表格(用作数据分析)
mongoimport        #恢复数据,导入数据
mongos            #集群分片命令
mongostat        #运行状态

1.mongostat运行状态

[root@redis03 ~]# mongostat
insert query update delete getmore command dirty used flushes vsize   res qrw arw net_in net_out conn                time
    *0    *0     *0     *0       0     2|0  0.0% 0.0%       0  974M 44.0M 0|0 1|0   160b   61.7k    3 May 28 10:09:04.579

insert        #每秒插入数据的数量
query        #每秒查询操作的数量
update        #每秒更新数据的数量
delete        #没秒删除操作的数量
getmore        #每秒查询游标时的操作数
command        #每秒执行的命令数
dirty        #脏数据占缓存的多少
used        #使用中的缓存
flushes
            #在 wiredtiger引擎,表示轮询间隔
            #在MMapv1引擎,表示每秒写入磁盘次数
vsize        #虚拟内存使用量
res            #物理内存使用量
qrw            #客户端等待读数据的队列长度
arw            #客户端等待写入数据的队列长度
net_in        #网络进流量
net_out        #网络出流量
conn        #连接总数
time        #时间

三、用户授权认证

1.先创建用户和角色

> use admin
switched to db admin

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

user:用户名
pwd:用户密码
roles:指定用户身份
    role:身份
        常用的身份:read、readwrite、root、backup、clusteradmin
    db:关联的数据库

2.查看用户

> db.getUsers()
[
    {
        "_id" : "admin.admin",
        "userId" : UUID("dc00d586-8cc7-49aa-96a7-fb7d5d27637a"),
        "user" : "admin",
        "db" : "admin",
        "roles" : [
            {
                "role" : "root",
                "db" : "admin"
            }
        ]
    }
]

3.开启用户认证

#停掉服务
[mongo@redis03 ~]$ mongod -f /server/mongodb/27017/conf/mongo.conf --shutdown

#添加配置
[mongo@redis03 ~]$ vim /server/mongodb/27017/conf/mongo.conf
security:
  authorization: enabled

#重启
[mongo@redis03 ~]$ mongod -f /server/mongodb/27017/conf/mongo.conf

4.认证后登录

#操作报错
> show dbs
2020-05-28T10:37:44.142+0800 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "there are no users authenticated",
    "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:860:19
shellHelper@src/mongo/shell/utils.js:750:15
@(shellhelp2):1:1

5.使用用户密码登录

[mongo@redis03 ~]$ mongo -uadmin -p123456
MongoDB shell version v3.6.13
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("2f2c9d64-d1e2-4eee-ab4b-0b63abda9207") }
MongoDB server version: 3.6.13
>

#指定关联数据库登录
[mongo@redis03 ~]$ mongo -uadmin -p123456 --authenticationDatabase admin
MongoDB shell version v3.6.13
connecting to: mongodb://127.0.0.1:27017/?authSource=admin&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("4a00d635-e9fa-4dde-a6e3-5079efbb2757") }
MongoDB server version: 3.6.13
>

#注意:连接Mongodb的时候,除了需要用户名,密码,还需要指定这个用户的认证db。为什么需要指定这个认证db?是因为Mongodb允许存在多个同名的用户存在,但同名的用户认证db必须不能相同

6.创建普通用户

> db.createUser({user:"test",pwd:"123",roles:[{role:"read",db:"read"},{role:"readWrite",db:"write"}]})
Successfully added user: {
    "user" : "test",
    "roles" : [
        {
            "role" : "read",
            "db" : "read"
        },
        {
            "role" : "readWrite",
            "db" : "write"
        }
    ]
}

7.创建数据

> use write
> db.writetable.insert({name:"lhd",age:18})
> db.writetable.insert({name:"lhd",age:18})
> db.writetable.insert({name:"lhd",age:18})
> db.writetable.insert({name:"lhd",age:18})
> db.writetable.insert({name:"lhd",age:18})

> use read
> db.readtable.insert({name:"lhd",age:18})
> db.readtable.insert({name:"lhd",age:18})
> db.readtable.insert({name:"lhd",age:18})
> db.readtable.insert({name:"lhd",age:18})

8.测试用户访问数据

[mongo@redis03 ~]$ mongo -utest -p123 --authenticationDatabase test
> show dbs
2020-05-28T11:08:41.629+0800 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0, lsid: { id: UUID(\"948896d3-7101-4413-9d8c-b7dd954cc0c5\") }, $db: \"admin\" }",
    "code" : 13,
    "codeName" : "Unauthorized"
}

#切换到write库,能读写
> use write
switched to db write
> show tables
writetable
> db.writetable.insert({name:"lhd",age:18})
WriteResult({ "nInserted" : 1 })

#切换到read库,只能读
> use read
switched to db read
> show tables
readtable
> db.readtable.insert({name:"lhd",age:18})
WriteResult({
    "writeError" : {
        "code" : 13,
        "errmsg" : "not authorized on read to execute command { insert: \"readtable\", ordered: true, lsid: { id: UUID(\"948896d3-7101-4413-9d8c-b7dd954cc0c5\") }, $db: \"read\" }"
    }
})

9.修改用户权限

> use test
> db.updateUser("test",{pwd:"123",roles:[{role:"read",db:"read"},{role:"readWrite",db:"write"}]})

10.删除用户

#切换到数据库
> use test
> db.getUsers()

#删除
> db.dropUser('test')
true

四、副本集

1.介绍

https://docs.mongodb.com/manual/replication/

2.创建多实例目录

[root@redis03 ~]# mkdir /server/mongodb/2801{7,8,9}/{conf,logs,pid,data} -p

3.配置多实例

[root@redis03 ~]# cp /server/mongodb/27017/conf/mongo.conf /server/mongodb/28017/conf/
[root@redis03 ~]# vim /server/mongodb/28017/conf/mongo.conf 
systemLog:
  destination: file
  logAppend: true
  path: /server/mongodb/28017/logs/mongodb.log

storage:
  journal:
    enabled: true
  dbPath: /server/mongodb/28017/data
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true

processManagement:
  fork: true
  pidFilePath: /server/mongodb/28017/pid/mongod.pid

net:
  port: 28017
  bindIp: 127.0.0.1,10.0.0.93

replication:
  oplogSizeMB: 1024
  replSetName: dba

#解析
replication:
  #类似于数据库的binlog
  oplogSizeMB: 1024
  #副本集的名字
  replSetName: dba

#第二台第三台
[root@redis03 ~]# cp /server/mongodb/28017/conf/mongo.conf /server/mongodb/28018/conf/
[root@redis03 ~]# cp /server/mongodb/28017/conf/mongo.conf /server/mongodb/28019/conf/
[root@redis03 ~]# sed -i 's#28017#28018#g' /server/mongodb/28018/conf/mongo.conf 
[root@redis03 ~]# sed -i 's#28017#28019#g' /server/mongodb/28019/conf/mongo.conf

4.启动多实例

#授权
[root@redis03 ~]# chown -R mongo.mongo /server/mongodb/

#启动
[mongo@redis03 ~]$ mongod -f /server/mongodb/28017/conf/mongo.conf 
[mongo@redis03 ~]$ mongod -f /server/mongodb/28018/conf/mongo.conf 
[mongo@redis03 ~]$ mongod -f /server/mongodb/28019/conf/mongo.conf

#验证
[mongo@redis03 ~]$ netstat -lntp | grep mongo
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 10.0.0.93:27017         0.0.0.0:*               LISTEN      39333/mongod        
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      39333/mongod        
tcp        0      0 10.0.0.93:28017         0.0.0.0:*               LISTEN      43372/mongod        
tcp        0      0 127.0.0.1:28017         0.0.0.0:*               LISTEN      43372/mongod        
tcp        0      0 10.0.0.93:28018         0.0.0.0:*               LISTEN      43404/mongod        
tcp        0      0 127.0.0.1:28018         0.0.0.0:*               LISTEN      43404/mongod        
tcp        0      0 10.0.0.93:28019         0.0.0.0:*               LISTEN      43435/mongod        
tcp        0      0 127.0.0.1:28019         0.0.0.0:*               LISTEN      43435/mongod

5.登录多实例

[root@redis03 ~]# vim /etc/hosts
10.0.0.93 redis03

[root@redis03 ~]# su - mongo
[mongo@redis03 ~]$ mongo 10.0.0.93:28017
[mongo@redis03 ~]$ mongo 10.0.0.93:28018
[mongo@redis03 ~]$ mongo 10.0.0.93:28019

#其他连接方式
[mongo@redis03 ~]$ mongo localhost:28019
[mongo@redis03 ~]$ mongo 127.0.0.1:28019
[mongo@redis03 ~]$ mongo redis03:28019

#关机方式(只允许使用localhost连接的时候使用)
> use admin
switched to db admin
> db.shutdownServer()

6.初始化副本集(三台都执行)

#设置副本及集
> config={_id:"dba",members:[{_id:0,host:"10.0.0.93:28017"},{_id:1,host:"10.0.0.93:28018"},{_id:2,host:"10.0.0.93:28019"}]}
{
    "_id" : "dba",
    "members" : [
        {
            "_id" : 0,
            "host" : "10.0.0.93:28017"
        },
        {
            "_id" : 1,
            "host" : "10.0.0.93:28018"
        },
        {
            "_id" : 2,
            "host" : "10.0.0.93:28019"
        }
    ]
}

#确定读取副本集
> rs.initiate(config)
{
    "ok" : 1,
    "operationTime" : Timestamp(1590640057, 1),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1590640057, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

7.查看集群状态

dba:PRIMARY> rs.status()
    "members" : [
        {
            #id
            "_id" : 0,
            #host
            "name" : "10.0.0.93:28017",
            #健康状况 1表示正常,0表示故障
            "health" : 1,
            #状态 1表示主库,2表示从库,3表示恢复数据中,7表示仲裁者,8表示down机
            "state" : 2,
            #标注是主库还是从库  SECONDARY是从库  PRIMARY是主库
            "stateStr" : "SECONDARY",
            #心跳检测
            "lastHeartbeat" : ISODate("2020-05-28T04:32:37.759Z"),
            #数据接受时间
            "optimeDate" : ISODate("2020-05-28T04:32:29Z"),
            #从库同步的是谁
            "syncingTo" : "10.0.0.93:28018",

#查看主节点是谁
dba:PRIMARY> rs.isMaster()

#打印从库oplog信息
dba:PRIMARY> rs.printReplicationInfo()
configured oplog size:   1024MB
log length start to end: 892secs (0.25hrs)
oplog first event time:  Thu May 28 2020 12:27:37 GMT+0800 (CST)
oplog last event time:   Thu May 28 2020 12:42:29 GMT+0800 (CST)
now:                     Thu May 28 2020 12:42:29 GMT+0800 (CST)

#查看延时时间
dba:PRIMARY> rs.printSlaveReplicationInfo()
source: 10.0.0.93:28017
    syncedTo: Thu May 28 2020 12:42:59 GMT+0800 (CST)
    10 secs (0 hrs) behind the primary 
source: 10.0.0.93:28019
    syncedTo: Thu May 28 2020 12:42:59 GMT+0800 (CST)
    10 secs (0 hrs) behind the primary

#查看副本集配置文件
dba:PRIMARY> rs.config()
Copyright © 高程程 all right reserved,powered by Gitbook修订于: 2021-05-18 21:14:59

results matching ""

    No results matching ""