天天看點

mongodb三節點同時建立副本集出現的bug

節點一:10.4.4.4:27017

節點二:10.4.4.5:27017

節點三:10.4.4.6:27017

建立三個節點組成的副本集,竟然産生以下結果:

./mongo 10.4.4.4:27017

檢視rs

rs.status()

{

        "set" : "mongodb_set",

        "date" : ISODate("2014-04-04T06:44:10Z"),

        "myState" : 1,

        "members" : [

                {

                        "_id" : 0,

                        "name" : "10.4.4.4:27017",

                        "health" : 1,

                        "state" : 1,

                        "stateStr" : "PRIMARY",

                        "uptime" : 903,

                        "optime" : Timestamp(1396592962, 1),

                        "optimeDate" : ISODate("2014-04-04T06:29:22Z"),

                        "self" : true

                },

                {

                        "_id" : 1,

                        "name" : "10.4.4.5:27017",

                        "health" : 1,

                        "state" : 1,

                        "stateStr" : "PRIMARY",

                        "uptime" : 883,

                        "optime" : Timestamp(1396593341, 1416),

                        "optimeDate" : ISODate("2014-04-04T06:35:41Z"),

                        "lastHeartbeat" : ISODate("2014-04-04T06:44:09Z"),

                        "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),

                        "pingMs" : 0

                }

        ],

        "ok" : 1

}

這個狀态之一存在,直到關閉目前連接配接。

./mongo 10.4.4.5:27017

檢視rs

rs.status()

{

        "set" : "mongodb_set",

        "date" : ISODate("2014-04-04T06:43:45Z"),

        "myState" : 1,

        "members" : [

                {

                        "_id" : 0,

                        "name" : "10.4.4.5:27017",

                        "health" : 1,

                        "state" : 1,

                        "stateStr" : "PRIMARY",

                        "uptime" : 878,

                        "optime" : Timestamp(1396593341, 1416),

                        "optimeDate" : ISODate("2014-04-04T06:35:41Z"),

                        "self" : true

                },

                {

                        "_id" : 1,

                        "name" : "10.4.4.6:27017",

                        "health" : 1,

                        "state" : 2,

                        "stateStr" : "SECONDARY",

                        "uptime" : 858,

                        "optime" : Timestamp(1396593341, 1416),

                        "optimeDate" : ISODate("2014-04-04T06:35:41Z"),

                        "lastHeartbeat" : ISODate("2014-04-04T06:43:45Z"),

                        "lastHeartbeatRecv" : ISODate("2014-04-04T06:43:45Z"),

                        "pingMs" : 0,

                        "syncingTo" : "10.4.4.5:27017"

                }

        ],

        "ok" : 1

}

以上現象非常奇怪,副本集id都是一緻的,結果産生了兩個副本集,都是獨立的,而且更奇怪的是,其中有個一副本集具有兩個primary。

測試以下兩個副本集是否相通:

在第二個副本集上執行資料插入

for(i=1;i<10000;++i){ 

  db.person.insert({ 

        id: i, 

        name: "mongodb"+i 

  } ) 

}

在第二個副本集上查詢,結果:

>db.person.find()

{ "_id" : ObjectId("533e51da0fb65d4623fe3607"), "id" : 1, "name" : "mongodb1" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3608"), "id" : 2, "name" : "mongodb2" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3609"), "id" : 3, "name" : "mongodb3" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360a"), "id" : 4, "name" : "mongodb4" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360b"), "id" : 5, "name" : "mongodb5" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360c"), "id" : 6, "name" : "mongodb6" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360d"), "id" : 7, "name" : "mongodb7" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360e"), "id" : 8, "name" : "mongodb8" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360f"), "id" : 9, "name" : "mongodb9" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3610"), "id" : 10, "name" : "mongodb10" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3611"), "id" : 11, "name" : "mongodb11" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3612"), "id" : 12, "name" : "mongodb12" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3613"), "id" : 13, "name" : "mongodb13" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3614"), "id" : 14, "name" : "mongodb14" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3615"), "id" : 15, "name" : "mongodb15" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3616"), "id" : 16, "name" : "mongodb16" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3617"), "id" : 17, "name" : "mongodb17" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3618"), "id" : 18, "name" : "mongodb18" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3619"), "id" : 19, "name" : "mongodb19" }

{ "_id" : ObjectId("533e51da0fb65d4623fe361a"), "id" : 20, "name" : "mongodb20" }

Type "it" for more

而同時在第一個副本集上查詢,結果為空,表明它與第二副本集資料不是相通的。

兩個副本集同時關閉,再重新開機,

./mongo 10.4.4.4:27017

檢視rs

>rs.status()

{

        "set" : "mongodb_set",

        "date" : ISODate("2014-04-04T06:58:22Z"),

        "myState" : 2,

        "syncingTo" : "10.4.4.5:27017",

        "members" : [

                {

                        "_id" : 0,

                        "name" : "10.4.4.4:27017",

                        "health" : 1,

                        "state" : 2,

                        "stateStr" : "SECONDARY",

                        "uptime" : 135,

                        "optime" : Timestamp(1396594084, 4268),

                        "optimeDate" : ISODate("2014-04-04T06:48:04Z"),

                        "self" : true

                },

                {

                        "_id" : 1,

                        "name" : "10.4.4.5:27017",

                        "health" : 1,

                        "state" : 1,

                        "stateStr" : "PRIMARY",

                        "uptime" : 133,

                        "optime" : Timestamp(1396594084, 4268),

                        "optimeDate" : ISODate("2014-04-04T06:48:04Z"),

                        "lastHeartbeat" : ISODate("2014-04-04T06:58:21Z"),

                        "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),

                        "pingMs" : 0

                }

        ],

        "ok" : 1

}

注意到,這時候副本集一由當初的兩個primary狀态轉變為正常的primary和secondary。由于現在連接配接的secondary節點,無法正常查詢。

執行

>db.getMongo().setSlaveOk();

>db.person.find()

{ "_id" : ObjectId("533e51da0fb65d4623fe3607"), "id" : 1, "name" : "mongodb1" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3608"), "id" : 2, "name" : "mongodb2" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3609"), "id" : 3, "name" : "mongodb3" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360a"), "id" : 4, "name" : "mongodb4" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360b"), "id" : 5, "name" : "mongodb5" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360c"), "id" : 6, "name" : "mongodb6" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360d"), "id" : 7, "name" : "mongodb7" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360e"), "id" : 8, "name" : "mongodb8" }

{ "_id" : ObjectId("533e51da0fb65d4623fe360f"), "id" : 9, "name" : "mongodb9" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3610"), "id" : 10, "name" : "mongodb10" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3611"), "id" : 11, "name" : "mongodb11" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3612"), "id" : 12, "name" : "mongodb12" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3613"), "id" : 13, "name" : "mongodb13" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3614"), "id" : 14, "name" : "mongodb14" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3615"), "id" : 15, "name" : "mongodb15" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3616"), "id" : 16, "name" : "mongodb16" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3617"), "id" : 17, "name" : "mongodb17" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3618"), "id" : 18, "name" : "mongodb18" }

{ "_id" : ObjectId("533e51da0fb65d4623fe3619"), "id" : 19, "name" : "mongodb19" }

{ "_id" : ObjectId("533e51da0fb65d4623fe361a"), "id" : 20, "name" : "mongodb20" }

Type "it" for more

這時候可以查找到資料。

./mongo 10.4.4.5:27017

檢視rs

rs.status()

{

        "set" : "mongodb_set",

        "date" : ISODate("2014-04-04T06:56:30Z"),

        "myState" : 1,

        "members" : [

                {

                        "_id" : 0,

                        "name" : "10.4.4.5:27017",

                        "health" : 1,

                        "state" : 1,

                        "stateStr" : "PRIMARY",

                        "uptime" : 22,

                        "optime" : Timestamp(1396594084, 4268),

                        "optimeDate" : ISODate("2014-04-04T06:48:04Z"),

                        "self" : true

                },

                {

                        "_id" : 1,

                        "name" : "10.4.4.6:27017",

                        "health" : 1,

                        "state" : 2,

                        "stateStr" : "SECONDARY",

                        "uptime" : 20,

                        "optime" : Timestamp(1396594084, 4268),

                        "optimeDate" : ISODate("2014-04-04T06:48:04Z"),

                        "lastHeartbeat" : ISODate("2014-04-04T06:56:30Z"),

                        "lastHeartbeatRecv" : ISODate("2014-04-04T06:56:30Z"),

                        "pingMs" : 0,

                        "lastHeartbeatMessage" : "syncing to: 10.4.4.5:27017",

                        "syncingTo" : "10.4.4.5:27017"

                }

        ],

        "ok" : 1

}

副本集二沒有變化。

現在兩個副本集的資料相通。但是三個節點共有同一個副本集id,結果實際上分屬于兩個不同副本集。

現在從副本集一上的10.4.4.4:27017節點退出,改為10.4.4.5:27017登入,結果又如何?

./mongo 10.4.4.5:27017

檢視rs

>rs.status()

{

        "set" : "mongodb_set",

        "date" : ISODate("2014-04-04T07:08:08Z"),

        "myState" : 1,

        "members" : [

                {

                        "_id" : 0,

                        "name" : "10.4.4.5:27017",

                        "health" : 1,

                        "state" : 1,

                        "stateStr" : "PRIMARY",

                        "uptime" : 720,

                        "optime" : Timestamp(1396594084, 4268),

                        "optimeDate" : ISODate("2014-04-04T06:48:04Z"),

                        "self" : true

                },

                {

                        "_id" : 1,

                        "name" : "10.4.4.6:27017",

                        "health" : 1,

                        "state" : 2,

                        "stateStr" : "SECONDARY",

                        "uptime" : 718,

                        "optime" : Timestamp(1396594084, 4268),

                        "optimeDate" : ISODate("2014-04-04T06:48:04Z"),

                        "lastHeartbeat" : ISODate("2014-04-04T07:08:06Z"),

                        "lastHeartbeatRecv" : ISODate("2014-04-04T07:08:06Z"),

                        "pingMs" : 0,

                        "syncingTo" : "10.4.4.5:27017"

                }

        ],

        "ok" : 1

}

可見目前連接配接的是副本集二的primary,此時副本集一的primary去哪裡了呢?似乎隻能通過10.4.4.4:27017來通路secondary了。

這個難道是mongodb的一個bug?