從mongodb standalone模式遷移至副本集模式(3.2.x版本)
步驟一:停止所有mongodb讀寫,否則影響數據同步。
步驟二:創建副本集的mongo實例,將standalone模式的數據庫文件拷貝所有副本集實例對應配置文件的dpapth路徑中。
注:該操作也可不進行,僅保留主庫中數據文件,secoundary節點數據庫文件爲空,依賴副本集初始化過程的數據自動同步機制,將數據同步到secoundary節點,如果數據庫較大,這樣操作耗時較長。
步驟三:創建集羣用戶:
以standalone模式啓動mongod實例,用原standalone賬號登錄mongo shell
執行:use admin
創建有clusterAdmin集羣管理權限(副本集、分片、主從等相關管理)的用戶
執行:
db.createUser({"user":"dbupdater","pwd":"l79bv2PA","roles":[{role:"root",db:"admin"},{role:"clusterAdmin",db:"admin"}]})
db.auth('dbupdater','l79bv2PA')
步驟四:修改防火牆,開啓副本集實例啓動所需要的相應端口訪問權限
步驟五:mongod配置文件中增加副本集配置
replSet = replTest
注:同一副本集名稱相同
步驟六:初始化副本集
使用創建的集羣用戶登錄mongo shell
輸入變量:
conf={_id:"replTest", members:[{_id:0, host:'172.28.81.226:27017',priority:2},{_id:1, host:'172.28.81.226:27018'},{_id:2, host:'172.28.81.226:27019'}]}
執行初始化:
rs.initiate(conf)
報錯:
{
"ok" : 0,
"errmsg" : "Attempting to initiate a replica set with name rs0, but command line reports replTest; rejecting",
"code" : 93
}
原因:
mongod啓動設置的replSet名稱與初始化腳本的_id不一致
解決方式:
腳本中_id與配置文件副本集名稱相同
報錯:
{
"ok" : 0,
"errmsg" : "replSetInitiate quorum check failed because not all proposed set members responded affirmatively: 127.0.0.1:27018 failed with not authorized on admin to execute command { replSetHeartbeat: \"replTest\", pv: 1, v: 1, from: \"127.0.0.1:27017\", fromId: 0, checkEmpty: true }, 127.0.0.1:27019 failed with not authorized on admin to execute command { replSetHeartbeat: \"replTest\", pv: 1, v: 1, from: \"127.0.0.1:27017\", fromId: 0, checkEmpty: true }",
"code" : 74
}
原因:
未配置節點間的免密認證
解決方式:
生成祕鑰文件
openssl rand 700 -base64 > /home/config/mongodb.keyfile
chmod 600 /home/config/mongodb.keyfile
將祕鑰拷貝到其他服務器(當前實驗環境,副本集實例在一臺機器不用拷貝):
scp /home/config/mongodb.keyfile [email protected]:/home/config/
scp /home/config/mongodb.keyfile [email protected]:/home/config/
在每個實例的配置文件中追加配置項———用於配置節點間的免密驗證
在mongod配置文件設置祕鑰文件路徑
keyFile= /home/replMongo/mongodb.keyfile
報錯:
{
"ok" : 0,
"errmsg" : "'172.28.81.226:27018' has data already, cannot initiate set.",
"code" : 110
}
原因:未知
網上有資料說應清空副本集中數據內容,再初始化副本集,保證初始化副本集過程中,secoundary節點沒有數據,從主節點同步數據到各secoundary節點
解決方式:
未採用網上方式,改用變更初始化副本集腳本,先初始化一個節點,再將後續副本集節點追加進來。該方式可成功初始化副本集。
變更腳本
conf={_id:"replTest", members:[{_id:0, host:'172.28.81.226:27017'}]}
執行初始化:
rs.initiate(conf)
當前節點被默認爲主節點
執行副本集追加操作:
rs.add("172.28.81.226:27018")
rs.add("172.28.81.226:27019")
rs.status()
可以看到後兩個從節點stateStr爲STARTUP2,正在進行初始化。
觀察日誌會發現一些索引和數據的同步操作,等待片刻,初始化完成,副本集構建成功。
執行rs.status()
{
"set" : "replTest",
"date" : ISODate("2020-06-15T12:33:54.331Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 0,
"name" : "172.28.81.226:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2422,
"optime" : {
"ts" : Timestamp(1592224129, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-06-15T12:28:49Z"),
"electionTime" : Timestamp(1592224053, 2),
"electionDate" : ISODate("2020-06-15T12:27:33Z"),
"configVersion" : 3,
"self" : true
},
{
"_id" : 1,
"name" : "172.28.81.226:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 334,
"optime" : {
"ts" : Timestamp(1592224129, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-06-15T12:28:49Z"),
"lastHeartbeat" : ISODate("2020-06-15T12:33:53.886Z"),
"lastHeartbeatRecv" : ISODate("2020-06-15T12:33:49.524Z"),
"pingMs" : NumberLong(0),
"configVersion" : 3
},
{
"_id" : 2,
"name" : "172.28.81.226:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 304,
"optime" : {
"ts" : Timestamp(1592224129, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-06-15T12:28:49Z"),
"lastHeartbeat" : ISODate("2020-06-15T12:33:53.886Z"),
"lastHeartbeatRecv" : ISODate("2020-06-15T12:33:54.015Z"),
"pingMs" : NumberLong(0),
"configVersion" : 3
}
],
"ok" : 1
}