本文共 25023 字,大约阅读时间需要 83 分钟。
上一篇文章练习了,MongoDB 的以下操作
接下来继续
MongoDB Limit() 方法
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
插入测试数据
db.col.insert({title: 'MongoDB-1'})db.col.insert({title: 'MongoDB-2'})db.col.insert({title: 'MongoDB-3'})db.col.insert({title: 'MongoDB-4'})
MongoDB Enterprise > db.col.find(){ "_id" : ObjectId("5a6e8eaef14a3f270ba2dd0c"), "title" : "MongoDB-1" }{ "_id" : ObjectId("5a6e8ec8f14a3f270ba2dd0d"), "title" : "MongoDB-2" }{ "_id" : ObjectId("5a6e8ecbf14a3f270ba2dd0e"), "title" : "MongoDB-3" }{ "_id" : ObjectId("5a6e8ed5f14a3f270ba2dd0f"), "title" : "MongoDB-4" }MongoDB Enterprise >
语法
limit()方法基本语法如下所示:
> db.COLLECTION_NAME.find().limit(NUMBER)
以上实例为显示查询文档中的两条记录:
MongoDB Enterprise > db.col.find().limit(2){ "_id" : ObjectId("5a6e8eaef14a3f270ba2dd0c"), "title" : "MongoDB-1" }{ "_id" : ObjectId("5a6e8ec8f14a3f270ba2dd0d"), "title" : "MongoDB-2" }MongoDB Enterprise > db.col.find({},{"title":1,_id:0}).limit(2){ "title" : "MongoDB-1" }{ "title" : "MongoDB-2" }MongoDB Enterprise >
注:如果你们没有指定limit()方法中的参数则显示集合中的所有数据。
MongoDB Enterprise > db.col.find({},{"title":1,_id:0}).limit(){ "title" : "MongoDB-1" }{ "title" : "MongoDB-2" }{ "title" : "MongoDB-3" }{ "title" : "MongoDB-4" }
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
语法skip() 方法脚本语法格式如下:
> db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
实例
以上实例只会显示第二条文档数据
MongoDB Enterprise > db.col.find({},{"title":1,_id:0}).limit(1).skip(1){ "title" : "MongoDB-2" }MongoDB Enterprise >
注:skip()方法默认参数为 0
在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段
使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
语法
sort()方法基本语法如下所示:
> db.COLLECTION_NAME.find().sort({KEY:1})
col 集合中的数据如下:
MongoDB Enterprise > db.col.find(){ "_id" : ObjectId("5a6e8eaef14a3f270ba2dd0c"), "title" : "MongoDB-1" }{ "_id" : ObjectId("5a6e8ec8f14a3f270ba2dd0d"), "title" : "MongoDB-2" }{ "_id" : ObjectId("5a6e8ecbf14a3f270ba2dd0e"), "title" : "MongoDB-3" }{ "_id" : ObjectId("5a6e8ed5f14a3f270ba2dd0f"), "title" : "MongoDB-4" }MongoDB Enterprise >
其中 1 为升序排列,而-1是用于降序排列
以下实例演示了 col 集合中的数据按字段 title 的降序排列:
MongoDB Enterprise > db.col.find({},{"title":1,_id:0}).sort({"title":-1}){ "title" : "MongoDB-4" }{ "title" : "MongoDB-3" }{ "title" : "MongoDB-2" }{ "title" : "MongoDB-1" }MongoDB Enterprise >
注: 如果没有指定sort()方法的排序方式,默认按照文档的升序排列。
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
MongoDB使用 ensureIndex() 方法来创建索引。
语法
ensureIndex()方法基本语法格式如下所示:
> db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
实例
> db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
实例
MongoDB Enterprise > db.col.ensureIndex({"title":1}){ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1}MongoDB Enterprise >
db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '搜云库教程-专注于开发技术的研究与知识分享', url: 'http://www.souyunku.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100})
ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
MongoDB Enterprise > db.col.ensureIndex({"title":1,"description":1}){ "createdCollectionAutomatically" : false, "numIndexesBefore" : 3, "numIndexesAfter" : 4, "ok" : 1}
ensureIndex() 接收可选参数,可选参数列表如下:
实例
在后台创建索引:
建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。
MongoDB Enterprise > db.col.ensureIndex({"url":1}, {background: true}){ "createdCollectionAutomatically" : false, "numIndexesBefore" : 5, "numIndexesAfter" : 6, "ok" : 1}MongoDB Enterprise >
MongoDB 聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。
删除之前的测试数据
MongoDB Enterprise > db.col.remove({})WriteResult({ "nRemoved" : 5 })MongoDB Enterprise >
插入新的测试数据
db.col.insert({ title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by_user: 'penglei', url: 'http://www.souyunku.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100})db.col.insert({ title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by_user: 'penglei', url: 'http://www.souyunku.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 200})db.col.insert({ title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by_user: 'penglei', url: 'http://www.souyunku.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 300})
MongoDB Enterprise > db.col.find(){ "_id" : ObjectId("5a6ebfab5326a260464a4072"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by_user" : "penglei", "url" : "http://www.souyunku.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }{ "_id" : ObjectId("5a6ebfab5326a260464a4073"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by_user" : "penglei", "url" : "http://www.souyunku.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 200 }{ "_id" : ObjectId("5a6ebfab5326a260464a4074"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by_user" : "penglei", "url" : "http://www.souyunku.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 300 }MongoDB Enterprise >
MongoDB中聚合的方法使用aggregate()。
语法
aggregate() 方法的基本语法格式如下所示:
> db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
MongoDB Enterprise > db.col.aggregate([{$group : {_id : "$by_user", num_tutorials : {$sum : 1}}}]){ "_id": "penglei", "num_tutorials": 3}MongoDB Enterprise > db.col.aggregate([{$group : {_id : "$by_user", totle : {$sum : 1}}}]){ "_id": "penglei", "totle": 3}MongoDB Enterprise >
以上实例类似sql语句:select by_user, count(*) from col group by by_user
在上面的例子中,我们通过字段by_user字段对数据进行分组,并计算by_user字段相同值的总和。
下表展示了一些聚合的表达式:
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
1、$project实例
MongoDB Enterprise > db.col.aggregate( { $project : { title : 1 , by_user : 1 , }} ); { "_id" : ObjectId("5a6ebfab5326a260464a4072"), "title" : "MongoDB 教程", "by_user" : "penglei" }{ "_id" : ObjectId("5a6ebfab5326a260464a4073"), "title" : "MongoDB 教程", "by_user" : "penglei" }{ "_id" : ObjectId("5a6ebfab5326a260464a4074"), "title" : "MongoDB 教程", "by_user" : "penglei" }MongoDB Enterprise >
这样的话结果中就只还有_id,tilte和by_user三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:
MongoDB Enterprise > db.col.aggregate( { $project : { _id : 0 , title : 1 , by_user : 1 }});
{ "title" : "MongoDB 教程", "by_user" : "penglei" }{ "title" : "MongoDB 教程", "by_user" : "penglei" }{ "title" : "MongoDB 教程", "by_user" : "penglei" }
2.$match实例
db.col.aggregate( [ { $match : { likes : { $gt : 90, $lte : 200 } } }, { $group: { _id: null, count: { $sum: 1 } } } ] );
$match用于获取 likes 大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。
MongoDB Enterprise > db.col.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]){ "_id" : "penglei", "num_tutorial" : 3 }MongoDB Enterprise >
以上实例类似sql语句:
select by_user as _id, count(*) as num_tutorial from mycol group by by_user
按日、按月、按年、按周、按小时、按分钟聚合操作如下:
db.getCollection('m_msg_tb').aggregate([ {$match:{m_id:10001,mark_time:{$gt:new Date(2017,8,0)}}}, {$group: { _id: {$dayOfMonth:'$mark_time'}, pv: {$sum: 1} } }, {$sort: {"_id": 1}}])
时间关键字如下:
MongoDB复制是将数据同步在多个服务器的过程。
复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
复制还允许您从硬件故障和服务中断中恢复数据。
官方文档
mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
mongodb各个节点常见的搭配方式为:一主一从、一主多从。
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
MongoDB复制结构图如下所示:
以上结构图中,客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。
1、关闭正在运行的MongoDB服务器。
service mongod stop
2.节点建点
首先需要去你选择的mongodb数据文件存放的文件夹新建三个数据库,用来模拟三台不通的机器,博主的路径如下
mkdir -p /data/db/node1mkdir -p /data/db/node2mkdir -p /data/db/node3
3.启动三个数据库(dbpath),并且端口(--port 1000x),集群名称(--replSet gabriel),关闭日志选项(--nojournal),守护进程方式启动,会自动拉起(--fork),日志目录(--logpath)
mongod --dbpath /data/db/node1 --port 10001 --replSet gabriel --nojournal --fork --logpath /data/db/node1.logmongod --dbpath /data/db/node2 --port 10002 --replSet gabriel --nojournal --fork --logpath /data/db/node2.logmongod --dbpath /data/db/node3 --port 10003 --replSet gabriel --nojournal --fork --logpath /data/db/node3.log
4.顺便连接一个服务器,做初始化操作,这里博主连入10001端口
终端下进入
mongo localhost:10001
进入后输入初始化方法
MongoDB Enterprise gabriel:OTHER> rs.initiate({_id:"gabriel",members:[{_id:1,host:"localhost:10001"},{_id:2,host:"localhost:10002"},{_id:3,host:"localhost:10003"},]})
收到如下信息就成功了。
{ "ok" : 1, "operationTime" : Timestamp(1517221411, 1), "$clusterTime" : { "clusterTime" : Timestamp(1517221411, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }}MongoDB Enterprise gabriel:OTHER>
此时会发现终端上的输出已经有了变化。
//从单个一个>//变成了gabriel:OTHER>
5.查询状态
MongoDB Enterprise gabriel:OTHER> rs.status(){ "set" : "gabriel", "date" : ISODate("2018-01-29T10:33:21.227Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1517221984, 1), "t" : NumberLong(1) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1517221984, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1517221994, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1517221994, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 1, "name" : "localhost:10001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 659, "optime" : { "ts" : Timestamp(1517221994, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-01-29T10:33:14Z"), "electionTime" : Timestamp(1517221422, 1), "electionDate" : ISODate("2018-01-29T10:23:42Z"), "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "localhost:10002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 589, "optime" : { "ts" : Timestamp(1517221994, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1517221984, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-01-29T10:33:14Z"), "optimeDurableDate" : ISODate("2018-01-29T10:33:04Z"), "lastHeartbeat" : ISODate("2018-01-29T10:33:20.972Z"), "lastHeartbeatRecv" : ISODate("2018-01-29T10:33:19.923Z"), "pingMs" : NumberLong(0), "syncingTo" : "localhost:10001", "configVersion" : 1 }, { "_id" : 3, "name" : "localhost:10003", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 589, "optime" : { "ts" : Timestamp(1517221994, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1517221984, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-01-29T10:33:14Z"), "optimeDurableDate" : ISODate("2018-01-29T10:33:04Z"), "lastHeartbeat" : ISODate("2018-01-29T10:33:20.972Z"), "lastHeartbeatRecv" : ISODate("2018-01-29T10:33:19.921Z"), "pingMs" : NumberLong(0), "syncingTo" : "localhost:10001", "configVersion" : 1 } ], "ok" : 1, "operationTime" : Timestamp(1517221994, 1), "$clusterTime" : { "clusterTime" : Timestamp(1517221994, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }}
在返回中,参数set后面为集群名称,每个members下面可以看到他们各自的情况,其中stateStr是角色,主节点为(PRIMARY)。
6.进入主节点插入数据,进入从节点查看数据
博主主节点在10001接口
mongo localhost:10001
插入数据
MongoDB Enterprise gabriel:PRIMARY> use testswitched to db test
db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '搜云库教程-专注于开发技术的研究与知识分享', url: 'http://www.souyunku.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100})
MongoDB Enterprise gabriel:PRIMARY> db.col.find(){ "_id" : ObjectId("5a6ef998525d903d07a00cdf"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "搜云库教程-专注于开发技术的研究与知识分享", "url" : "http://www.souyunku.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }MongoDB Enterprise gabriel:PRIMARY>
博主切换从节点10002
mongo localhost:10002
切换到从节点,你会发现使用show dbs 会报错,是因为还没有开启权限,输入rs.slaveOk();就可以顺利访问了。
MongoDB Enterprise gabriel:SECONDARY> show dbs2018-01-29T10:40:37.362+0000 E QUERY [thread1] Error: listDatabases failed:{ "operationTime" : Timestamp(1517222434, 1), "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk", "$clusterTime" : { "clusterTime" : Timestamp(1517222434, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }} :_getErrorWithCode@src/mongo/shell/utils.js:25:13Mongo.prototype.getDBs@src/mongo/shell/mongo.js:65:1shellHelper.show@src/mongo/shell/utils.js:813:19shellHelper@src/mongo/shell/utils.js:703:15@(shellhelp2):1:1MongoDB Enterprise gabriel:SECONDARY>
MongoDB Enterprise gabriel:SECONDARY> rs.slaveOk()
再次查看
MongoDB Enterprise gabriel:SECONDARY> show dbsadmin 0.000GBconfig 0.000GBlocal 0.000GBtest 0.000GBMongoDB Enterprise gabriel:SECONDARY>
切到test 库,查看数据已经同步过来了
MongoDB Enterprise gabriel:SECONDARY> use testswitched to db testMongoDB Enterprise gabriel:SECONDARY> db.col.find(){ "_id" : ObjectId("5a6ef998525d903d07a00cdf"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "搜云库教程-专注于开发技术的研究与知识分享", "url" : "http://www.souyunku.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }MongoDB Enterprise gabriel:SECONDARY>
以上就是简单的主从复制建立过程,现在已经可以在从服务器看到主服务器插入的数据了。
切换从节点10003 一样的问题
删除从节点
rs.remove('ip:port')
关闭主服务器后,再重新启动,会发现原来的从服务器变为了从服务器,新启动的服务器(原来的从服务器)变为了从服务器
首先通过 rs.status()
查看,可以看到主节点是10001,主节点"name" : "localhost:10001", "stateStr" : "PRIMARY"
接下来停止 10001 主节点,测试故障切换
MongoDB Enterprise gabriel:PRIMARY> rs.status(){ "set" : "gabriel", "date" : ISODate("2018-01-30T02:39:58.468Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1517279986, 1), "t" : NumberLong(1) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1517279986, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1517279996, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1517279996, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 1, "name" : "localhost:10001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 58656, "optime" : { "ts" : Timestamp(1517279996, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-01-30T02:39:56Z"), "electionTime" : Timestamp(1517221422, 1), "electionDate" : ISODate("2018-01-29T10:23:42Z"), "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "localhost:10002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 58586, "optime" : { "ts" : Timestamp(1517279996, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1517279986, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-01-30T02:39:56Z"), "optimeDurableDate" : ISODate("2018-01-30T02:39:46Z"), "lastHeartbeat" : ISODate("2018-01-30T02:39:58.289Z"), "lastHeartbeatRecv" : ISODate("2018-01-30T02:39:57.220Z"), "pingMs" : NumberLong(0), "syncingTo" : "localhost:10001", "configVersion" : 1 }, { "_id" : 3, "name" : "localhost:10003", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2018-01-30T02:39:58.304Z"), "lastHeartbeatRecv" : ISODate("2018-01-30T02:39:21.208Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 } ], "ok" : 1, "operationTime" : Timestamp(1517279996, 1), "$clusterTime" : { "clusterTime" : Timestamp(1517279996, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }}MongoDB Enterprise gabriel:PRIMARY>
连接到主节点
mongo localhost:10001
关闭主节点
mongo localhost:10001
显示所有数据库
MongoDB Enterprise gabriel:PRIMARY> show dbsadmin 0.000GBconfig 0.000GBlocal 0.000GBtest 0.000GB
切换到admin
MongoDB Enterprise gabriel:PRIMARY> use adminswitched to db admin
停止数据库,必须进入 admin 库
MongoDB Enterprise gabriel:PRIMARY> db.shutdownServer()
响应
2018-01-30T02:51:34.503+0000 I NETWORK [thread1] trying reconnect to localhost:10001 (127.0.0.1) failed2018-01-30T02:51:35.398+0000 I NETWORK [thread1] Socket recv() Connection reset by peer 127.0.0.1:100012018-01-30T02:51:35.398+0000 I NETWORK [thread1] SocketException: remote: (NONE):0 error: SocketException socket exception [RECV_ERROR] server [127.0.0.1:10001] 2018-01-30T02:51:35.399+0000 I NETWORK [thread1] reconnect localhost:10001 (127.0.0.1) failed failed 2018-01-30T02:51:35.404+0000 I NETWORK [thread1] trying reconnect to localhost:10001 (127.0.0.1) failed2018-01-30T02:51:35.404+0000 W NETWORK [thread1] Failed to connect to 127.0.0.1:10001, in(checking socket for error after poll), reason: Connection refused2018-01-30T02:51:35.404+0000 I NETWORK [thread1] reconnect localhost:10001 (127.0.0.1) failed failed MongoDB Enterprise >
查看是否真的停止了,发现已经没有10001 节点进程了
root@souyunku-2:# ps -ef | grep mongoroot 5554 1 0 Jan29 ? 00:03:34 mongod --dbpath /data/db/node2 --port 10002 --replSet gabriel --nojournal --fork --logpath /data/db/node2.logroot 12284 1 0 02:43 ? 00:00:02 mongod --dbpath /data/db/node3 --port 10003 --replSet gabriel --nojournal --fork --logpath /data/db/node3.logroot 12436 5132 0 02:53 pts/1 00:00:00 grep --color=auto mongoroot@souyunku-2:# netstat -nltpActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program nametcp 0 0 127.0.0.1:10002 0.0.0.0:* LISTEN 5554/mongod tcp 0 0 127.0.0.1:10003 0.0.0.0:* LISTEN 12284/mongod root@souyunku-2:/data/db#
查看是否故障专业
root@souyunku-2:# mongo localhost:10001
查看主从状态
MongoDB Enterprise gabriel:SECONDARY> rs.status(){ "set" : "gabriel", "date" : ISODate("2018-01-30T02:56:48.074Z"), "myState" : 2, "term" : NumberLong(2), "syncingTo" : "localhost:10003", "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1517280995, 1), "t" : NumberLong(2) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1517280995, 1), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1517281005, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1517280995, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 1, "name" : "localhost:10001", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2018-01-30T02:56:47.605Z"), "lastHeartbeatRecv" : ISODate("2018-01-30T02:51:34.519Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 2, "name" : "localhost:10002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 59660, "optime" : { "ts" : Timestamp(1517281005, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2018-01-30T02:56:45Z"), "syncingTo" : "localhost:10003", "configVersion" : 1, "self" : true }, { "_id" : 3, "name" : "localhost:10003", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 784, "optime" : { "ts" : Timestamp(1517281005, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1517281005, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2018-01-30T02:56:45Z"), "optimeDurableDate" : ISODate("2018-01-30T02:56:45Z"), "lastHeartbeat" : ISODate("2018-01-30T02:56:46.486Z"), "lastHeartbeatRecv" : ISODate("2018-01-30T02:56:47.147Z"), "pingMs" : NumberLong(0), "electionTime" : Timestamp(1517280703, 1), "electionDate" : ISODate("2018-01-30T02:51:43Z"), "configVersion" : 1 } ], "ok" : 1, "operationTime" : Timestamp(1517281005, 1), "$clusterTime" : { "clusterTime" : Timestamp(1517281005, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }}MongoDB Enterprise gabriel:SECONDARY>
发现 "name" : "localhost:10001","stateStr" : "(not reachable/healthy)", 健康状态已经是“无法访问状态了”
主节点已经切换成 10003 节点了
"_id" : 3,"name" : "localhost:10003","health" : 1,"state" : 1,"stateStr" : "PRIMARY",
重启节点10001
mongod --dbpath /data/db/node1 --port 10001 --replSet gabriel --nojournal --fork --logpath /data/db/node1.log
参考:
Runoob 教程:
Tutorials 教程:Point MongoDB 官网地址: MongoDB 官方英文文档: MongoDB 各平台下载地址: MongoDB 安装