一、mongodb副本集
mongodb副本集介绍
mongodb复制原理
副本集实现方式
1、配置mongodb副本集(主机51、52、53)
(1)在所有mongodb服务器主机上启用副本集功能并定义名称
[root@host51 ~]# vim /usr/local/mongodb/etc/mongodb.conf
logpath=/usr/local/mongodb/log/mongodb.log
logappend=true
dbpath=/usr/local/mongodb/data/db
fork=true
bind_ip=192.168.8.51
port=27051
replSet=rs1
(2)配置节点信息(在51主机上配置,则51为主库)
[root@host51 ~]# /usr/local/mongodb/bin/mongo -host 192.168.8.51 -port 27051
...
> config={_id:"rs1",members:[ \
> {_id:0,host:"192.168.8.51:27051"}, \
> {_id:1,host:"192.168.8.52:27052"}, \
> {_id:2,host:"192.168.8.53:27053"} \
> ] \
> } //创建副本集
{
"_id" : "rs1",
"members" : [
{
"_id" : 0,
"host" : "192.168.8.51:27051"
},
{
"_id" : 1,
"host" : "192.168.8.52:27052"
},
{
"_id" : 2,
"host" : "192.168.8.53:27053"
}
]
}
> rs.initiate(config) //初始化副本集
{
"ok" : 1,
"operationTime" : Timestamp(1557052058, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1557052058, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
rs1:OTHER>
rs1:PRIMARY> //primary表示主库
rs1:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
user 0.000GB
userbak 0.000GB
rs1:PRIMARY> use local
switched to db local
rs1:PRIMARY> show tables
me
oplog.rs
replset.election
replset.minvalid
startup_log
system.replset
system.rollback.id
rs1:PRIMARY> db.me.find()
{ "_id" : ObjectId("5cceaba6fca4cf761bb31a78"), "host" : "host51" }
rs1:PRIMARY> rs.isMaster() //查看数据库角色信息
{
"hosts" : [
"192.168.8.51:27051",
"192.168.8.52:27052",
"192.168.8.53:27053"
],
"setName" : "rs1",
"setVersion" : 1,
"ismaster" : true, //表明本机是主库
"secondary" : false,
...
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
config={_id:"rs1",members: \ //创建副本集时可以设置各节点优先级
[ \
{_id:0,host:"192.168.8.51:27051",priority:10} //设置优先级10
{_id:1,host:"192.168.8.52:27052",priority:10} //设置优先级10
{_id:2,host:"192.168.8.53:27053",priority:12} //设置优先级12,当主库宕机时,优先级高的节点主动升级为主库
]
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
(3)查看从库配置情况
[root@host52 ~]# /usr/local/mongodb/bin/mongo -host 192.168.8.52 -port 27052
rs1:SECONDARY> db.getMongo().setSlaveOk() //设置从库执行查询命令
rs1:SECONDARY> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
user 0.000GB
userbak 0.000GB
rs1:SECONDARY> rs.isMaster()
{
"hosts" : [
"192.168.8.51:27051",
"192.168.8.52:27052",
"192.168.8.53:27053"
],
"setName" : "rs1",
"setVersion" : 1,
"ismaster" : false,
"secondary" : true, //表明本机是从库
...
++++++++++++++++++++++++++++++++++++++++++++++++++
副本集配置失败排错思路:
1、关闭mongodb主配置文件mongodb.conf集群配置项
#replSet=集群名称
2、重启mongodb服务,登录并删除local库
3、启用mongodb主配置文件mongodb.conf的集群配置项
replSet=集群名称
4、重启mongodb服务,登录并重新配置集群
++++++++++++++++++++++++++++++++++++++++++++++++++
(4)测试从库同步复制
[root@host50 ~]# /usr/local/mongodb/bin/mongo -host 192.168.8.51 -port 27051 客户端50主机登录主库51主机写入数据
rs1:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
user 0.000GB
userbak 0.000GB
rs1:PRIMARY> use db15
switched to db db15
rs1:PRIMARY> db.t1.save({name:"bob",age:26,sex:"boy"})
WriteResult({ "nInserted" : 1 })
rs1:PRIMARY> db.t1.save({name:"bob",age:26,sex:"boy"})
WriteResult({ "nInserted" : 1 })
rs1:PRIMARY> db.t1.save({name:"bob",age:26,sex:"boy"})
WriteResult({ "nInserted" : 1 })
rs1:PRIMARY> db.t1.find()
{ "_id" : ObjectId("5ccf5db1c99c1868d4246ead"), "name" : "bob", "age" : 26, "sex" : "boy" }
{ "_id" : ObjectId("5ccf5db4c99c1868d4246eae"), "name" : "bob", "age" : 26, "sex" : "boy" }
{ "_id" : ObjectId("5ccf5db5c99c1868d4246eaf"), "name" : "bob", "age" : 26, "sex" : "boy" }
[root@host52 ~]# /usr/local/mongodb/bin/mongo -host 192.168.8.52 -port 27052 //查看从库同步情况
rs1:SECONDARY> db.getMongo().setSlaveOk()
rs1:SECONDARY> show dbs
admin 0.000GB
config 0.000GB
db15 0.000GB
local 0.000GB
user 0.000GB
userbak 0.000GB
rs1:SECONDARY> use db15
switched to db db15
rs1:SECONDARY> show tables
t1
rs1:SECONDARY> db.t1.find()
{ "_id" : ObjectId("5ccf5db1c99c1868d4246ead"), "name" : "bob", "age" : 26, "sex" : "boy" }
{ "_id" : ObjectId("5ccf5db4c99c1868d4246eae"), "name" : "bob", "age" : 26, "sex" : "boy" }
{ "_id" : ObjectId("5ccf5db5c99c1868d4246eaf"), "name" : "bob", "age" : 26, "sex" : "boy" }
(5)测试高可用
[root[root@host51 ~]# mstop //关闭51主库mongodb服务(mstop为定义的别名)
killing process with pid: 16504
[root@host52 ~]# /usr/local/mongodb/bin/mongo -host 192.168.8.52 -port 27052
...
rs1:PRIMARY> db.isMaster()
{
"hosts" : [
"192.168.8.51:27051",
"192.168.8.52:27052",
"192.168.8.53:27053"
],
"setName" : "rs1",
"setVersion" : 1,
"ismaster" : true, //52主机升级为主库
"secondary" : false,
"primary" : "192.168.8.52:27052",
"me" : "192.168.8.52:27052",
...
(6)测试故障自动恢复
[root@host51 ~]# mstart //重启51主机mongodb服务(mstart为定义的别名)
[root@host51 ~]# /usr/local/mongodb/bin/mongo -host 192.168.8.51 -port 27051
...
rs1:SECONDARY> db.isMaster()
{
"hosts" : [
"192.168.8.51:27051",
"192.168.8.52:27052",
"192.168.8.53:27053"
],
"setName" : "rs1",
"setVersion" : 1,
"ismaster" : false,
"secondary" : true, //51主机恢复后自动成为从库
"primary" : "192.168.8.52:27052",
"me" : "192.168.8.51:27051"
...
2、文档管理
更新文档
示例:
[root@host50 ~]# /usr/local/mongodb/bin/mongo -host 192.168.8.50 -port 27050
...
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
user 0.000GB
userb 0.000GB
> use userb
switched to db userb
> show tables
userb
#查询
> db.userb.find()
{ "_id" : ObjectId("5ccf0305c638f7fde11ca32c"), "name" : "root", "passwd" : "x", "uid" : 0, "gid" : 0, "comment" : "root", "home" : "/root", "shell" : "/bin/bash" }
{ "_id" : ObjectId("5ccf0305c638f7fde11ca32e"), "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "home" : "/sbin", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5ccf0305c638f7fde11ca32f"), "name" : "adm", "passwd" : "x", "uid" : 3, "gid" : 4, "comment" : "adm", "home" : "/var/adm", "shell" : "/sbin/nologin" }
...
#统计
> db.userb.count()
22
> db.userb.find({shell:"/sbin/nologin"}).count()
16
#按匹配条件查询
> db.userb.find({shell:"/sbin/nologin"})
{ "_id" : ObjectId("5ccf0305c638f7fde11ca32e"), "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "home" : "/sbin", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5ccf0305c638f7fde11ca32f"), "name" : "adm", "passwd" : "x", "uid" : 3, "gid" : 4, "comment" : "adm", "home" : "/var/adm", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5ccf0305c638f7fde11ca330"), "name" : "lp", "passwd" : "x", "uid" : 4, "gid" : 7, "comment" : "lp", "home" : "/var/spool/lpd", "shell" : "/sbin/nologin" }
...
#逻辑与查询
> db.userb.find({name:"sync",uid:5},{_id:0,name:1,uid:1})
{ "name" : "sync", "uid" : 5 }
#逻辑或查询
> db.userb.find({$or:[{uid:8},{uid:7},{name:"sync"}]},{_id:0,name:1,uid:1})
{ "name" : "sync", "uid" : 5 }
{ "name" : "halt", "uid" : 7 }
{ "name" : "mail", "uid" : 8 }
#范围内查询
> db.userb.find({uid:{$in:[5,6,8]}},{_id:0,name:1,uid:1})
{ "name" : "sync", "uid" : 5 }
{ "name" : "shutdown", "uid" : 6 }
{ "name" : "mail", "uid" : 8 }
#数值比较查询
> db.userb.find({uid:{$gte:100}},{_id:0,name:1,uid:1})
{ "name" : "student", "uid" : 1000 }
{ "name" : "systemd-network", "uid" : 192 }
{ "name" : "polkitd", "uid" : 999 }
{ "name" : "chrony", "uid" : 998 }
> db.userb.find({uid:{$gte:100,$lt:1000}},{_id:0,name:1,uid:1})
{ "name" : "systemd-network", "uid" : 192 }
{ "name" : "polkitd", "uid" : 999 }
{ "name" : "chrony", "uid" : 998 }
#正则匹配查询
> db.userb.find({name:/^a/},{_id:0,name:1,uid:1})
{ "name" : "adm", "uid" : 3 }
{ "name" : "apache", "uid" : 48 }
#null空值查询
> db.userb.find({name:null},{_id:0,name:1,uid:1})
{ "name" : null, "uid" : 120 }
#按匹配条件查询,只显示相应字段
> db.userb.find({shell:"/sbin/nologin"},{_id:0,name:1,shell:1})
{ "name" : "daemon", "shell" : "/sbin/nologin" }
{ "name" : "adm", "shell" : "/sbin/nologin" }
{ "name" : "lp", "shell" : "/sbin/nologin" }
{ "name" : "mail", "shell" : "/sbin/nologin" }
...
#按匹配条件查询,只显示前几行
> db.userb.find({},{_id:0,name:1,uid:1,shell:1}).limit(5)
{ "name" : "root", "uid" : 0, "shell" : "/bin/bash" }
{ "name" : "daemon", "uid" : 2, "shell" : "/sbin/nologin" }
{ "name" : "adm", "uid" : 3, "shell" : "/sbin/nologin" }
{ "name" : "lp", "uid" : 4, "shell" : "/sbin/nologin" }
{ "name" : "sync", "uid" : 5, "shell" : "/bin/sync" }
#按匹配条件查询,跳过前几行显示
> db.userb.find({},{_id:0,name:1,uid:1,shell:1}).skip(5)
{ "name" : "shutdown", "uid" : 6, "shell" : "/sbin/shutdown" }
{ "name" : "halt", "uid" : 7, "shell" : "/sbin/halt" }
{ "name" : "mail", "uid" : 8, "shell" : "/sbin/nologin" }
{ "name" : "operator", "uid" : 11, "shell" : "/sbin/nologin" }
...
#按匹配条件查询,升序显示
> db.userb.find({},{_id:0,name:1,uid:1,shell:1}).sort({uid:1}) //按uid号升序显示
{ "name" : "root", "uid" : 0, "shell" : "/bin/bash" }
{ "name" : "bin", "uid" : 1, "shell" : "/sbin/nologin" }
{ "name" : "daemon", "uid" : 2, "shell" : "/sbin/nologin" }
{ "name" : "adm", "uid" : 3, "shell" : "/sbin/nologin" }
{ "name" : "lp", "uid" : 4, "shell" : "/sbin/nologin" }
{ "name" : "sync", "uid" : 5, "shell" : "/bin/sync" }
...
#按匹配条件查询,降序显示
> db.userb.find({},{_id:0,name:1,uid:1,shell:1}).sort({uid:-1}) //按uid号降序显示
{ "name" : "student", "uid" : 1000, "shell" : "/bin/bash" }
{ "name" : "polkitd", "uid" : 999, "shell" : "/sbin/nologin" }
{ "name" : "chrony", "uid" : 998, "shell" : "/sbin/nologin" }
{ "name" : "systemd-network", "uid" : 192, "shell" : "/sbin/nologin" }
{ "name" : "nobody", "uid" : 99, "shell" : "/sbin/nologin" }
{ "name" : "postfix", "uid" : 89, "shell" : "/sbin/nologin" }
...
#使用save命令插入数据
> db.t1.save({_id:1,name:"bob",age:26})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 1 })
> db.t1.find()
{ "_id" : 1, "name" : "bob", "age" : 26 }
> db.t1.save({_id:1,name:"tom",age:26}) //_id值存在时,修改键值
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.t1.find()
{ "_id" : 1, "name" : "tom", "age" : 26 }
#使用insert命令插入数据
> db.t1.insert({_id:1,name:"tom",age:26}) //_id值存在时,插入失败
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: userb.t1 index: _id_ dup key: { : 1.0 }"
}
})
> db.t1.insert({_id:2,name:"tom",age:26}) //_id值不存在时,插入成功
WriteResult({ "nInserted" : 1 })
> db.t1.find()
{ "_id" : 1, "name" : "tom", "age" : 26 }
{ "_id" : 2, "name" : "tom", "age" : 26 }
#同时插入多条记录
> db.t1.insertMany([{_id:3,name:"jim",age:26},{_id:4,name:"lili",age:22}])
{ "acknowledged" : true, "insertedIds" : [ 3, 4 ] }
> db.t1.find()
{ "_id" : 1, "name" : "tom", "age" : 26 }
{ "_id" : 2, "name" : "tom", "age" : 26 }
{ "_id" : 3, "name" : "jim", "age" : 26 }
{ "_id" : 4, "name" : "lili", "age" : 22 }
#使用$set更新指定字段值
> db.userb.update({shell:"/sbin/nologin"},{$set:{gid:1001,comment:"student"}},false,true) //更新与条件(shell:"/sbin/nologin")匹配的行,修改所有匹配行的gid和comment
WriteResult({ "nMatched" : 16, "nUpserted" : 0, "nModified" : 16 })
> db.userb.find()
{ "_id" : ObjectId("5ccf0305c638f7fde11ca32c"), "name" : "root", "passwd" : "x", "uid" : 0, "gid" : 0, "comment" : "root", "home" : "/root", "shell" : "/bin/bash" }
{ "_id" : ObjectId("5ccf0305c638f7fde11ca32e"), "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 1001, "comment" : "student", "home" : "/sbin", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5ccf0305c638f7fde11ca32f"), "name" : "adm", "passwd" : "x", "uid" : 3, "gid" : 1001, "comment" : "student", "home" : "/var/adm", "shell" : "/sbin/nologin" }
> db.userb.find({uid:2},{_id:0})
{ "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 1001, "comment" : "student", "home" : "/sbin", "shell" : "/sbin/nologin" }
#使用$unset删除指定字段
> db.userb.update({uid:2},{$unset:{comment:"student"}},false,true)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.userb.find({uid:2},{_id:0})
{ "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 1001, "home" : "/sbin", "shell" : "/sbin/nologin" }
#字段值自加自减
> db.userb.find({uid:{$lte:100}},{_id:0,name:1,uid:1}).limit(3)
{ "name" : "root", "uid" : 0 }
{ "name" : "mysql", "uid" : 27 }
{ "name" : "bin", "uid" : 1 }
> db.userb.update({uid:{$lte:100}},{$inc:{uid:+2}},false,true) //匹配行uid自加2
WriteResult({ "nMatched" : 18, "nUpserted" : 0, "nModified" : 18 })
> db.userb.find({uid:{$lte:100}},{_id:0,name:1,uid:1})
{ "name" : "root", "uid" : 2 }
{ "name" : "mysql", "uid" : 29 }
{ "name" : "bin", "uid" : 3 }
{ "name" : "daemon", "uid" : 4 }
> db.userb.update({uid:{$lte:100}},{$inc:{uid:-2}},false,true) //匹配行uid自减2
WriteResult({ "nMatched" : 17, "nUpserted" : 0, "nModified" : 17 })
> db.userb.find({uid:{$lte:100}},{_id:0,name:1,uid:1})
{ "name" : "root", "uid" : 0 }
{ "name" : "mysql", "uid" : 27 }
{ "name" : "bin", "uid" : 1 }
{ "name" : "daemon", "uid" : 2 }
#字段值push增、pull删、addToset增(不可重复)
> db.t3.save({name:"jim",likes:["a","b","c","d","e"]})
WriteResult({ "nInserted" : 1 })
> db.t3.find()
{ "_id" : ObjectId("5cd02563ad808c7a4c5dcf91"), "name" : "jim", "likes" : [ "a", "b", "c", "d", "e" ] }
> db.t3.update({name:"jim"},{$push:{likes:"food"}}) //增加数组字段值,可重复追加
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.t3.find({},{_id:0,name:1,likes:1})
{ "name" : "jim", "likes" : [ "a", "b", "c", "d", "e", "food" ] }
> db.t3.update({name:"jim"},{$addToSet:{likes:"game"}}) //增加数组字段值,不可重复追加
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.t3.find({},{_id:0,name:1,likes:1})
{ "name" : "jim", "likes" : [ "a", "b", "c", "d", "e", "food", "game" ] }
> db.t3.update({name:"jim"},{$pull:{likes:"game"}}) //删除数组指定字段值
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.t3.find({},{_id:0,name:1,likes:1})
{ "name" : "jim", "likes" : [ "a", "b", "c", "d", "e", "food" ] }