Replication

如何驗證副本集是否正常工作?

  • December 24, 2018

我是 MongoDB 的新手,甚至更擅長數據庫管理。但是我的老闆給了我一個要解決的問題。

設想

當我執行命令時,我有兩台使用 MongoDB 和 ReplicaSet 的伺服器

db.adminCommand( { replSetGetStatus : 1 } )

在主伺服器上,我得到以下結果:

{
   ...
   "date" : ISODate("2018-12-17T10:39:00.247Z"),
   "myState" : 1,
   ...
}

在輔助伺服器上,我得到以下結果:

{
   ...
   "date" : ISODate("2018-12-17T10:39:00.247Z"),
   "myState" : 2,
   ...
}

正如預期的那樣。

問題

  1. 如果我停止主伺服器的網路介面(eth0)以啟動ReplicaSet,那麼從伺服器的myStatus屬性是否應該更改為1?
  2. 如果狀態要改變,我已經測試過了,它沒有改變。我怎麼知道次要已成為主要?

如果我停止主伺服器的網路介面(eth0)以啟動ReplicaSet,那麼從伺服器的myState屬性是否應該更改為1?

由於您的副本集中只有兩個投票成員,因此選舉或維護主節點 ( n/2 + 1) 所需的投票成員的嚴格多數是2.

您應該期望,如果任一成員不可用,則不會有主副本:兩個成員副本集不提供自動容錯

如果狀態要改變,我已經測試過了,它沒有改變。我怎麼知道次要已成為主要?

副本集成員狀態更改以反映副本集成員的目前角色。如果沒有手動干預強制重新配置副本集,您倖存的輔助節點無法成為主節點。生產部署的推薦解決方案是將第三個成員添加到您的副本集(理想情況下是託管在第三台機器上的另一個承載數據的成員),以便您的部署可以從任何不可用的單個成員中自動恢復。

有幾種方法可以通過mongoshell 確認成員狀態:

  • 預設的mongoshell 提示以您連接到的 MongoDB 程序的副本集名稱和成員狀態為前綴,例如:replset:PRIMARY>. 如果成員狀態發生了變化,點擊<enter>應該重新建立連接並刷新 shell 提示。
  • 通過檢查db.isMaster().primarydb.isMaster().me如果它是主要的,則此狀態值應設置為目前主機(相當於)。
  • 檢查 中的成員國rs.status().myState。值1表示目前成員具有狀態PRIMARY

REPL您可以通過使用日誌組件搜尋 MongoDB 日誌行來找到有關選舉過程的更多資訊 。當您關閉兩個成員副本集上的主節點時,您應該會在剩餘的輔助節點上看到類似於以下內容的日誌消息:

# Checking from a bash shell (note the intentional space after "REPL ")
grep "REPL " mongod.log | tail -1

2018-12-24T12:40:01.894+1100 I REPL     [replexec-2] Not starting an election, since we are not electable due to: Not standing for election because I cannot see a majority

如果我停止主伺服器的網路介面(eth0)以啟動ReplicaSet,那麼從伺服器的myStatus屬性是否應該更改為1?

根據此處的 MongoDB 文件

rs.stepDown()

Or

rs.stepDown(stepDownSecs, secondaryCatchUpPeriodSecs)

指示副本集的節點成為輔助節點。主節點下台後,符合條件的輔助節點將舉行主節點選舉

該方法不會立即降低初級。如果沒有可選的輔助節點與主節點保持同步,則主節點會等待最多 secondaryCatchUpPeriodSecs(預設為 10 秒)以使輔助節點趕上。一旦可選的輔助節點可用,該方法就會逐步降低主節點。

**注意:**從接收到rs.stepDown()方法開始,直到選出新的主節點,或者如果沒有可選的輔助節點,原始主節點恢復正常操作,所有對主節點的寫入都失敗。寫入失敗的最大時間段為:secondaryCatchUpPeriodSecs(預設10s)+ electionTimeoutMillis(預設10s)。

如果狀態要改變,我已經測試過了,它沒有改變。我怎麼知道次要已成為主要?

根據 MongoDB 文件rs.status()此輸出反映了副本集的目前狀態,使用從副本集的其他成員發送的心跳數據包派生的數據。

從 MongoDB 3.4 開始,如果命令在輔助節點上執行,replSetGetStatus命令可以接受可選的 initialSync: 1 以報告初始同步狀態和進度。要報告輔助節點的初始同步,您必須執行命令而不是幫助程序。

db.adminCommand( { replSetGetStatus : 1 } )

例如

該命令返回範例副本集主副本的以下輸出:

{
  "set" : "replset",
  "date" : ISODate("2018-12-06T18:34:41.288Z"),
  "myState" : 1,
  "term" : NumberLong(1),
  "syncingTo" : "",
  "syncSourceHost" : "",
  "syncSourceId" : -1,
  "heartbeatIntervalMillis" : NumberLong(2000),
  "optimes" : {
     "lastCommittedOpTime" : {
        "ts" : Timestamp(1544121271, 1),
        "t" : NumberLong(1)
     },
     "readConcernMajorityOpTime" : {
        "ts" : Timestamp(1544121271, 1),
        "t" : NumberLong(1)
     },
     "appliedOpTime" : {
        "ts" : Timestamp(1544121271, 1),
        "t" : NumberLong(1)
     },
     "durableOpTime" : {
        "ts" : Timestamp(1544121271, 1),
        "t" : NumberLong(1)
     }
  },
  "lastStableCheckpointTimestamp" : Timestamp(1544121271, 1),
  "members" : [
        {
           "_id" : 0,
           "name" : "m1.example.net:27017",
           "health" : 1,
           "state" : 1,
           "stateStr" : "PRIMARY",
           "uptime" : 85,
           "optime" : {
              "ts" : Timestamp(1544121271, 1),
              "t" : NumberLong(1)
           },
           "optimeDate" : ISODate("2018-12-06T18:34:31Z"),
           "syncingTo" : "",
           "syncSourceHost" : "",
           "syncSourceId" : -1,
           "infoMessage" : "could not find member to sync from",
           "electionTime" : Timestamp(1544121209, 1),
           "electionDate" : ISODate("2018-12-06T18:33:29Z"),
           "configVersion" : 1,
           "self" : true,
           "lastHeartbeatMessage" : ""
        },
        {
           "_id" : 1,
           "name" : "m2.example.net:27017",
           "health" : 1,
           "state" : 2,
           "stateStr" : "SECONDARY",
           "uptime" : 81,
           "optime" : {
              "ts" : Timestamp(1544121271, 1),
              "t" : NumberLong(1)
           },
           "optimeDurable" : {
              "ts" : Timestamp(1544121271, 1),
              "t" : NumberLong(1)
           },
           "optimeDate" : ISODate("2018-12-06T18:34:31Z"),
           "optimeDurableDate" : ISODate("2018-12-06T18:34:31Z"),
           "lastHeartbeat" : ISODate("2018-12-06T18:34:39.866Z"),
           "lastHeartbeatRecv" : ISODate("2018-12-06T18:34:41.118Z"),
           "pingMs" : NumberLong(0),
           "lastHeartbeatMessage" : "",
           "syncingTo" : "m1.example.net:27017",
           "syncSourceHost" : "m1.example.net:27017",
           "syncSourceId" : 0,
           "infoMessage" : "",
           "configVersion" : 1
        },
        {
           "_id" : 2,
           "name" : "m3.example.net:27017",
           "health" : 1,
           "state" : 2,
           "stateStr" : "SECONDARY",
           "uptime" : 12,
           "optime" : {
              "ts" : Timestamp(1544121271, 1),
              "t" : NumberLong(1)
           },
           "optimeDurable" : {
              "ts" : Timestamp(1544121271, 1),
              "t" : NumberLong(1)
           },
           "optimeDate" : ISODate("2018-12-06T18:34:31Z"),
           "optimeDurableDate" : ISODate("2018-12-06T18:34:31Z"),
           "lastHeartbeat" : ISODate("2018-12-06T18:34:40.934Z"),
           "lastHeartbeatRecv" : ISODate("2018-12-06T18:34:40.740Z"),
           "pingMs" : NumberLong(0),
           "lastHeartbeatMessage" : "",
           "syncingTo" : "m2.example.net:27017",
           "syncSourceHost" : "m2.example.net:27017",
           "syncSourceId" : 1,
           "infoMessage" : "",
           "configVersion" : 1
        }
     ],
  "ok" : 1,
  "$clusterTime" : {
     "clusterTime" : Timestamp(1526229410, 1),
     "signature" : {
        "hash" : BinData(0,"WE7yaBuLazOtqwdJxaroLp1Kluo="),
        "keyId" : NumberLong("6554495980643811329")
     }
  },
  "operationTime" : Timestamp(1526229410, 1),
}

引用自:https://dba.stackexchange.com/questions/225144