Replication

在 MongoDB 中重新配置 replSet 問題

  • December 28, 2018

我曾經在同一個 db 文件夾中嘗試複製集展示。副本集名稱為“test”。然後我嘗試使用不同的名稱“repl”重新建構 repl 集。重新配置後,我收到以下錯誤消息:

{
       "ok" : 0,
       "errmsg" : "replSetReconfig should only be run on PRIMARY, but my state is REMOVED; use the \"force\" argument to override",
       "code" : 10107,
       "codeName" : "NotMaster"
}

所以我按照errmsg,並嘗試執行以下命令:

rs.reconfig(config,{"force":true})

現在我收到以下錯誤消息:

{
       "ok" : 0,
       "errmsg" : "New and old configurations differ in replica set name; old was test, and new is repl",
       "code" : 103,
       "codeName" : "NewReplicaSetConfigurationIncompatible"
}

太糟糕了!所以我使用了以前的名字“test”。但我再次得到錯誤。

{                                                                                                                       
       "ok" : 0,                                                                                                       
       "errmsg" : "New and old configurations differ in the setting of the arbiterOnly field for member 127.0.0.1:27020
; to make this change, remove then re-add the member",                                                                  
       "code" : 103,                                                                                                   
       "codeName" : "NewReplicaSetConfigurationIncompatible"                                                           
}  

我實在是不明白,如果每一個配置資訊都必須和之前的一致,那為什麼還要重新配置呢?

有人說可以drop本地數據庫,但是這個操作還是不行。

{
           "ok" : 0,
           "errmsg" : "Cannot drop 'local' database while replication is active",
           "code" : 20,
           "codeName" : "IllegalOperation"
   } 

哦,MGD!我只是不明白為什麼在目前 db 文件夾中重新啟動 replset 如此困難。

按照 MongoDB BOL Here To Reconfigures an existing replica set,覆蓋現有的副本集配置。要執行該方法,您必須連接到副本集的主節點。

rs.reconfig(configuration, force)

要重新配置現有副本集,首先使用 檢索目前配置rs.conf(),根據需要修改配置文件,然後將修改後的文件傳遞給rs.reconfig()

rs.reconfig() 為replSetReconfig命令提供了一個包裝器。

force 參數允許向非主節點發出重新配置命令。

**警告:**避免重新配置包含不同 MongoDB 版本成員的副本集,因為驗證規則可能因 MongoDB 版本而異。

rs.reconfig()shell 方法在某些情況下可以觸發目前的主節點降級。當主節點關閉時,它會強制關閉所有客戶端連接。這是設計使然。由於選擇新的主節點可能需要一段時間,因此請在維護期間安排重新配置更改,以最大程度地減少寫入可用性的損失。

{ force: true }

警告: 將 rs.reconfig() 與 { force: true } 一起使用可能會導致已送出的寫入回滾。使用此選項時要小心。

成員優先級和投票 已更改MongoDB version 3.2

優先級大於0不能擁有的成員0 votes

Non-voting成員必須具有 的優先級0

例如,名為rs0的副本集具有以下配置:

{
  "_id" : "rs0",
  "version" : 1,
  "protocolVersion" : NumberLong(1),
  "members" : [
     {
        "_id" : 0,
        "host" : "mongodb0.example.net:27017",
        "arbiterOnly" : false,
        "buildIndexes" : true,
        "hidden" : false,
        "priority" : 1,
        "tags" : {

        },
        "slaveDelay" : NumberLong(0),
        "votes" : 1
     },
     {
        "_id" : 1,
        "host" : "mongodb1.example.net:27017",
        "arbiterOnly" : false,
        "buildIndexes" : true,
        "hidden" : false,
        "priority" : 1,
        "tags" : {

        },
        "slaveDelay" : NumberLong(0),
        "votes" : 1
     },
     {
        "_id" : 2,
        "host" : "mongodb2.example.net:27017",
        "arbiterOnly" : false,
        "buildIndexes" : true,
        "hidden" : false,
        "priority" : 1,
        "tags" : {

        },
        "slaveDelay" : NumberLong(0),
        "votes" : 1
     }
  ],
  "settings" : {
     "chainingAllowed" : true,
     "heartbeatIntervalMillis" : 2000,
     "heartbeatTimeoutSecs" : 10,
     "electionTimeoutMillis" : 10000,
     "catchUpTimeoutMillis" : 2000,
     "getLastErrorModes" : {

     },
     "getLastErrorDefaults" : {
        "w" : 1,
        "wtimeout" : 0
     },
     "replicaSetId" : ObjectId("58858acc1f5609ed986b641b")
  }
}

以下操作序列更新成員$$ n $$.第二個成員的優先級。這些操作是通過連接到主的mongo shell 發出的。

cfg = rs.conf();
cfg.members[1].priority = 2;
rs.reconfig(cfg);

正如上述聲明的工作方式,例如

  1. 第一條語句使用 rs.conf() 方法檢索包含副本集目前配置的文件,並將該文件設置為局部變數 cfg。
  2. 第二條語句members[n].priority為 members 數組中的第二個文件設置一個值。有關其他設置,請參閱副本集配置設置。
To access the member configuration document in the array, the
statement uses the array index and not the replica set member’s
`members[n]._id` field.
  1. 最後一條語句rs.reconfig()使用修改後的 cfg 呼叫方法來初始化這個新配置。成功重新配置後,副本集配置將類似於以下內容:

{“_id”:“rs0”,“版本”:2,“protocolVersion”:NumberLong(1),“成員”:[{“_id”:0,“主機”:“mongodb0.example.net:27017”, “arbiterOnly”:假,“buildIndexes”:真,“隱藏”:假,“優先級”:1,“標籤”:{

    },
    "slaveDelay" : NumberLong(0),
    "votes" : 1
 },
 {
    "_id" : 1,
    "host" : "mongodb1.example.net:27017",
    "arbiterOnly" : false,
    "buildIndexes" : true,
    "hidden" : false,
    "priority" : 2,
    "tags" : {

    },
    "slaveDelay" : NumberLong(0),
    "votes" : 1
 },
 {
    "_id" : 2,
    "host" : "mongodb2.example.net:27017",
    "arbiterOnly" : false,
    "buildIndexes" : true,
    "hidden" : false,
    "priority" : 1,
    "tags" : {

    },
    "slaveDelay" : NumberLong(0),
    "votes" : 1
 }

],“設置”:{“chainingAllowed”:真,“heartbeatIntervalMillis”:2000,“heartbeatTimeoutSecs”:10,“electionTimeoutMillis”:10000,“catchUpTimeoutMillis”:2000,“getLastErrorModes”:{

 },
 "getLastErrorDefaults" : {
    "w" : 1,
    "wtimeout" : 0
 },
 "replicaSetId" : ObjectId("58858acc1f5609ed986b641b")

} }

**注意:**更新副本配置對象時,使用數組索引訪問成員數組中的副本集成員。數組索引從 0 開始。不要將此索引值與members[n]._id成員數組中每個文件中的欄位值混淆。

如需幫助,您可以輸入mongoshell rs.help()

> rs.help()
       rs.status()                                { replSetGetStatus : 1 } checks repl set status
       rs.initiate()                              { replSetInitiate : null } initiates set with default settings
       rs.initiate(cfg)                           { replSetInitiate : cfg } initiates set with configuration cfg
       rs.conf()                                  get the current configuration object from local.system.replset
       rs.reconfig(cfg)                           updates the configuration of a running replica set with cfg (disconnects)
       rs.add(hostportstr)                        add a new member to the set with default attributes (disconnects)
       rs.add(membercfgobj)                       add a new member to the set with extra attributes (disconnects)
       rs.addArb(hostportstr)                     add a new member which is arbiterOnly:true (disconnects)
       rs.stepDown([stepdownSecs, catchUpSecs])   step down as primary (disconnects)
       rs.syncFrom(hostportstr)                   make a secondary sync from the given member
       rs.freeze(secs)                            make a node ineligible to become primary for the time specified
       rs.remove(hostportstr)                     remove a host from the replica set (disconnects)
       rs.slaveOk()                               allow queries on secondary nodes

       rs.printReplicationInfo()                  check oplog size and time range
       rs.printSlaveReplicationInfo()             check replica set members and replication lag
       db.isMaster()                              check who is primary

       reconfiguration helpers disconnect from the database so the shell will display
       an error, even if the command succeeds.

供您進一步參考這里這裡

我認為您需要先刪除所有副本配置。所以基本上你需要在沒有--replSet. 然後去db.system.replsetcollection去掉對應的id。然後重新啟動副本實例。

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