分散式文件儲存資料庫之MongoDB副本集

1874發表於2020-11-10

  前文我們聊到了mongodb的索引的相關作用和介紹以及索引的管理,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13950287.html;今天我們來聊下mongodb的副本集;

  1、什麼是副本集?主要作用是什麼?它是怎麼工作的呢?

  所謂副本集是指服務於同一資料集的多個mongodb例項;這意味著在mongodb中資料集副本的數量可以是多個,每個副本的資料都是一樣的;副本的存在主要作用是對mongodb資料庫中的資料做冗餘備份和提高資料服務的可用性;在mongodb中對資料做冗餘的方式有兩種,一種是主從架構(master/slave),這種架構和mysql中的主從架構沒有什麼不同,但是在mongodb中,主從架構的方式幾乎沒有人用,處於廢棄的狀態。。另外一種是副本集(replica set),副本集本質上也是主從架構的一種,它和我們剛才說的主從架構,有一個顯著的區別,副本集支援故障自動轉移,不需要人工手動干預;所謂的故障自動轉移是指當一個副本集中主節點因各種原因當機或者從節點在一定時間內沒有收到主節點傳送到心跳資訊,此時就會觸發從節點重新選舉主節點的操作;在多個從節點中選舉出來一個主節點以後,其他從節點能夠自動指向新選舉的主節點同步資料,從而完成這次故障轉移;

  2、mongodb副本集架構

  提示:對於mongodb中的副本集來說,為了保證資料的一致性,一個副本集中只能有一個主節點,並且只有主節點才擁有讀寫許可權,其他從節點都只有讀許可權;在mongodb的副本集中,主節點我們叫做primary,從節點叫做secondary;

  3、副本集是通過什麼來複制資料的呢?

  我知道mysql的主從複製是通過主節點記錄寫操作到binlog中,從節點通過同步主節點的binlog,然後把同步的binlog在本地進行重放,從而實現資料同步;在mongodb中也是類似的操作,不同的是在mongodb中主節點將寫操作記錄到oplog(操作日誌),各從節點通過複製主節點的oplog,在本地重放實現資料同步;oplog的作用和mysql中的binlog的作用很類似,都是用來記錄寫操作事件,都是用來同步資料;mongodb中的oplog是一個定容集合,所謂定容是指它的大小是固定的,它不會像binlog隨日誌的增多而逐漸變大;通常oplog我們不人為指定其大小,預設就是佔用所在檔案系統空閒磁碟的5%;除了大小是不變的,它還有一個冪等的特點;所謂冪等就是不管在monogdb中執行多少次oplog中的操作,其最終的結果都是一樣的;如果寫操作日誌把oplog寫滿了,它會從頭覆蓋之前的oplog,依次迴圈寫oplog;

  4、副本集是怎麼完成故障轉移的?

  在前邊我們聊zookeeper時,聊到過分散式場景中的選舉過程;mongodb的主節點故障以後,也是通過這種機制來完成選舉;在mongodb的副本集中,主節點每隔兩秒向各從節點傳送心跳資訊,各從節點通過檢測主節點的心跳資訊來判定主節點是否存活;如果在一定的時間範圍內,從節點沒有收到主節點傳送到心跳資訊,此時從節點會認為主節點掛了,從而觸發主節點選舉的操作;這個選舉和zookeeper裡的選舉很類似,通常情況都是大於叢集總票的一半一方可以代表叢集正常工作;所以通常情況mongodb副本集都是基數個節點組成;當然mongodb中也可以是偶數節點(正常提供服務的節點),如果是偶數節點,通常會藉助一個仲裁節點來完成選舉;仲裁節點擁有選票,但不被選舉成為主節點,也不擁有副本資料,同時它必須要能夠檢測主節點心跳;簡單總結就是mongodb副本集是通過從節點檢測主節點心跳來判斷主節點是否存活,如果在一定時間範圍內,沒有檢測到主節點的心跳資訊,此時就會觸發主節點選舉操作,如果叢集節點數量為偶數個,通常會藉助仲裁節點來完成選舉;從而實現完成故障自動轉移;

  5、mongodb副本集中特殊型別節點分類

  0優先順序節點:這種節點的特點是優先順序為0,可參與選舉,擁有副本資料,但不被選舉成為主節點,可讀不可寫;這種節點我們也叫冷備節點;通常用於異地容災使用;

  被隱藏的從節點:這種節點的特點是,可參與選舉,擁有副本資料,但不被選舉成為主節點,對客戶端不可讀寫也不可見;通常用於同步同一副本集中的其他節點的不同工作流的場景中;

  延遲複製的從節點:這種節點的特點是,副本資料落後主節點一個時間視窗,也就說這種節點上的副本資料總是過期的;除此它可參與選舉,不可被選舉為主節點;主要用於特殊功用;比如在主節點上執行了一個刪除操作,我們可以在延遲複製的從節點上把資料找回;

  arbiter節點:這種就是我們說的仲裁節點,它可參與選舉,不擁有副本資料,不被選舉成為主節點,不可讀寫;主要作用是輔助判定主節點是否存活,輔助從節點完成選舉,實現故障轉移;

  6、建立mongodb的副本集合

  環境準備

主機名 ip地址
node01 192.168.0.41
node02 192.168.0.42
node03 192.168.0.43

 

 

 

 

 

 

  在三個節點上分別做好時間同步,關閉selinux,關閉防火牆,主機名解析,有必要還可以做ssh互信。準備好基礎環境以後,在三臺server上配置mongodb的yum源

[root@node01 ~]# cat /etc/yum.repos.d/mongodb.repo 
[mongodb-org]
name = MongoDB Repository
baseurl = https://mirrors.aliyun.com/mongodb/yum/redhat/7/mongodb-org/4.4/x86_64/
gpgcheck = 1
enabled = 1
gpgkey = https://www.mongodb.org/static/pgp/server-4.4.asc
[root@node01 ~]# scp /etc/yum.repos.d/mongodb.repo node02:/etc/yum.repos.d/
mongodb.repo                                                                  100%  206    80.4KB/s   00:00    
[root@node01 ~]# scp /etc/yum.repos.d/mongodb.repo node03:/etc/yum.repos.d/
mongodb.repo                                                                  100%  206    88.9KB/s   00:00    
[root@node01 ~]# 

  安裝mongodb-org

yum install -y mongodb-org

  準備資料目錄和存放日誌的目錄,並將其屬主和屬組更改為mongod使用者

[root@node01 ~]# mkdir -pv /mongodb/{data,log} 
mkdir: created directory ‘/mongodb’
mkdir: created directory ‘/mongodb/data’
mkdir: created directory ‘/mongodb/log’
[root@node01 ~]# chown -R mongod.mongod /mongodb/
[root@node01 ~]# ll -d /mongodb/
drwxr-xr-x 4 mongod mongod 29 Nov 10 19:36 /mongodb/
[root@node01 ~]# 

  提示:以上需在三個節點都要做一遍;

  配置mongodb

  提示:主要配置replication,其中oplogSizeMB用來指定oplog的大小,預設不指定,其大小就是所在檔案系統空閒磁碟的%5;replSetName用來指定副本集的名稱,這個名稱非常重要,主要用來標識不同副本集;enableMajorityReadConcern用來指定是否開啟mongodb週期性的做快照,並記錄oplog的時間戳;

  完整配置

分散式文件儲存資料庫之MongoDB副本集
[root@node01 ~]# cat /etc/mongod.conf
systemLog:
  destination: file
  logAppend: true
  path: /mongodb/log/mongod.log

storage:
  dbPath: /mongodb/data/
  journal:
    enabled: true

processManagement:
  fork: true  
  pidFilePath: /var/run/mongodb/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27017
  bindIp: 0.0.0.0

replication:
   oplogSizeMB: 2048
   replSetName: test_replset
   enableMajorityReadConcern: false



#security:

#operationProfiling:

#sharding:

## Enterprise-Only Options

#auditLog:

#snmp:
[root@node01 ~]# 
View Code

  複製配置檔案到node02,node03

[root@node01 ~]# scp /etc/mongod.conf node02:/etc/
mongod.conf                                                                   100%  494   315.1KB/s   00:00    
[root@node01 ~]# scp /etc/mongod.conf node03:/etc/
mongod.conf                                                                   100%  494   351.6KB/s   00:00    
[root@node01 ~]# 

  啟動服務

  提示:請確保對應節點上的mongodb所監聽的埠正常即可;

  連線三個節點任意一個節點檢視副本集狀態

> 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.secondaryOk()                               allow queries on secondary nodes

        rs.printReplicationInfo()                  check oplog size and time range
        rs.printSecondaryReplicationInfo()             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.
> rs.status() 
{
        "operationTime" : Timestamp(0, 0),
        "ok" : 0,
        "errmsg" : "no replset config has been received",
        "code" : 94,
        "codeName" : "NotYetInitialized",
        "$clusterTime" : {
                "clusterTime" : Timestamp(0, 0),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
> 

  提示:所有關於副本集的操作命令都可以使用rs.help()方法去檢視幫助;其中rs.status()是用來檢視副本集狀態;這裡顯示沒有副本集配置,其原因是沒有初始化副本集;

  初始化副本集

> rs.initiate()
{
        "info2" : "no configuration specified. Using a default configuration for the set",
        "me" : "node01.test.org:27017",
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605010821, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605010821, 1)
}
test_replset:SECONDARY> rs.status()
{
        "set" : "test_replset",
        "date" : ISODate("2020-11-10T12:20:32.079Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "majorityVoteCount" : 1,
        "writeMajorityCount" : 1,
        "votingMembersCount" : 1,
        "writableVotingMembersCount" : 1,
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1605010821, 8),
                        "t" : NumberLong(1)
                },
                "lastCommittedWallTime" : ISODate("2020-11-10T12:20:21.720Z"),
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1605010821, 8),
                        "t" : NumberLong(1)
                },
                "readConcernMajorityWallTime" : ISODate("2020-11-10T12:20:21.720Z"),
                "appliedOpTime" : {
                        "ts" : Timestamp(1605010821, 8),
                        "t" : NumberLong(1)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1605010821, 8),
                        "t" : NumberLong(1)
                },
                "lastAppliedWallTime" : ISODate("2020-11-10T12:20:21.720Z"),
                "lastDurableWallTime" : ISODate("2020-11-10T12:20:21.720Z")
        },
        "electionCandidateMetrics" : {
                "lastElectionReason" : "electionTimeout",
                "lastElectionDate" : ISODate("2020-11-10T12:20:21.632Z"),
                "electionTerm" : NumberLong(1),
                "lastCommittedOpTimeAtElection" : {
                        "ts" : Timestamp(0, 0),
                        "t" : NumberLong(-1)
                },
                "lastSeenOpTimeAtElection" : {
                        "ts" : Timestamp(1605010821, 1),
                        "t" : NumberLong(-1)
                },
                "numVotesNeeded" : 1,
                "priorityAtElection" : 1,
                "electionTimeoutMillis" : NumberLong(10000),
                "newTermStartDate" : ISODate("2020-11-10T12:20:21.694Z"),
                "wMajorityWriteAvailabilityDate" : ISODate("2020-11-10T12:20:21.719Z")
        },
        "members" : [
                {
                        "_id" : 0,
                        "name" : "node01.test.org:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 674,
                        "optime" : {
                                "ts" : Timestamp(1605010821, 8),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2020-11-10T12:20:21Z"),
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "Could not find member to sync from",
                        "electionTime" : Timestamp(1605010821, 2),
                        "electionDate" : ISODate("2020-11-10T12:20:21Z"),
                        "configVersion" : 1,
                        "configTerm" : 1,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                }
        ],
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605010821, 8),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605010821, 8)
}
test_replset:PRIMARY> 

  提示:初始化副本集以後,再次檢視副本集狀態,它告訴我們有一個成員,其主機名為node01.test.org:27017,其health狀態為1,stateStr為PRIMARY等等一堆資訊;

  檢視副本集配置

test_replset:PRIMARY> rs.conf()
{
        "_id" : "test_replset",
        "version" : 1,
        "term" : 1,
        "protocolVersion" : NumberLong(1),
        "writeConcernMajorityJournalDefault" : true,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "node01.test.org: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" : -1,
                "catchUpTakeoverDelayMillis" : 30000,
                "getLastErrorModes" : {

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("5faa85853d5a2d8fdf8af85e")
        }
}
test_replset:PRIMARY> 

  提示:可以看到心跳時間間隔為2s,超時為10s,選舉超時時長為10等等資訊;

  新增node02,node03節點到副本整合員

test_replset:PRIMARY> rs.add("node02")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605011243, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605011243, 1)
}
test_replset:PRIMARY> rs.add("node03")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605011250, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605011250, 1)
}
test_replset:PRIMARY> rs.status()
{
        "set" : "test_replset",
        "date" : ISODate("2020-11-10T12:27:45.849Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "majorityVoteCount" : 2,
        "writeMajorityCount" : 2,
        "votingMembersCount" : 3,
        "writableVotingMembersCount" : 3,
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1605011261, 1),
                        "t" : NumberLong(1)
                },
                "lastCommittedWallTime" : ISODate("2020-11-10T12:27:41.873Z"),
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1605011261, 1),
                        "t" : NumberLong(1)
                },
                "readConcernMajorityWallTime" : ISODate("2020-11-10T12:27:41.873Z"),
                "appliedOpTime" : {
                        "ts" : Timestamp(1605011261, 1),
                        "t" : NumberLong(1)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1605011261, 1),
                        "t" : NumberLong(1)
                },
                "lastAppliedWallTime" : ISODate("2020-11-10T12:27:41.873Z"),
                "lastDurableWallTime" : ISODate("2020-11-10T12:27:41.873Z")
        },
        "electionCandidateMetrics" : {
                "lastElectionReason" : "electionTimeout",
                "lastElectionDate" : ISODate("2020-11-10T12:20:21.632Z"),
                "electionTerm" : NumberLong(1),
                "lastCommittedOpTimeAtElection" : {
                        "ts" : Timestamp(0, 0),
                        "t" : NumberLong(-1)
                },
                "lastSeenOpTimeAtElection" : {
                        "ts" : Timestamp(1605010821, 1),
                        "t" : NumberLong(-1)
                },
                "numVotesNeeded" : 1,
                "priorityAtElection" : 1,
                "electionTimeoutMillis" : NumberLong(10000),
                "newTermStartDate" : ISODate("2020-11-10T12:20:21.694Z"),
                "wMajorityWriteAvailabilityDate" : ISODate("2020-11-10T12:20:21.719Z")
        },
        "members" : [
                {
                        "_id" : 0,
                        "name" : "node01.test.org:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 1107,
                        "optime" : {
                                "ts" : Timestamp(1605011261, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2020-11-10T12:27:41Z"),
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "electionTime" : Timestamp(1605010821, 2),
                        "electionDate" : ISODate("2020-11-10T12:20:21Z"),
                        "configVersion" : 3,
                        "configTerm" : 1,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                },
                {
                        "_id" : 1,
                        "name" : "node02:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 21,
                        "optime" : {
                                "ts" : Timestamp(1605011261, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1605011261, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2020-11-10T12:27:41Z"),
                        "optimeDurableDate" : ISODate("2020-11-10T12:27:41Z"),
                        "lastHeartbeat" : ISODate("2020-11-10T12:27:44.967Z"),
                        "lastHeartbeatRecv" : ISODate("2020-11-10T12:27:43.983Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncSourceHost" : "node01.test.org:27017",
                        "syncSourceId" : 0,
                        "infoMessage" : "",
                        "configVersion" : 3,
                        "configTerm" : 1
                },
                {
                        "_id" : 2,
                        "name" : "node03:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 14,
                        "optime" : {
                                "ts" : Timestamp(1605011261, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1605011261, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2020-11-10T12:27:41Z"),
                        "optimeDurableDate" : ISODate("2020-11-10T12:27:41Z"),
                        "lastHeartbeat" : ISODate("2020-11-10T12:27:44.967Z"),
                        "lastHeartbeatRecv" : ISODate("2020-11-10T12:27:44.571Z"),
                        "pingMs" : NumberLong(1),
                        "lastHeartbeatMessage" : "",
                        "syncSourceHost" : "node02:27017",
                        "syncSourceId" : 1,
                        "infoMessage" : "",
                        "configVersion" : 3,
                        "configTerm" : 1
                }
        ],
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605011261, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605011261, 1)
}
test_replset:PRIMARY> 

  提示:新增節點到副本成員使用rs.add(),括號裡面寫主機名,或者ip地址,如果對應節點監聽埠不是27017,還需要寫明埠;除此我們也可以直接用一個子文件的形式,手動指定節點的各屬性資訊來新增節點到副本整合員;

  到此副本集的配置就完成了,三個節點都新增到副本集;

  驗證:在主庫上插入資料,看看從庫是否都可以正常同步其資料呢?

  在主節點插入資料

test_replset:PRIMARY> use students
switched to db students
test_replset:PRIMARY> db.student_info.insert({name:"tom",age:18,gender:"M"})
WriteResult({ "nInserted" : 1 })
test_replset:PRIMARY> db.student_info.find()
{ "_id" : ObjectId("5faa89297077300f4fc31d1c"), "name" : "tom", "age" : 18, "gender" : "M" }
test_replset:PRIMARY> 

  在從節點檢視資料

test_replset:SECONDARY> show dbs
uncaught exception: Error: listDatabases failed:{
        "topologyVersion" : {
                "processId" : ObjectId("5faa83025f9218c5d19ea91b"),
                "counter" : NumberLong(4)
        },
        "operationTime" : Timestamp(1605011801, 1),
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotMasterNoSlaveOk",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605011801, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12
shellHelper.show@src/mongo/shell/utils.js:937:13
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1
test_replset:SECONDARY> 

  提示:這裡在從節點上沒法檢視資料,原因是預設情況副本集配置好以後,要在從節點執行rs.secondaryOk()來告訴從節點已經配置好了,否則它會不允許我們讀,有點類似從節點為就緒的感覺;

  在從節點上執行rs.secondaryOk(),然後再次檢視資料

test_replset:SECONDARY> rs.secondaryOk()  
test_replset:SECONDARY> show dbs
admin     0.000GB
config    0.000GB
local     0.000GB
students  0.000GB
test_replset:SECONDARY> use students
switched to db students
test_replset:SECONDARY> show collections
student_info
test_replset:SECONDARY> db.student_info.find().pretty()
{
        "_id" : ObjectId("5faa89297077300f4fc31d1c"),
        "name" : "tom",
        "age" : 18,
        "gender" : "M"
}
test_replset:SECONDARY> 

  提示:可以看到在secondary節點上能夠查詢到對應資料庫中的對應collection中插入的資料;

  驗證:在從節點上插入資料,看看是否能插入成功?

test_replset:SECONDARY> db.student_info.insert({name:"jerry",age:19,gender:"M"})
WriteCommandError({
        "topologyVersion" : {
                "processId" : ObjectId("5faa831bde03c4ae108f0be4"),
                "counter" : NumberLong(3)
        },
        "operationTime" : Timestamp(1605012904, 1),
        "ok" : 0,
        "errmsg" : "not master",
        "code" : 10107,
        "codeName" : "NotMaster",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605012904, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
})
test_replset:SECONDARY> 

  提示:我們在從節點上插入資料,它提示我們不是主節點,不允許插入資料;這說明副本集的從節點是不允許寫;

  驗證:將主節點上的mongodb服務停掉,然後在其他兩個節點上檢視副本集狀態,看看兩個節點是否重新選舉了master?

[root@node01 ~]# systemctl stop mongod.service 
[root@node01 ~]# ss -tnl
State      Recv-Q Send-Q           Local Address:Port                          Peer Address:Port              
LISTEN     0      128                          *:22                                       *:*                  
LISTEN     0      100                  127.0.0.1:25                                       *:*                  
LISTEN     0      128                         :::22                                      :::*                  
LISTEN     0      100                        ::1:25                                      :::*                  
[root@node01 ~]# mongo --host node02
MongoDB shell version v4.4.1
connecting to: mongodb://node02:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("90d60f76-fc95-44a8-bbf7-d927d5947331") }
MongoDB server version: 4.4.1
---
The server generated these startup warnings when booting: 
        2020-11-10T20:09:39.555+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
        2020-11-10T20:09:39.555+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
        2020-11-10T20:09:39.555+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never'
---
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).

        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.

        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
test_replset:PRIMARY> rs.status()
{
        "set" : "test_replset",
        "date" : ISODate("2020-11-10T12:59:25.775Z"),
        "myState" : 1,
        "term" : NumberLong(2),
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "majorityVoteCount" : 2,
        "writeMajorityCount" : 2,
        "votingMembersCount" : 3,
        "writableVotingMembersCount" : 3,
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1605013164, 1),
                        "t" : NumberLong(2)
                },
                "lastCommittedWallTime" : ISODate("2020-11-10T12:59:24.417Z"),
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1605013164, 1),
                        "t" : NumberLong(2)
                },
                "readConcernMajorityWallTime" : ISODate("2020-11-10T12:59:24.417Z"),
                "appliedOpTime" : {
                        "ts" : Timestamp(1605013164, 1),
                        "t" : NumberLong(2)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1605013164, 1),
                        "t" : NumberLong(2)
                },
                "lastAppliedWallTime" : ISODate("2020-11-10T12:59:24.417Z"),
                "lastDurableWallTime" : ISODate("2020-11-10T12:59:24.417Z")
        },
        "electionCandidateMetrics" : {
                "lastElectionReason" : "stepUpRequestSkipDryRun",
                "lastElectionDate" : ISODate("2020-11-10T12:58:34.398Z"),
                "electionTerm" : NumberLong(2),
                "lastCommittedOpTimeAtElection" : {
                        "ts" : Timestamp(1605013112, 1),
                        "t" : NumberLong(1)
                },
                "lastSeenOpTimeAtElection" : {
                        "ts" : Timestamp(1605013112, 1),
                        "t" : NumberLong(1)
                },
                "numVotesNeeded" : 2,
                "priorityAtElection" : 1,
                "electionTimeoutMillis" : NumberLong(10000),
                "priorPrimaryMemberId" : 0,
                "numCatchUpOps" : NumberLong(0),
                "newTermStartDate" : ISODate("2020-11-10T12:58:34.410Z"),
                "wMajorityWriteAvailabilityDate" : ISODate("2020-11-10T12:58:34.506Z")
        },
        "members" : [
                {
                        "_id" : 0,
                        "name" : "node01.test.org:27017",
                        "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("2020-11-10T12:59:24.558Z"),
                        "lastHeartbeatRecv" : ISODate("2020-11-10T12:58:35.045Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "Error connecting to node01.test.org:27017 (192.168.0.41:27017) :: caused by :: Connection refused",
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "configVersion" : 3,
                        "configTerm" : 1
                },
                {
                        "_id" : 1,
                        "name" : "node02:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 2987,
                        "optime" : {
                                "ts" : Timestamp(1605013164, 1),
                                "t" : NumberLong(2)
                        },
                        "optimeDate" : ISODate("2020-11-10T12:59:24Z"),
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "electionTime" : Timestamp(1605013114, 1),
                        "electionDate" : ISODate("2020-11-10T12:58:34Z"),
                        "configVersion" : 3,
                        "configTerm" : 2,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                },
                {
                        "_id" : 2,
                        "name" : "node03:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 1914,
                        "optime" : {
                                "ts" : Timestamp(1605013164, 1),
                                "t" : NumberLong(2)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1605013164, 1),
                                "t" : NumberLong(2)
                        },
                        "optimeDate" : ISODate("2020-11-10T12:59:24Z"),
                        "optimeDurableDate" : ISODate("2020-11-10T12:59:24Z"),
                        "lastHeartbeat" : ISODate("2020-11-10T12:59:24.459Z"),
                        "lastHeartbeatRecv" : ISODate("2020-11-10T12:59:25.506Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncSourceHost" : "node02:27017",
                        "syncSourceId" : 1,
                        "infoMessage" : "",
                        "configVersion" : 3,
                        "configTerm" : 2
                }
        ],
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605013164, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605013164, 1)
}
test_replset:PRIMARY> 

  提示:可以看到當node01上的mongodb服務停掉以後,對應的主節點也就不能夠正常的向從節點傳送心跳,所以剩下的兩個從節點都認為主節點掛了,此時他倆就開始重新選舉主節點;我們再次連線到node02上的mongodb檢視副本集狀態時,此時node02上的mongodb就成為了主節點;同時我們也能看到node01的健康狀態為0,表示不健康;

  檢視從節點的複製資訊

test_replset:PRIMARY> rs.printSecondaryReplicationInfo()
source: node01.test.org:27017
        syncedTo: Thu Jan 01 1970 08:00:00 GMT+0800 (CST)
        1605013534 secs (445837.09 hrs) behind the primary 
source: node03:27017
        syncedTo: Tue Nov 10 2020 21:05:34 GMT+0800 (CST)
        0 secs (0 hrs) behind the primary 
test_replset:PRIMARY>

  提示:這裡可以看到node01落後主節點很長時間,node03不落後主節點;

  檢視同步資訊時間視窗,以及oplog大小

test_replset:PRIMARY> rs.printReplicationInfo()
configured oplog size:   2048MB
log length start to end: 2291secs (0.64hrs)
oplog first event time:  Tue Nov 10 2020 20:27:23 GMT+0800 (CST)
oplog last event time:   Tue Nov 10 2020 21:05:34 GMT+0800 (CST)
now:                     Tue Nov 10 2020 21:05:35 GMT+0800 (CST)
test_replset:PRIMARY>

  提示:可以看到oplog的小為2048MB,日誌開始到結束的時間視窗為2291秒,意思是說當前啟動副本集到查詢複製資訊是的時長為2291秒;第一個oplog時間時間和最後oplog事件時間以及現在的時間都可檢視得到;

  移除節點(從副本集中,將node01節點移除)

test_replset:PRIMARY> rs.remove("node01.test.org:27017")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605014063, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605014063, 1)
}
test_replset:PRIMARY> rs.status()
{
        "set" : "test_replset",
        "date" : ISODate("2020-11-10T13:14:35.362Z"),
        "myState" : 1,
        "term" : NumberLong(2),
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "majorityVoteCount" : 2,
        "writeMajorityCount" : 2,
        "votingMembersCount" : 2,
        "writableVotingMembersCount" : 2,
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1605014074, 1),
                        "t" : NumberLong(2)
                },
                "lastCommittedWallTime" : ISODate("2020-11-10T13:14:34.514Z"),
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1605014074, 1),
                        "t" : NumberLong(2)
                },
                "readConcernMajorityWallTime" : ISODate("2020-11-10T13:14:34.514Z"),
                "appliedOpTime" : {
                        "ts" : Timestamp(1605014074, 1),
                        "t" : NumberLong(2)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1605014074, 1),
                        "t" : NumberLong(2)
                },
                "lastAppliedWallTime" : ISODate("2020-11-10T13:14:34.514Z"),
                "lastDurableWallTime" : ISODate("2020-11-10T13:14:34.514Z")
        },
        "electionCandidateMetrics" : {
                "lastElectionReason" : "stepUpRequestSkipDryRun",
                "lastElectionDate" : ISODate("2020-11-10T12:58:34.398Z"),
                "electionTerm" : NumberLong(2),
                "lastCommittedOpTimeAtElection" : {
                        "ts" : Timestamp(1605013112, 1),
                        "t" : NumberLong(1)
                },
                "lastSeenOpTimeAtElection" : {
                        "ts" : Timestamp(1605013112, 1),
                        "t" : NumberLong(1)
                },
                "numVotesNeeded" : 2,
                "priorityAtElection" : 1,
                "electionTimeoutMillis" : NumberLong(10000),
                "priorPrimaryMemberId" : 0,
                "numCatchUpOps" : NumberLong(0),
                "newTermStartDate" : ISODate("2020-11-10T12:58:34.410Z"),
                "wMajorityWriteAvailabilityDate" : ISODate("2020-11-10T12:58:34.506Z")
        },
        "members" : [
                {
                        "_id" : 1,
                        "name" : "node02:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 3897,
                        "optime" : {
                                "ts" : Timestamp(1605014074, 1),
                                "t" : NumberLong(2)
                        },
                        "optimeDate" : ISODate("2020-11-10T13:14:34Z"),
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "electionTime" : Timestamp(1605013114, 1),
                        "electionDate" : ISODate("2020-11-10T12:58:34Z"),
                        "configVersion" : 4,
                        "configTerm" : 2,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                },
                {
                        "_id" : 2,
                        "name" : "node03:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 2824,
                        "optime" : {
                                "ts" : Timestamp(1605014063, 1),
                                "t" : NumberLong(2)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1605014063, 1),
                                "t" : NumberLong(2)
                        },
                        "optimeDate" : ISODate("2020-11-10T13:14:23Z"),
                        "optimeDurableDate" : ISODate("2020-11-10T13:14:23Z"),
                        "lastHeartbeat" : ISODate("2020-11-10T13:14:33.958Z"),
                        "lastHeartbeatRecv" : ISODate("2020-11-10T13:14:33.970Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncSourceHost" : "node02:27017",
                        "syncSourceId" : 1,
                        "infoMessage" : "",
                        "configVersion" : 4,
                        "configTerm" : 2
                }
        ],
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605014074, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605014074, 1)
}
test_replset:PRIMARY> 

  提示:移除節點需要寫明對應節點的主機名地址和埠,或者是ip地址埠;這個字串必須是同加入到副本集中的名字相同才可移除,否則它會提示我們給定主機字串找不到;

  設定node03的優先順序為10

test_replset:PRIMARY> cfg = rs.conf()
{
        "_id" : "test_replset",
        "version" : 4,
        "term" : 2,
        "protocolVersion" : NumberLong(1),
        "writeConcernMajorityJournalDefault" : true,
        "members" : [
                {
                        "_id" : 1,
                        "host" : "node02:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "node03: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" : -1,
                "catchUpTakeoverDelayMillis" : 30000,
                "getLastErrorModes" : {

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("5faa85853d5a2d8fdf8af85e")
        }
}
test_replset:PRIMARY> cfg.members[1].priority = 10
10
test_replset:PRIMARY> rs.reconfig(cfg)
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605015945, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605015945, 1)
}
test_replset:PRIMARY> rs.config()
{
        "_id" : "test_replset",
        "version" : 5,
        "term" : 3,
        "protocolVersion" : NumberLong(1),
        "writeConcernMajorityJournalDefault" : true,
        "members" : [
                {
                        "_id" : 1,
                        "host" : "node02:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "node03:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 10,
                        "tags" : {

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

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("5faa85853d5a2d8fdf8af85e")
        }
}
test_replset:SECONDARY> 

  提示:設定某個成員的優先順序,首先要把當前配置用一個變數儲存,然後通過修改儲存的配置變數來修改優先順序以後,再使用rs.reconfig()來讀取修改後的配置即可生效;這裡需要注意我在修改配置檔案時指定成員,是指定對應成員在members列表的下標,而非id;所以修改前要先確定對應成員的下標是多少;我們修改了node03的優先順序以後,心細的你一定會發現node02此時就變成了secondary;這意味著,只要在副本集中有更高優先順序的成員加入,會觸發一次選舉,當然選舉成為主節點,影響最大的就是各節點的優先順序,優先順序越高,當選主節點的機率就越大;預設情況每個成員的優先順序都為1,優先順序設定的取值範圍是0-1000;

  將node01上的mongodb服務啟動起來,然後在主節點上將其新增為仲裁節點

  啟動node01上的mongodb服務

[root@node01 ~]# systemctl start mongod.service 
[root@node01 ~]# ss -tnl
State      Recv-Q Send-Q           Local Address:Port                          Peer Address:Port              
LISTEN     0      128                          *:22                                       *:*                  
LISTEN     0      100                  127.0.0.1:25                                       *:*                  
LISTEN     0      128                          *:27017                                    *:*                  
LISTEN     0      128                         :::22                                      :::*                  
LISTEN     0      100                        ::1:25                                      :::*                  
[root@node01 ~]# 

  在主節點上將node01新增為仲裁節點

test_replset:PRIMARY> rs.addArb("node01")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605016848, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605016848, 1)
}
test_replset:PRIMARY>

  檢視配置資訊,看看node01上的arbiterOnly是否變成了true?

test_replset:PRIMARY> rs.config()
{
        "_id" : "test_replset",
        "version" : 8,
        "term" : 3,
        "protocolVersion" : NumberLong(1),
        "writeConcernMajorityJournalDefault" : true,
        "members" : [
                {
                        "_id" : 1,
                        "host" : "node02:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "node03:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 10,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 3,
                        "host" : "node01:27017",
                        "arbiterOnly" : true,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 0,
                        "tags" : {

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

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("5faa85853d5a2d8fdf8af85e")
        }
}
test_replset:PRIMARY> 

  提示:可以看到node01節點上的arbiterOnly屬性已經啟用,說明這就是一個仲裁節點;我們說過仲裁節點上沒有儲存副本,我們到node01上看看是否儲存的有副本集資料呢?

test_replset:ARBITER> show databases
uncaught exception: Error: listDatabases failed:{
        "topologyVersion" : {
                "processId" : ObjectId("5faa9d87e504fa222c4a584d"),
                "counter" : NumberLong(1)
        },
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotMasterNoSlaveOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12
shellHelper.show@src/mongo/shell/utils.js:937:13
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1
test_replset:ARBITER> rs.secondaryOk()
test_replset:ARBITER> show databases
uncaught exception: Error: listDatabases failed:{
        "topologyVersion" : {
                "processId" : ObjectId("5faa9d87e504fa222c4a584d"),
                "counter" : NumberLong(1)
        },
        "ok" : 0,
        "errmsg" : "node is not in primary or recovering state",
        "code" : 13436,
        "codeName" : "NotMasterOrSecondary"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12
shellHelper.show@src/mongo/shell/utils.js:937:13
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1
test_replset:ARBITER> 

  提示:我們在仲裁節點上檢視資料庫列表,它提示我們不是主節點和從節點,不允許讀;既然都不允許讀,寫肯定是沒有辦法進行;

  ok,到此mongodb的副本集的配置、測試就到此為止;

相關文章