MongoDB4.2 副本集扫盲说明

说明:

  在扫盲MongoDB相关的一些知识的时候,顺手做下笔记。本文将说明副本集相关的内容。在比较早之前已经对这些有过说明,可以看MongoDB 副本集的原理、搭建、应用。MongoDB中的副本集是一组维护相同数据集的mongod进程,副本集提供冗余和高可用性,可提供一定程度的容错能力,以防止丢失单个数据库服务器,是生产部署的基础。

  在某些情况下,复制可以提供更大的读取容量,因为客户端可以将读取操作发送到不同的服务器。 在不同数据中心中维护数据副本可以提高数据本地性和分布式应用程序的可用性,还可以维护其他副本以用于专用目的,例如灾难恢复,报告或备份。

知识点:

  一个副本集最多有50个成员,并且最多7个成员有投票权。如果副本集已具有7个投票成员,则其他成员必须是非投票成员,确保副本集的投票成员数为奇数。

  副本集的所有成员都可以接受读取操作。 但默认情况下,应用程序将其读取操作定向到主要成员。 有关更改默认读取行为(读取首选项)请见:Read Preference。如果当前的主要节点不可用,则副本集会进行选择以选择哪个辅助节点成为新的主要节点。

  副本集成员每2秒钟彼此发送一次心跳(ping)。 如果心跳未在10秒(settings.electionTimeoutMillis)内响应,则其他成员将无法访问的成员标记为无法访问,如果是主节点,则会开始选举。集群选择新的主数据库之前的中值时间通常不应超过12秒。这包括将主要节点标记为不可用并完成选举所需的时间。优先级属性高的从更有可能成为主节点,优先级为0的,则不会参与选举。

  非投票成员的优先级必须为0,优先级大于0的成员必须有投票权。以下状态的成员才有资格具有投票权:

  即具有投票的节点,状态需要在上面列表中。如一个非投票成员的属性如:

{
   "_id" : <num>,
   "host" : <hostname:port>,
   "arbiterOnly" : false,
   "buildIndexes" : true,
   "hidden" : false,
   "priority" : 0,
   "tags" : {

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

1)Oplog

Oplog(操作日志)是一个特殊的capped集合,保持所有修改存储在数据库中的数据的操作的记录,类似于MySQL的Binlog,存储在local.oplog.rs集合中。

主节点的oplog异步同步到从节点,副本集可以在一个或多个成员失败的情况下继续运行。 从数据库成员将这些操作复制并应用本身。所有副本集成员都将心跳(ping)发送给所有其他成员,任何从成员都可以从任何其他成员应用操作日志。需要注意的时候,如果副本集只剩一个节点,该节点会变成从节点(不能写)。

操作日志中的每个操作都是幂等的,也就是说oplog操作会产生相同的结果,无论是一次还是多次应用于目标数据集。

OpLog大小通过参数oplogSizeMB设置,不设置的话 WiredTiger 存储引擎默认为空闲磁盘空间5%的大小,上限50G。可以在运行时,手动执行replSetResizeOplog来改变Oplog的大小。通过rs.printReplicationInfo()db.getReplicationInfo()来查看OpLog的状态:大小、可使用时间等。

从MongoDB 4.2开始,可以限制主数据库应用Oplog的写入速率,可以将从延迟保持在flowControlTargetLagSeconds < db.adminCommand({ setFeatureCompatibilityVersion: "4.2" }> 以下。

2)同步过程

初始化同步复制除local数据库外的所有数据库,mongod扫描每个源数据库中的每个集合,并将所有数据插入这些集合的自己的数据库中。

在版本3.4中更改:在为每个集合复制文档时,初始同步将构建所有集合索引(先同步索引,再同步数据)。 在早期版本的MongoDB中,在此阶段仅构建_id索引(先同步数据,再同步索引)。 

在版本3.4中更改:初始同步在数据复制期间提取新添加的操作日志记录。 确保目标成员在local数据库中具有足够的磁盘空间,以在此数据复制阶段持续时间临时存储这些操作日志记录。mongod使用源中的操作日志,将所有更改应用于数据集。初始同步完成后,成员将从STARTUP2转换为SECONDARY。

初始化时,同步源的选择取决于mongod启动参数initialSyncSourceReadPreference的值(4.2.7中的新增功能)。如果无法选择同步源,将记录错误并等待1秒钟,然后重新选择,从mongod最多可以重新初始同步源选择过程10次,然后错误退出。选择同步源的要求可以看这里

3)复制:多线程

MongoDB使用多线程批量应用写入操作以提高并发性。 MongoDB按文档ID(WiredTiger)对批次进行分组,并同时使用不同的线程来应用每组操作,MongoDB始终以原始写入顺序对给定文档应用写入操作。

4)成员

①  Primary:处理所有写操作。

② Secondaries:从主数据库(oplog)复制操作,并将操作应用于其数据集,以维护相同的数据集,其有各种属性:优先级、延迟、隐藏等。

③ Arbiter:仲裁节点,只投票,不保存数据,节省存储成本。从MongoDB 3.6开始,仲裁程序的优先级只能为0。因为不存储数据,所以不具有用于身份验证的用户和角色映射的内部表。在认证的情况下登录的唯一方法是使用localhost。

成员属性

① 优先级属性(Priority):优先级为0的成员不能成为Primary,并且不能触发选举,但能选举投票和读取。

② 隐藏属性(Hidden):优先级为0,有投票权。适用于具有与副本集中其他成员不同的使用模式的工作负载(备份<db.fsyncLock()>、报表)。mongos不会与隐藏成员交互。

③ 延迟属性(Delayed):用于恢复,必须是优先级为0的成员,有隐藏属性,可以有投票权。对于分片中的平衡作用有限。延迟单位为秒:

cfg = rs.conf()
cfg.members[0].priority = 0
cfg.members[0].hidden = true
cfg.members[0].slaveDelay = 3600
rs.reconfig(cfg)

④ 投票(votes):投票权为0的成员不能确定"majority" write concern。

⑤ 标签(tags):通过标签,可以设置readpreference、readConcern和writeConcern。

成员状态

状态值     状态名           状态说明
0       STARTUP       所有成员都以该状态启动,mongod在启动状态下解析副本集配置文档。
1       PRIMARY       主节点状态,唯一支持写的节点。有投票资格
2       SECONDARY      从节点状态,复制同步数据。有投票资格
3       RECOVERING     恢复状态,要么从完成回滚或重新同步过渡。有投票资格
5       STARTUP2      加入副本集,并正在运行初始同步。有投票资格
6       UNKNOWN       从副本集的另一个成员的角度来看,该成员的状态尚不清楚。没有投票资格
7       ARBITER      仲裁节点状态,不复制数据,仅存在于参加选举中。 有投票资格
8       DOWN         从副本集的另一个成员的角度来看,该成员不可访问。没有投票资格
9       ROLLBACK      回滚节点状态,无法从该成员读取数据。有投票资格
10      REMOVED        删除节点状态,从副本集中删除。

部署

环境:版本(4.2.8)

192.168.163.134:27017
192.168.163.134:27018
192.168.163.134:27019  

配置文件:其中一个节点的配置

systemLog:
   verbosity: 0
   quiet: false
   traceAllExceptions: false
   path: "/usr/local/mongodb_1/logs/mongodb.log"
   logAppend: true
   logRotate: rename
   destination: file
   timeStampFormat: iso8601-local

processManagement:
   fork: true
   pidFilePath: "/usr/local/mongodb_1/mongodb.pid"

net:
   port: 27017
   bindIp: 0.0.0.0
   maxIncomingConnections: 65536
   wireObjectCheck: true
   unixDomainSocket:
      enabled: true
      pathPrefix: /tmp
      filePermissions: 0700

security:
#   keyFile: "/usr/local/mongodb_1/test-keyfile"
   authorization: disabled

storage:
   dbPath: "/usr/local/mongodb_1/data"
   journal:
      enabled: true
      commitIntervalMs: 500
   directoryPerDB: true
   syncPeriodSecs: 60
   engine: wiredTiger
   wiredTiger:
      engineConfig:
         cacheSizeGB: 1
         journalCompressor: snappy
         directoryForIndexes: false
         maxCacheOverflowFileSizeGB: 0
      collectionConfig:
         blockCompressor: snappy
      indexConfig:
         prefixCompression: true

operationProfiling:
   # 指定应分析哪些操作,默认off:分析器已关闭,并且不收集任何数据;slowOp:收集比slowms的时间长的数据;all:收集所有操作的数据
   mode: slowOp
   # 慢操作时间阈值(以毫秒为单位),版本4.0中进行了更改:slowOpThresholdMs设置可用于mongod和mongos
   slowOpThresholdMs: 100
   # 分析记录慢速操作
   slowOpSampleRate: 1.0
   # 过滤器,记录耗时超过2秒的查询操作
   #filter: '{ op: "query", millis: { $gt: 2000 } }'

replication:
   oplogSizeMB: 100
   replSetName: shard1
   enableMajorityReadConcern: false

sharding:
   clusterRole: shardsvr
   archiveMovedChunks: false
   # mongos配置项,指定配置服务器
   #configDB: <configReplSetName>/cfg1.example.net:27019, cfg2.example.net:27019,...
View Code

按照配置文件里的配置,创建好各个目录。

启动节点:3个节点 

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb_1/mongo.conf 

搭建:

①:无认证搭建authorization: disabled

> rs.initiate(
    {
    _id : 'shard1',
    members: [
    { _id : 0, host : "192.168.163.134:27017" },
    { _id : 1, host : "192.168.163.134:27018" },
    { _id : 2, host : "192.168.163.134:27019" }
              ]
    } 
   )

说明:副本集为shard1,3个成员(PSS) 

"_id": 副本集的名称
"members": 副本集的服务器列表
  "_id": 成员的ID
  "host": 成员的地址和端口
-- 以上是必填的,下面的成员属性按照需要设置:
  "priority": 是优先级,默认为1,优先级0为被动节点,不能成为活跃节点。优先级不为0则按照有大到小选出活跃节点。
  "arbiterOnly": 仲裁节点,只参与投票,不接收数据,也不能成为活跃节点。
  "hidden": 隐藏节点,优先级和投票必须为0。
  "votes": 投票资格,0为没有投票资格;1为有投票资格。
  "slaveDelay": 延迟节点,单位为秒。
  "tags": 标签属性。

可以通过日志看到副本集初始化的一些具体信息:

2021-02-24T07:54:29.381+0000 I  REPL     [initandlisten] Did not find local initialized voted for document at startup.
2021-02-24T07:54:29.381+0000 I  REPL     [initandlisten] Did not find local Rollback ID document at startup. Creating one.
2021-02-24T07:54:29.423+0000 I  REPL     [initandlisten] Initialized the rollback ID to 1
2021-02-24T07:54:29.423+0000 I  REPL     [initandlisten] Did not find local replica set configuration document at startup;  NoMatchingDocument: Did not find replica set configuration document in local.system.replset
2021-02-24T07:55:57.511+0000 I  REPL     [conn2] replSetInitiate admin command received from client
2021-02-24T07:55:57.517+0000 I  REPL     [conn2] replSetInitiate config object with 3 members parses ok
2021-02-24T07:55:57.517+0000 I  REPL     [conn2] Scheduling remote command request for initiate quorum check: RemoteCommand 1 -- target:192.168.163.134:27018 db:admin cmd:{ replSetHeartbeat: "shard1", checkEmpty: true, configVersion: 1, hbv: 1, from: "192.168.163.134:27017", fromId: 0, term: 0 }
2021-02-24T07:55:57.517+0000 I  REPL     [conn2] Scheduling remote command request for initiate quorum check: RemoteCommand 2 -- target:192.168.163.134:27019 db:admin cmd:{ replSetHeartbeat: "shard1", checkEmpty: true, configVersion: 1, hbv: 1, from: "192.168.163.134:27017", fromId: 0, term: 0 }
2021-02-24T07:55:57.521+0000 I  REPL     [conn2] ******
2021-02-24T07:55:57.522+0000 I  REPL     [conn2] creating replication oplog of size: 100MB...
2021-02-24T07:55:57.582+0000 I  REPL     [conn2] ******
2021-02-24T07:55:57.674+0000 I  REPL     [conn2] New replica set config in use: { _id: "shard1", version: 1, protocolVersion: 1, writeConcernMajorityJournalDefault: true, members: [ { _id: 0, host: "192.168.163.134:27017", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 1.0, tags: {}, slaveDelay: 0, votes: 1 }, { _id: 1, host: "192.168.163.134:27018", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 1.0, tags: {}, slaveDelay: 0, votes: 1 }, { _id: 2, host: "192.168.163.134:27019", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 1.0, tags: {}, slaveDelay: 0, votes: 1 } ], settings: { chainingAllowed: true, heartbeatIntervalMillis: 2000, heartbeatTimeoutSecs: 10, electionTimeoutMillis: 10000, catchUpTimeoutMillis: -1, catchUpTakeoverDelayMillis: 30000, getLastErrorModes: {}, getLastErrorDefaults: { w: 1, wtimeout: 0 }, replicaSetId: ObjectId('6036068d6eda8e54419e12a1') } }
2021-02-24T07:55:57.675+0000 I  REPL     [conn2] This node is 192.168.163.134:27017 in the config
2021-02-24T07:55:57.675+0000 I  REPL     [conn2] transition to STARTUP2 from STARTUP
2021-02-24T07:55:57.676+0000 I  REPL     [replexec-0] Member 192.168.163.134:27018 is now in state STARTUP
2021-02-24T07:55:57.676+0000 I  REPL     [replexec-0] Member 192.168.163.134:27019 is now in state STARTUP
2021-02-24T07:55:57.676+0000 I  REPL     [conn2] Starting replication storage threads
2021-02-24T07:55:57.678+0000 I  REPL     [conn2] transition to RECOVERING from STARTUP2
2021-02-24T07:55:57.678+0000 I  REPL     [conn2] Starting replication fetcher thread
2021-02-24T07:55:57.678+0000 I  REPL     [conn2] Starting replication applier thread
2021-02-24T07:55:57.678+0000 I  REPL     [conn2] Starting replication reporter thread
2021-02-24T07:55:57.680+0000 I  REPL     [rsSync-0] Starting oplog application
2021-02-24T07:55:57.711+0000 I  REPL     [rsSync-0] transition to SECONDARY from RECOVERING
2021-02-24T07:55:57.711+0000 I  REPL     [rsSync-0] Resetting sync source to empty, which was :27017
2021-02-24T07:55:57.711+0000 I  REPL     [rsBackgroundSync] waiting for 2 pings from other members before syncing
2021-02-24T07:55:58.177+0000 I  REPL     [replexec-1] Member 192.168.163.134:27018 is now in state STARTUP2
2021-02-24T07:55:58.177+0000 I  REPL     [replexec-1] Member 192.168.163.134:27019 is now in state STARTUP2
2021-02-24T07:55:59.681+0000 I  REPL     [replexec-0] Member 192.168.163.134:27018 is now in state SECONDARY
2021-02-24T07:55:59.681+0000 I  REPL     [replexec-0] Member 192.168.163.134:27019 is now in state SECONDARY
2021-02-24T07:56:07.922+0000 I  REPL     [replexec-0] Scheduling remote command request for vote request: RemoteCommand 45 -- target:192.168.163.134:27018 db:admin cmd:{ replSetRequestVotes: 1, setName: "shard1", dryRun: true, term: 0, candidateIndex: 0, configVersion: 1, lastCommittedOp: { ts: Timestamp(1614153357, 1), t: -1 } }
2021-02-24T07:56:07.922+0000 I  REPL     [replexec-0] Scheduling remote command request for vote request: RemoteCommand 46 -- target:192.168.163.134:27019 db:admin cmd:{ replSetRequestVotes: 1, setName: "shard1", dryRun: true, term: 0, candidateIndex: 0, configVersion: 1, lastCommittedOp: { ts: Timestamp(1614153357, 1), t: -1 } }
2021-02-24T07:56:07.926+0000 I  REPL     [replexec-1] Scheduling remote command request for vote request: RemoteCommand 47 -- target:192.168.163.134:27018 db:admin cmd:{ replSetRequestVotes: 1, setName: "shard1", dryRun: false, term: 1, candidateIndex: 0, configVersion: 1, lastCommittedOp: { ts: Timestamp(1614153357, 1), t: -1 } }
2021-02-24T07:56:07.928+0000 I  REPL     [replexec-1] Scheduling remote command request for vote request: RemoteCommand 48 -- target:192.168.163.134:27019 db:admin cmd:{ replSetRequestVotes: 1, setName: "shard1", dryRun: false, term: 1, candidateIndex: 0, configVersion: 1, lastCommittedOp: { ts: Timestamp(1614153357, 1), t: -1 } }
2021-02-24T07:56:07.929+0000 I  REPL     [replexec-0] transition to PRIMARY from SECONDARY
2021-02-24T07:56:07.929+0000 I  REPL     [replexec-0] Resetting sync source to empty, which was :27017
2021-02-24T07:56:07.930+0000 I  REPL     [replexec-0] Entering primary catch-up mode.
2021-02-24T07:56:07.931+0000 I  REPL     [replexec-0] Caught up to the latest optime known via heartbeats after becoming primary. Target optime: { ts: Timestamp(1614153357, 1), t: -1 }. My Last Applied: { ts: Timestamp(1614153357, 1), t: -1 }
2021-02-24T07:56:07.931+0000 I  REPL     [replexec-0] Exited primary catch-up mode.
2021-02-24T07:56:07.931+0000 I  REPL     [replexec-0] Stopping replication producer
2021-02-24T07:56:07.931+0000 I  REPL     [ReplBatcher] Oplog buffer has been drained in term 1
2021-02-24T07:56:07.932+0000 I  REPL     [ReplBatcher] Oplog buffer has been drained in term 1
2021-02-24T07:56:07.932+0000 I  REPL     [RstlKillOpThread] Starting to kill user operations
2021-02-24T07:56:07.932+0000 I  REPL     [RstlKillOpThread] Stopped killing user operations
2021-02-24T07:56:07.932+0000 I  REPL     [RstlKillOpThread] State transition ops metrics: { lastStateTransition: "stepUp", userOpsKilled: 0, userOpsRunning: 0 }
2021-02-24T07:56:07.983+0000 I  REPL     [rsSync-0] transition to primary complete; database writes are now permitted
View Code

大致的流程是:检查配置、初始化local库的各个集合、转换各个成员的状态(STARTUP -> STARTUP2 -> RECOVERING -> SECONDARY)、10秒后开始选举(SECONDARY -> PRIMARY

TIP:

可以把副本集的配置先声明好,再用replSetInitiate进行初始化(PSA):

> cfg = {
    _id : 'shard1',
    members: [
    { _id : 0, host : "192.168.163.134:27017" },
    { _id : 1, host : "192.168.163.134:27018" },
    { _id : 2, host : "192.168.163.134:27019", arbiterOnly: true }
              ]
    } 

> db.runCommand({ replSetInitiate : cfg })
或则
> rs.initiate(cfg)

②:有认证搭建authorization: true)

从安全上考虑,需要为实例添加用户来进行访问控制。在添加了认证的实例上,副本集各个成员之间的访问就需要认证,现在来说明通过Keyfile的方式进行成员间的认证。

1. 创建keyfile:使用YAML格式,长度为6~1024字符,并且只能包含base64集中的字符

 使用keyfile进行身份验证,副本集中的每个mongod实例都将keyfile的内容用作共享密码来进行身份验证。生成方法:

openssl rand -base64 756 > xx_keyfile
chmod 400 xx_keyfile  --Linux需要

2. 生成好keyfile之后,副本集中的所有成员都共享该文件,复制到各个实例的目录,并修改配置文件参数:开启了keyFile参数之后,认证自动启动(authorization)。

security:
   keyFile: "/usr/local/mongodb_1/xx_keyfile"
   authorization: enabled

3. 开启实例,并进行部署:

-- 启动3个节点
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb_1/mongo.conf 

-- 初始化副本集
> rs.initiate(
    {
    _id : 'shard1',
    members: [
    { _id : 0, host : "192.168.163.134:27017" },
    { _id : 1, host : "192.168.163.134:27018" },
    { _id : 2, host : "192.168.163.134:27019" }
              ]
    } 
   )

-- 创建管理用户
> db.createUser(
{
user:'dba',
pwd:passwordPrompt(),
roles:[{role:'root',db:'admin'}],
customData:{name:'运维账号'}
}
)

注意:当认证开启之后,第一次必须创建管理用户,后续的登录需要认证才能操作。到此,副本集部署已经完成,部署比较简单,更多的部署信息可以看官方文档说明。

副本集维护

维护方面的包括很多:扩容、缩容、修改属性、副本集命令行等等,本节开始对日常工作中遇到的一些操作进行说明,关于副本集的一些命令说明可以看文档

1. 扩容

新增节点rs.add(host, arbiterOnly):参数为字符串或则文档,arbiterOnly可选,在host为字符串的时候使用。

字符串的格式为:主机名(IP)和端口:

IP:Port

文档的格式为:

{
   _id: <int>,
   host: <string>,
   arbiterOnly: <boolean>,
   buildIndexes: <boolean>,
   hidden: <boolean>,
   priority: <number>,
   tags: <document>,
   slaveDelay: <int>,
   votes: <number>
}

① 用主机参数添加:该方式添加的成员属性是默认的。

> rs.add("192.168.163.134:27019")

② 用文档参数添加:该方式添加的成员属性可以自定义。如添加一个优先级为0的隐藏节点:

> rs.add({"_id":3,"host":"192.168.163.134:27019","priority":0,"hidden":true})

此外,还可以添加其他属性的成员,比如:延迟、投票、标签、仲裁等等。

除了用rs.add添加之外,还可以用replSetReconfig(rs.reconfig)来修改配置进行添加,其中仲裁节点可以用rs.addArb来进行快速添加。

③ 添加仲裁节点:rs.addArb(host) 

> rs.addArb('192.168.163.134:27019')

2. 缩容

移除节点rs.remove(hostname):参数为字符串

字符串的格式为:主机名(IP)和端口:

IP:Port

从集群中移除刚添加的隐藏节点:

> rs.remove("192.168.163.134:27019")

除了用rs.remove移除之外,还可以用replSetReconfig(rs.reconfig)来修改配置进行移除。需要注意的运行rs.remove之前,最好关闭要删除的副本集成员。

默认情况下,副本集成员需要等待5分钟,然后再断开与已删除成员的连接,4.2之后可以在其余其他成员上执行以下命令来关闭连接:

db.adminCommand(
  {
    "dropConnections" : 1,
    "hostAndPort" : [
      "192.168.163.134:27019"
    ]
  }
)

3. 修改成员属性rs.reconfig(configuration, force):参数为配置文档,force:强制副本集接受新配置,即使大多数成员不可访问,允许向非主节点发出重新配置命令:rs.reconfig(cfg,{force:true}) 重新配置现有副本集,覆盖现有的配置,默认必须连接到副本集的主数据库。在某些情况下,rs.reconfig可以触发当前主数据库降级,通过该方法实现的主库降级,新选出来的主大概需要花费10~12秒,后面有自动降级的方法可以减少选主时间。

4.2开始,当主数据库降级时,不再关闭所有客户端连接,并且正在进行的写入将被杀死。
4.0和更早版本中,当主数据库降级时,它将关闭所有客户端连接。

指定某一个成员为主,修改其优先级为所有成员中最大:

① 获取副本集配置文档

> cfg = rs.conf()

② 修改文档中指定成员的属性:优先级

> cfg.members[1].priority = 2

③ 新文档生效

> rs.reconfig(cfg)

大概10~12秒左右,会完成新主的选举。也可以主动降级来加快新主的选择,用rs.stepDown

4. 主节点降级为备份节点rs.stepDown(stepDownSecs, secondaryCatchUpPeriodSecs)

该方法不会立即降级主库, 如果没有可选举的从节点,则主节点将等待secondaryCatchUpPeriodSecs(默认为10秒),以等待从节点赶上。 一旦可以选择的从节点可用,就降级主节点。降级后,原始的主节点将成为从节点,并且在stepDownSecs指定的剩余时间内没有资格再次成为主节点,默认60秒。

4.2开始,rs.stepDown方法不再关闭所有客户端连接
4.0和更早版本中,rs.stepDown方法在降级期间关闭所有客户端连接

和3中的步骤一样,可以先修改优先级属性,再在主节点上执行:

> rs.stepDown(60,10)

注意:rs.stepDown开始的时间段内,所有对主的写入都会失败,直到选择了新的主数据库,或者如果没有可选举的辅助数据库,则原始主数据库将恢复正常操作。正在进行的写入将被杀死,正在进行的事务也会因“ TransientTransactionError”而失败,并且可以整体重试。写入失败的时间最多为20秒:

secondaryCatchUpPeriodSecs(默认为10秒)+选举超时Millis(默认为10秒)

5. 让从节点在一定时间内不能成为主节点rs.freeze(seconds)

始终出于备份节点状态,强制他们出于从节点状态。比如在需要对副本集的各个节点进行轮询的维护,在优先级高的节点上执行了降级之后,虽然暂时成为了从节点,但在下个选举周期还是会被选举成为主节点,如果维护的时间比较长,可以在降级之后再执行,让他完成维护操作为止。

> rs.freeze(3600)

如果修改完操作之后,需要恢复,则可以直接用0来执行,不阻止升级为主节点:

> rs.freeze(0)

6. 修改同步源rs.syncFrom(hostname):参数为IP:Port

修改当前成员的默认同步目标。 以[主机名]:[端口]的形式指定要复制的成员的名称。从版本3.2中开始:具有投票权(>0)的副本集成员不能与没有投票权(0)的成员同步。

配置好的副本集都是自动的对同步源进行分配,根据pingMS来寻找最新的数据源,可能某个Secondary是另一个Secondary的同步源。如果当前主节点(PSS)的压力比较大,可以修改从节点的同步目标,修改到另一个成员,组成一个链级的复制(P -> S -> S),减轻主节点的压力,但可能会出现复制延迟不可控的情况。

① 查看同步源

shard1:SECONDARY> db.adminCommand({"replSetGetStatus":1}).syncingTo
192.168.163.134:27018
shard1:SECONDARY> rs.status().syncingTo
192.168.163.134:27018

② 修改同步源

shard1:SECONDARY> rs.syncFrom("192.168.163.134:27017")
{
    "syncFromRequested" : "192.168.163.134:27017",
    "prevSyncTarget" : "192.168.163.134:27018",
    "ok" : 1
}


> db.adminCommand({"replSetSyncFrom":"192.168.163.134:27017"})
{
    "syncFromRequested" : "192.168.163.134:27017",
    "prevSyncTarget" : "192.168.163.134:27018",
    "ok" : 1
}

7. 查看主从节点的延迟和OpLog信息rs.printReplicationInfo()rs.printSlaveReplicationInfo() 

shard1:PRIMARY> rs.printSlaveReplicationInfo()
source: 192.168.163.134:27017   --从节1点的落后时间
    syncedTo: Thu Feb 25 2021 09:27:05 GMT+0000 (UTC)
    0 secs (0 hrs) behind the primary 
source: 192.168.163.134:27019   --从节点2的落后时间
    syncedTo: Thu Feb 25 2021 09:27:05 GMT+0000 (UTC)
    0 secs (0 hrs) behind the primary 

shard1:PRIMARY> rs.printReplicationInfo()
configured oplog size:   100MB        --oplog大小
log length start to end: 25707secs (7.14hrs)  --oplog使用的时间长度
oplog first event time:  Thu Feb 25 2021 02:18:28 GMT+0000 (UTC)   -- 第一次操作时间
oplog last event time:   Thu Feb 25 2021 09:26:55 GMT+0000 (UTC)     -- 最后一次操作时间
now:                     Thu Feb 25 2021 09:26:59 GMT+0000 (UTC)    --当前时间

以上的几种方法是日常维护副本集会用到的,还有其他的比如:

db.serverStatus() == db.runCommand( { serverStatus: 1 } )

可带参数:db.serverStatus( { repl: 0,  metrics: 0, locks: 0 } )、db.runCommand( { serverStatus: 1, repl: 0, metrics: 0, locks: 0 } )

XYZ:PRIMARY> db.runCommand( { serverStatus: 1 } )
{
    "host" : "lbs-postgresql01",    -- 主机名
    "version" : "4.2.8",            -- 版本
    "process" : "mongod",            -- 进程名,可能的值为:mongos或mongod
    "pid" : NumberLong(27568),        -- pid
    "uptime" : 30149,                -- 服务运行时间(秒)
    "uptimeMillis" : NumberLong(30149594),    -- 服务运行时间(毫秒)
    "uptimeEstimate" : NumberLong(30149),    -- 服务运行时间(秒),根据MongoDB内部处理统计
    "localTime" : ISODate("2020-08-13T09:20:24.614Z"),    -- 根据服务器,以UTC表示当前时间的ISODate
    "asserts" : {    -- 报告自MongoDB流程启动以来提出的断言数量的文档。虽然断言错误通常很少见,但是如果断言的值不为零,则应检查日志文件以获取更多信息。
        "regular" : 0,    -- 自MongoDB流程开始以来提出的常规声明的数量。检查日志文件以获取有关这些消息的更多信息。
        "warning" : 0,    -- 该字段返回自MongoDB进程启动以来引发的警告数,从MongoDB 4.0开始,该字段返回零0
        "msg" : 0,        -- 自MongoDB进程启动以来引发的消息声明的数量。检查日志文件以获取有关这些消息的更多信息。
        "user" : 2244,    -- 自上次启动MongoDB进程以来发生的“用户断言”数量。 如磁盘空间不足或重复密钥。
        "rollovers" : 0    -- 自上次MongoDB进程启动以来,翻转计数器已翻转的次数。 230个断言后,计数器将翻转为零。
    },
    "connections" : {  -- 报告连接状态的文档。使用这些值可以评估服务器的当前负载和容量要求。
        "current" : 11,    -- 当前连接数
        "available" : 52417,    -- 可用连接数
        "totalCreated" : 38,    -- 总创建的连接数
        "active" : 2            -- 活跃连接数
    },
    "electionMetrics" : {     -- 选举信息
        "stepUpCmd" : {        -- Primary down时,在选举交接中调用的选举指标
            "called" : NumberLong(0),
            "successful" : NumberLong(0)
        },
        "priorityTakeover" : {    -- 由mongod实例调用的选举指标,因为其优先级高于Primary
            "called" : NumberLong(0),
            "successful" : NumberLong(0)
        },
        "catchUpTakeover" : {    -- 由mongod实例调用的选举指标,因为其数据比Primary新
            "called" : NumberLong(0),
            "successful" : NumberLong(0)
        },
        "electionTimeout" : {    -- 由mongod实例调用的选举指标,因为其无法在settings.electionTimeoutMillis内到达Primary
            "called" : NumberLong(1),
            "successful" : NumberLong(1)
        },
        "freezeTimeout" : {        -- mongod实例在冻结期(成员无法申请选举)之后调用的选举指标
            "called" : NumberLong(0),
            "successful" : NumberLong(0)
        },
        "numStepDownsCausedByHigherTerm" : NumberLong(0),   -- 由于更高的任期(term),该mongod实例down的次数
        "numCatchUps" : NumberLong(0),                        -- 作为新当选的主必须赶上已知的最高oplog条目的选举次数
        "numCatchUpsSucceeded" : NumberLong(0),                -- 作为新当选的主成功追上已知的最高oplog条目的次数
        "numCatchUpsAlreadyCaughtUp" : NumberLong(1),        -- 作为新当选的主完成追赶的次数,因为当选时已经被追赶
        "numCatchUpsSkipped" : NumberLong(0),                -- 作为新当选的主跳过追赶过程的次数
        "numCatchUpsTimedOut" : NumberLong(0),                -- 由于settings.catchUpTimeoutMillis限制,作为新当选的主完成其追赶过程的次数
        "numCatchUpsFailedWithError" : NumberLong(0),        -- 新当选的主追赶过程因错误而失败的次数
        "numCatchUpsFailedWithNewTerm" : NumberLong(0),        -- 由于另一位成员的任期较高(即其他一位或多位议员参加了其他选举),新当选的主追赶过程结束的次数
        "numCatchUpsFailedWithReplSetAbortPrimaryCatchUpCmd" : NumberLong(0),    -- 由于收到replSetAbortPrimaryCatchUp命令而导致的新当选的主追赶过程结束的次数
        "averageCatchUpOps" : 0                                -- 新当选的主在赶超过程中平均执行的操作数
    },
    "extra_info" : {                                        -- 提供有关基础系统的其他信息的文档
        "note" : "fields vary by platform",                    -- 文本为“字段因平台而异”的字符串
        "user_time_us" : NumberLong(114316152),                -- 用户使用的CPU时间
        "system_time_us" : NumberLong(19584160),            -- 内核使用的CPU时间
        "maximum_resident_set_kb" : NumberLong(91260),        -- 执行程序所占用内存的最大值。单位是 KB
        "input_blocks" : NumberLong(0),                        -- 输入块
        "output_blocks" : NumberLong(263944),                -- 输出块
        "page_reclaims" : NumberLong(97588),                -- 页回收数量
        "page_faults" : NumberLong(0),                        -- 数量错误数量
        "voluntary_context_switches" : NumberLong(1497531),    -- 主动上下文切换数量
        "involuntary_context_switches" : NumberLong(3283)    -- 被动上下文切换数量
    },
    "flowControl" : {            -- 使用流量控制时最大滞后时间。将尝试将大多数的延迟保持在指定的秒数内(10秒)https://docs.mongodb.com/v4.2/reference/parameters/#param.enableFlowControl
        "enabled" : true,        -- 是否开启,https://docs.mongodb.com/v4.2/reference/parameters/#param.enableFlowControl
        "targetRateLimit" : 1000000000,                -- 主服务器上运行时,每秒可以获取的最大票证数量;辅助服务器上运行时,返回的数字是占位符
        "timeAcquiringMicros" : NumberLong(780),    -- 主数据库上运行时,写操作等待获取票证的总时间;辅助服务器上运行时,返回的数字是占位符
        "locksPerOp" : 1.167,                        -- 主服务器上运行时,近似于每个操作获取的锁数;辅助服务器上运行时,返回的数字是占位符
        "sustainerRate" : 0,                        -- 主服务器上运行时,辅助服务器每秒维持提交点的每秒近似操作数;辅助服务器上运行时,返回的数字是占位符
        "isLagged" : false,                            -- 主数据库上运行时,是否已使用流控制。 当大多数承诺滞后时间大于已配置的flowControlTargetLagSeconds的某个百分比时,将启用流控制
        "isLaggedCount" : 0,                        -- 主服务器上运行时,自上次重新启动以来流控制已参与的次数;辅助服务器上运行时,返回的数字是占位符
        "isLaggedTimeMicros" : NumberLong(0)        -- 主服务器上运行时,自上次重新启动以来已花费了多少时间进行流控制
    },
    "freeMonitoring" : {                            -- 是否开启云监控
        "state" : "undecided"
    },
    "globalLock" : {                                -- 报告数据库锁定状态的文档,
        "totalTime" : NumberLong("30149591000"),    -- 自数据库启动并创建globalLock以来的时间(以微秒为单位)。这大致相当于服务器的总正常运行时间。
        "currentQueue" : {                            -- 由于锁而排队的操作数的信息的文档
            "total" : 0,                            -- 排队等待锁定的操作总数(即globalLock.currentQueue.readers和globalLock.currentQueue.writers的总和)
            "readers" : 0,                            -- 当前排队并等待读锁定的操作数。始终较小的读取队列,尤其是较短的操作,不会引起任何问题。
            "writers" : 0                            -- 当前排队并等待写锁定的操作数。始终较小的写队列,尤其是较短操作的写队列,无需担心。
        },
        "activeClients" : {                            -- 提供有关已连接客户端数量以及这些客户端执行的读取和写入操作的信息的文档。
            "total" : 0,                            -- 与数据库的内部客户端连接总数,包括系统线程以及排队的读取器和写入器。
            "readers" : 0,                            -- 执行读取操作的活动客户端连接数。
            "writers" : 0                            -- 执行写操作的活动客户端连接数。
        }
    },
    "locks" : {                                        -- 针对每个锁<类型>报告有关锁<模式>的数据的文档。https://docs.mongodb.com/v4.2/reference/command/serverStatus/#locks
        "ParallelBatchWriterMode" : {                -- 并行批处理写入器模式的锁
            "acquireCount" : {                        -- 在指定模式下获取锁定的次数
                "r" : NumberLong(32460)                -- 意向读锁(IS)
            }
        },
        "ReplicationStateTransition" : {            -- 副本集成员状态转换的锁定
            "acquireCount" : {                        -- 在指定模式下获取锁定的次数
                "w" : NumberLong(209603),            -- 意向写锁(IX)
                "W" : NumberLong(2)                    -- 排他(X)锁
            },
            "acquireWaitCount" : {                    -- 由于锁处于冲突模式而导致的locks.acquireCount锁获取遇到的等待次数。
                "w" : NumberLong(2),                -- 意向写锁(IX)
                "W" : NumberLong(1)                    -- 排他(X)锁
            },
            "timeAcquiringMicros" : {                -- 锁定获取的累积等待时间(以微秒为单位)
                "w" : NumberLong(175),                -- 意向写锁(IX)
                "W" : NumberLong(2)                    -- 排他(X)锁
            }
        },
        "Global" : {                                -- 全局锁
            "acquireCount" : {                        -- 在指定模式下获取锁定的次数
                "r" : NumberLong(206263),            -- 意向读锁(IS)
                "w" : NumberLong(3335),                -- 意向写锁(IX)
                "W" : NumberLong(5)                    -- 排他(X)锁
            },
            "acquireWaitCount" : {                    -- 由于锁处于冲突模式而导致的locks.acquireCount锁获取遇到的等待次数。
                "w" : NumberLong(1),                -- 意向写锁(IX)
                "W" : NumberLong(1)                    -- 排他(X)锁
            },
            "timeAcquiringMicros" : {                -- 锁定获取的累积等待时间(以微秒为单位)
                "w" : NumberLong(11524),            -- 意向写锁(IX)
                "W" : NumberLong(36)                -- 排他(X)锁
            }
        },
        "Database" : {                                -- 数据库锁
            "acquireCount" : {                        -- 在指定模式下获取锁定的次数
                "r" : NumberLong(145945),            -- 意向读锁(IS)
                "w" : NumberLong(496),                -- 意向写锁(IX)
                "W" : NumberLong(27)                -- 排他(X)锁
            },
            "acquireWaitCount" : {                    -- 由于锁处于冲突模式而导致的locks.acquireCount锁获取遇到的等待次数。
                "r" : NumberLong(2)                    -- 意向读锁(IS)
            },
            "timeAcquiringMicros" : {                -- 锁定获取的累积等待时间(以微秒为单位)
                "r" : NumberLong(10074)                -- 意向读锁(IS)
            }
        },
        "Collection" : {                            -- 集合锁
            "acquireCount" : {                        -- 在指定模式下获取锁定的次数
                "r" : NumberLong(34475),            -- 意向读锁(IS)
                "w" : NumberLong(494),                -- 意向写锁(IX)
                "R" : NumberLong(1),                -- 共享(S)锁
                "W" : NumberLong(18)                -- 排他(X)锁
            }
        },
        "Metadata" : {                                -- 元数据锁
            "acquireCount" : {                        -- 在指定模式下获取锁定的次数
                "W" : NumberLong(1)                    -- 排他(X)锁
            }
        },
        "Mutex" : {                                    -- 互斥锁
            "acquireCount" : {                        -- 在指定模式下获取锁定的次数
                "r" : NumberLong(126997)            -- 意向(IS)
            }
        },
        "oplog" : {                                    -- oplog锁
            "acquireCount" : {                        -- 在指定模式下获取锁定的次数
                "r" : NumberLong(115593),            -- 意向读锁(IS)
                "w" : NumberLong(2),                -- 共享(S)锁
                "W" : NumberLong(1)                    -- 排他(X)锁
            }
        }
    },
    "logicalSessionRecordCache" : {            -- 提供有关服务器会话缓存的指标
        "activeSessionsCount" : 1,            -- 自上次刷新周期以来,由mongod或mongos实例缓存在内存中所有活动的本地会话数。
        "sessionsCollectionJobCount" : 101,    -- 跟踪刷新过程在config.system.sessions集合上运行的次数的数字。
        "lastSessionsCollectionJobDurationMillis" : 4,    -- 上次刷新的时间(以毫秒为单位)
        "lastSessionsCollectionJobTimestamp" : ISODate("2020-08-13T09:17:55.863Z"),        -- 上次刷新发生的时间
        "lastSessionsCollectionJobEntriesRefreshed" : 1,    -- 在上次刷新期间刷新的会话数。
        "lastSessionsCollectionJobEntriesEnded" : 0,        -- 在上一次刷新期间结束的会话数。
        "lastSessionsCollectionJobCursorsClosed" : 0,        -- 在上一次config.system.sessions集合刷新期间关闭的游标数。
        "transactionReaperJobCount" : 101,                    -- 跟踪事务记录清除过程已在config.transactions集合上运行的次数的数字。
        "lastTransactionReaperJobDurationMillis" : 0,        -- 上次事务记录清除的长度(以毫秒为单位)
        "lastTransactionReaperJobTimestamp" : ISODate("2020-08-13T09:17:55.863Z"),    -- 上次事务记录清除的时间
        "lastTransactionReaperJobEntriesCleanedUp" : 0,        -- config.transactions集合中上次事务记录清除期间删除的条目数。
        "sessionCatalogSize" : 0                            -- 对于mongod实例,config.transactions条目的内存缓存大小;对于mongos实例:localLogicalSessionTimeoutMinutes内未过期的可重试写入或事务
    },
    "network" : {                                    -- MongoDB网络使用情况数据的文档。https://docs.mongodb.com/v4.2/reference/command/serverStatus/#network
        "bytesIn" : NumberLong(25843431),            -- 接收的网络流量的字节数
        "bytesOut" : NumberLong(32178855),            -- 发送的网络流量的字节数
        "physicalBytesIn" : NumberLong(18156427),
        "physicalBytesOut" : NumberLong(22163279),
        "numRequests" : NumberLong(57762),            -- 收到的不同请求的总数
        "compression" : {                            -- 压缩信息
            "snappy" : {
                "compressor" : {                    -- compressor信息
                    "bytesIn" : NumberLong(37694572),
                    "bytesOut" : NumberLong(26683033)
                },
                "decompressor" : {                    -- decompressor信息
                    "bytesIn" : NumberLong(27727534),
                    "bytesOut" : NumberLong(41769607)
                }
            },
            "zstd" : {
                "compressor" : {
                    "bytesIn" : NumberLong(0),
                    "bytesOut" : NumberLong(0)
                },
                "decompressor" : {
                    "bytesIn" : NumberLong(0),
                    "bytesOut" : NumberLong(0)
                }
            },
            "zlib" : {
                "compressor" : {
                    "bytesIn" : NumberLong(0),
                    "bytesOut" : NumberLong(0)
                },
                "decompressor" : {
                    "bytesIn" : NumberLong(0),
                    "bytesOut" : NumberLong(0)
                }
            }
        },
        "serviceExecutorTaskStats" : {
            "executor" : "passthrough",
            "threadsRunning" : 11
        }
    },
    "opLatencies" : {                            -- 仅适用于mongod实例,包含整个实例的操作延迟
        "reads" : {                                -- 读取请求的延迟统计信息
            "latency" : NumberLong(1140144),    
            "ops" : NumberLong(8506)
        },
        "writes" : {                            -- 写入操作的延迟统计信息
            "latency" : NumberLong(0),
            "ops" : NumberLong(0)
        },
        "commands" : {                            -- 数据库命令的延迟统计信息
            "latency" : NumberLong(3201015),
            "ops" : NumberLong(49254)
        },
        "transactions" : {                        -- 事务的延迟统计信息
            "latency" : NumberLong(0),
            "ops" : NumberLong(0)
        }
    },
    "opReadConcernCounters" : {                    -- 自上次启动以来,向mongod实例报告查询操作指定的读取关注级别的文档。
        "available" : NumberLong(0),            -- 指定读取关注级别“可用”的查询操作数
        "linearizable" : NumberLong(0),            -- 指定读取关注级别“linearizable”的查询操作数
        "local" : NumberLong(2),                -- 指定读取关注级别“本地”的查询操作数
        "majority" : NumberLong(0),                -- 指定读取关注级别“多数”的查询操作数
        "snapshot" : NumberLong(0),                -- 指定读取关注级别“快照”的查询操作数
        "none" : NumberLong(111)                -- 未指定读关注级别,而是使用默认读关注级别的查询操作数。
    },
    "opcounters" : {                            -- 自mongod实例上次启动以来按类型报告数据库操作的文档
        "insert" : NumberLong(3),                -- 自mongod实例上次启动以来收到的插入操作总数
        "query" : NumberLong(113),                -- 自mongod实例上次启动以来收到的查询总数
        "update" : NumberLong(9),                -- 自mongod实例上次启动以来收到的更新操作总数
        "delete" : NumberLong(2),                -- 自mongod实例上次启动以来的删除操作总数
        "getmore" : NumberLong(8489),            -- 自上次启动mongod实例以来,“getmore”操作的总数。即使查询计数很低,此计数器也可能很高。辅助节点在复制过程中发送getMore操作。
        "command" : NumberLong(49404)            -- 自mongod实例上次启动以来,发布到数据库的命令总数
    },
    "opcountersRepl" : {                        -- 自mongod实例上次启动以来按类型报告数据库复制操作的文档,仅当当前主机是副本集的成员时,才会显示这些值
        "insert" : NumberLong(0),                -- 插入总数
        "query" : NumberLong(0),                -- 查询总数
        "update" : NumberLong(0),                -- 更新总数
        "delete" : NumberLong(0),                -- 删除总数
        "getmore" : NumberLong(0),                -- getmore总数
        "command" : NumberLong(0)                -- 命令总数
    },
    "oplogTruncation" : {                                -- 当前实例是副本集的成员并使用WiredTiger Storage Engine时,才显示该字段。
        "totalTimeProcessingMicros" : NumberLong(33),    -- 扫描或采样操作日志以确定操作日志截断点所花费的总时间(以微秒为单位)
        "processingMethod" : "scanning",                -- 启动时用于确定oplog截断点的方法。 该值可以是“采样”或“扫描”。
        "totalTimeTruncatingMicros" : NumberLong(0),    -- 执行oplog截断所花费的累积时间(以微秒为单位)
        "truncateCount" : NumberLong(0)                    -- oplog截断的累积数量
    },
    "repl" : {                                    -- 报告副本集配置的文档。仅当当前主机是副本集时才会出现repl。
        "hosts" : [                                -- 成员主机名
            "11.11.11.11:27017",
            "11.11.11.12:27017",
            "11.11.11.13:27017"
        ],
        "setName" : "XYZ",                        -- 副本集名称
        "setVersion" : 1,                        -- 版本
        "ismaster" : true,                        -- 当前节点是否为副本集的主节点
        "secondary" : false,                    -- 当前节点是否为副本集的辅助节点
        "primary" : "11.11.11.11:27017",        -- 主节点地址
        "me" : "11.11.11.11:27017",                -- 当前执行的地址
        "electionId" : ObjectId("7fffffff0000000000000001"),
        "lastWrite" : {
            "opTime" : {                        -- 该成员所报告的有关该成员所应用操作日志中最后一次操作的信息
                "ts" : Timestamp(1597310423, 1),
                "t" : NumberLong(1)
            },
            "lastWriteDate" : ISODate("2020-08-13T09:20:23Z"),
            "majorityOpTime" : {
                "ts" : Timestamp(1597310423, 1),
                "t" : NumberLong(1)
            },
            "majorityWriteDate" : ISODate("2020-08-13T09:20:23Z")
        },
        "rbid" : 1                                -- 回滚标识符。用于确定此mongod实例是否发生了回滚
    },
    "storageEngine" : {                            -- 有关当前存储引擎数据的文档
        "name" : "wiredTiger",                    -- 当前存储引擎的名称
        "supportsCommittedReads" : true,        -- 存储引擎是否支持“多数”读取关注的布尔值
        "oldestRequiredTimestampForCrashRecovery" : Timestamp(1597310403, 1),
        "supportsPendingDrops" : true,
        "dropPendingIdents" : NumberLong(0),
        "supportsSnapshotReadConcern" : true,
        "readOnly" : false,                        -- 是否只读
        "persistent" : true,                    -- 指示存储引擎是否将数据持久保存到磁盘的布尔值
        "backupCursorOpen" : false
    },
    "tcmalloc" : {
        "generic" : {
            "current_allocated_bytes" : 137730688,
            "heap_size" : 176914432
        },
        "tcmalloc" : {
            "pageheap_free_bytes" : 2736128,
            "pageheap_unmapped_bytes" : 31244288,
            "max_total_thread_cache_bytes" : 1024458752,
            "current_total_thread_cache_bytes" : 1950976,
            "total_free_bytes" : 5203328,
            "central_cache_free_bytes" : 427840,
            "transfer_cache_free_bytes" : 2824512,
            "thread_cache_free_bytes" : 1950976,
            "aggressive_memory_decommit" : 0,
            "pageheap_committed_bytes" : 145670144,
            "pageheap_scavenge_count" : 575,
            "pageheap_commit_count" : 1376,
            "pageheap_total_commit_bytes" : NumberLong(1139781632),
            "pageheap_decommit_count" : 575,
            "pageheap_total_decommit_bytes" : 994111488,
            "pageheap_reserve_count" : 60,
            "pageheap_total_reserve_bytes" : 176914432,
            "spinlock_total_delay_ns" : 1320,
            "release_rate" : 1,
            "formattedString" : "------------------------------------------------\nMALLOC:      137731264 (  131.4 MiB) Bytes in use by application\nMALLOC: +      2736128 (    2.6 MiB) Bytes in page heap freelist\nMALLOC: +       427840 (    0.4 MiB) Bytes in central cache freelist\nMALLOC: +      2824512 (    2.7 MiB) Bytes in transfer cache freelist\nMALLOC: +      1950400 (    1.9 MiB) Bytes in thread cache freelists\nMALLOC: +      2883584 (    2.8 MiB) Bytes in malloc metadata\nMALLOC:   ------------\nMALLOC: =    148553728 (  141.7 MiB) Actual memory used (physical + swap)\nMALLOC: +     31244288 (   29.8 MiB) Bytes released to OS (aka unmapped)\nMALLOC:   ------------\nMALLOC: =    179798016 (  171.5 MiB) Virtual address space used\nMALLOC:\nMALLOC:           1434              Spans in use\nMALLOC:             71              Thread heaps in use\nMALLOC:           4096              Tcmalloc page size\n------------------------------------------------\nCall ReleaseFreeMemory() to release freelist memory to the OS (via madvise()).\nBytes released to the OS take up virtual address space but no physical memory.\n"
        }
    },
    "trafficRecording" : {                -- 输出中包括trafficRecording指标
        "running" : false
    },
    "transactions" : {                    -- 包含有关事务数据的文档,在3.6.3+的mongod和4.2+的mongos中可用。https://docs.mongodb.com/v4.2/reference/command/serverStatus/#transactions
        "retriedCommandsCount" : NumberLong(0),            -- 仅在mongod上可用。在已经提交了相应的可重试写入命令之后,已接收到的重试尝试总数。
        "retriedStatementsCount" : NumberLong(0),        -- 写语句总数,与transaction.retriedCommandsCount中重试的命令相关联
        "transactionsCollectionWriteCount" : NumberLong(0),        -- 仅在mongod上可用,提交新的可重试的写语句时触发对config.transactions集合的写总数
        "currentActive" : NumberLong(0),                -- 当前正在执行的事务总数
        "currentInactive" : NumberLong(0),                -- 当前未执行命令的事务总数
        "currentOpen" : NumberLong(0),                    -- 当前打开事务的总数
        "totalAborted" : NumberLong(0),                    -- 实例自上次启动以来中止的事务总数
        "totalCommitted" : NumberLong(0),                -- 实例自上次启动以来在实例上提交的事务总数
        "totalStarted" : NumberLong(0),                    -- 实例自上次启动以来在实例上启动的事务总数
        "totalPrepared" : NumberLong(0),                -- 实例自上次启动以来在服务器上处于准备状态的事务总数
        "totalPreparedThenCommitted" : NumberLong(0),    -- 实例自上次启动以来在服务器上准备并提交的事务总数
        "totalPreparedThenAborted" : NumberLong(0),        -- 实例自上次启动以来在服务器上准备并中止的事务总数
        "currentPrepared" : NumberLong(0)                -- 服务器上处于准备状态的当前事务数
    },
    "transportSecurity" : {                                -- 建立的TLS <version>连接的累积数量。 重新启动后将重置该值。
        "1.0" : NumberLong(0),
        "1.1" : NumberLong(0),
        "1.2" : NumberLong(0),
        "1.3" : NumberLong(0),
        "unknown" : NumberLong(0)
    },
    "twoPhaseCommitCoordinator" : {                        -- 二阶段提交信息
        "totalCreated" : NumberLong(0),
        "totalStartedTwoPhaseCommit" : NumberLong(0),
        "totalAbortedTwoPhaseCommit" : NumberLong(0),
        "totalCommittedTwoPhaseCommit" : NumberLong(0),
        "currentInSteps" : {
            "writingParticipantList" : NumberLong(0),
            "waitingForVotes" : NumberLong(0),
            "writingDecision" : NumberLong(0),
            "waitingForDecisionAcks" : NumberLong(0),
            "deletingCoordinatorDoc" : NumberLong(0)
        }
    },
    "wiredTiger" : {                    -- 使用WiredTiger存储引擎时信息才会出现。一些统计汇总信息。https://docs.mongodb.com/v4.2/reference/command/serverStatus/#wiredtiger
        "uri" : "statistics:",            -- 一个字符串。 供MongoDB内部使用。
        "async" : {                        -- 返回与异步操作API相关的统计信息的文档,MongoDB未使用它。
            "current work queue length" : 0,
            "maximum work queue length" : 0,
            "number of allocation state races" : 0,
            "number of flush calls" : 0,
            "number of operation slots viewed for allocation" : 0,
            "number of times operation allocation failed" : 0,
            "number of times worker found no work" : 0,
            "total allocations" : 0,
            "total compact calls" : 0,
            "total insert calls" : 0,
            "total remove calls" : 0,
            "total search calls" : 0,
            "total update calls" : 0
        },
        "block-manager" : {                -- 返回有关块管理器操作的统计信息的文档
            "blocks pre-loaded" : 0,
            "blocks read" : 1458,
            "blocks written" : 5954,
            "bytes read" : 5971968,
            "bytes written" : 39948288,
            "bytes written for checkpoint" : 39948288,
            "mapped blocks read" : 0,
            "mapped bytes read" : 0
        },
        "cache" : {                        -- 有关缓存的统计信息和来自缓存的页面逐出的文档
            "application threads page read from disk to cache count" : 0,
            "application threads page read from disk to cache time (usecs)" : 0,
            "application threads page write from cache to disk count" : 2972,
            "application threads page write from cache to disk time (usecs)" : 181330,
            "bytes belonging to page images in the cache" : 43,
            "bytes belonging to the cache overflow table in the cache" : 182,
            "bytes currently in the cache" : 753495,                -- 当前缓存中数据的字节大小,该值不应大于配置的最大字节数。
            "bytes dirty in the cache cumulative" : 2438469,
            "bytes not belonging to page images in the cache" : 753452,
            "bytes read into cache" : 0,
            "bytes written from cache" : 52711232,
            "cache overflow cursor application thread wait time (usecs)" : 0,
            "cache overflow cursor internal thread wait time (usecs)" : 0,
            "cache overflow score" : 0,
            "cache overflow table entries" : 0,
            "cache overflow table insert calls" : 0,
            "cache overflow table max on-disk size" : 0,
            "cache overflow table on-disk size" : 0,
            "cache overflow table remove calls" : 0,
            "checkpoint blocked page eviction" : 0,
            "eviction calls to get a page" : 1148,
            "eviction calls to get a page found queue empty" : 1129,
            "eviction calls to get a page found queue empty after locking" : 0,
            "eviction currently operating in aggressive mode" : 0,
            "eviction empty score" : 0,
            "eviction passes of a file" : 0,
            "eviction server candidate queue empty when topping up" : 0,
            "eviction server candidate queue not empty when topping up" : 0,
            "eviction server evicting pages" : 0,
            "eviction server slept, because we did not make progress with eviction" : 1056,
            "eviction server unable to reach eviction goal" : 0,
            "eviction server waiting for a leaf page" : 4,
            "eviction state" : 128,
            "eviction walk target pages histogram - 0-9" : 0,
            "eviction walk target pages histogram - 10-31" : 0,
            "eviction walk target pages histogram - 128 and higher" : 0,
            "eviction walk target pages histogram - 32-63" : 0,
            "eviction walk target pages histogram - 64-128" : 0,
            "eviction walk target strategy both clean and dirty pages" : 0,
            "eviction walk target strategy only clean pages" : 0,
            "eviction walk target strategy only dirty pages" : 0,
            "eviction walks abandoned" : 0,
            "eviction walks gave up because they restarted their walk twice" : 0,
            "eviction walks gave up because they saw too many pages and found no candidates" : 0,
            "eviction walks gave up because they saw too many pages and found too few candidates" : 0,
            "eviction walks reached end of tree" : 0,
            "eviction walks started from root of tree" : 0,
            "eviction walks started from saved location in tree" : 0,
            "eviction worker thread active" : 4,
            "eviction worker thread created" : 0,
            "eviction worker thread evicting pages" : 3,
            "eviction worker thread removed" : 0,
            "eviction worker thread stable number" : 0,
            "files with active eviction walks" : 0,
            "files with new eviction walks started" : 0,
            "force re-tuning of eviction workers once in a while" : 0,
            "forced eviction - pages evicted that were clean count" : 0,
            "forced eviction - pages evicted that were clean time (usecs)" : 0,
            "forced eviction - pages evicted that were dirty count" : 2,
            "forced eviction - pages evicted that were dirty time (usecs)" : 56,
            "forced eviction - pages selected because of too many deleted items count" : 5,
            "forced eviction - pages selected count" : 2,
            "forced eviction - pages selected unable to be evicted count" : 0,
            "forced eviction - pages selected unable to be evicted time" : 0,
            "hazard pointer blocked page eviction" : 0,
            "hazard pointer check calls" : 5,
            "hazard pointer check entries walked" : 0,
            "hazard pointer maximum array length" : 0,
            "in-memory page passed criteria to be split" : 0,
            "in-memory page splits" : 0,
            "internal pages evicted" : 0,
            "internal pages queued for eviction" : 0,
            "internal pages seen by eviction walk" : 0,
            "internal pages seen by eviction walk that are already queued" : 0,
            "internal pages split during eviction" : 0,
            "leaf pages split during eviction" : 0,
            "maximum bytes configured" : 1073741824,                    -- 已配置wiredTiger.cache.maximum字节,最大缓存大小
            "maximum page size at eviction" : 0,
            "modified pages evicted" : 7,
            "modified pages evicted by application threads" : 0,
            "operations timed out waiting for space in cache" : 0,
            "overflow pages read into cache" : 0,        
            "page split during eviction deepened the tree" : 0,
            "page written requiring cache overflow records" : 0,
            "pages currently held in the cache" : 59,
            "pages evicted by application threads" : 0,
            "pages queued for eviction" : 0,
            "pages queued for eviction post lru sorting" : 0,
            "pages queued for urgent eviction" : 5,
            "pages queued for urgent eviction during walk" : 0,
            "pages read into cache" : 0,                                -- 读入缓存的页面数,从缓存写入的wiredTiger.cache.pages读取到缓存的wiredTiger.cache.pages(IO)。
            "pages read into cache after truncate" : 30,
            "pages read into cache after truncate in prepare state" : 0,
            "pages read into cache requiring cache overflow entries" : 0,
            "pages read into cache requiring cache overflow for checkpoint" : 0,
            "pages read into cache skipping older cache overflow entries" : 0,
            "pages read into cache with skipped cache overflow entries needed later" : 0,
            "pages read into cache with skipped cache overflow entries needed later by checkpoint" : 0,
            "pages requested from the cache" : 234580,
            "pages seen by eviction walk" : 0,
            "pages seen by eviction walk that are already queued" : 0,
            "pages selected for eviction unable to be evicted" : 0,
            "pages selected for eviction unable to be evicted as the parent page has overflow items" : 0,
            "pages selected for eviction unable to be evicted because of active children on an internal page" : 0,
            "pages selected for eviction unable to be evicted because of failure in reconciliation" : 0,
            "pages selected for eviction unable to be evicted due to newer modifications on a clean page" : 0,
            "pages walked for eviction" : 0,
            "pages written from cache" : 2972,                        -- 从缓存写入的页面数,从缓存写入的wiredTiger.cache.pages和读取到缓存中的wiredTiger.cache.pages(IO)。
            "pages written requiring in-memory restoration" : 3,
            "percentage overhead" : 8,
            "tracked bytes belonging to internal pages in the cache" : 12935,
            "tracked bytes belonging to leaf pages in the cache" : 740560,
            "tracked dirty bytes in the cache" : 688182,            -- 高速缓存中脏数据的大小(以字节为单位),此值应小于缓存值中当前的字节。
            "tracked dirty pages in the cache" : 4,                    -- 高速缓存中脏数据页数
            "unmodified pages evicted" : 0                            -- 页面驱逐的主要统计数据
        },
        "capacity" : {                                                -- 后台刷写信息
            "background fsync file handles considered" : 0,
            "background fsync file handles synced" : 0,
            "background fsync time (msecs)" : 0,
            "bytes read" : 0,
            "bytes written for checkpoint" : 18069881,
            "bytes written for eviction" : 0,
            "bytes written for log" : 1635328,
            "bytes written total" : 19705209,
            "threshold to call fsync" : 0,
            "time waiting due to total capacity (usecs)" : 0,
            "time waiting during checkpoint (usecs)" : 0,
            "time waiting during eviction (usecs)" : 0,
            "time waiting during logging (usecs)" : 0,
            "time waiting during read (usecs)" : 0
        },
        "connection" : {                                            -- 返回与WiredTiger连接有关的统计信息的文档
            "auto adjusting condition resets" : 6370,
            "auto adjusting condition wait calls" : 191658,
            "detected system time went backwards" : 0,
            "files currently open" : 34,
            "memory allocations" : 2615516,
            "memory frees" : 2607397,
            "memory re-allocations" : 437367,
            "pthread mutex condition wait calls" : 510231,
            "pthread mutex shared lock read-lock calls" : 736461,
            "pthread mutex shared lock write-lock calls" : 82147,
            "total fsync I/Os" : 7277,
            "total read I/Os" : 1970,
            "total write I/Os" : 10269
        },
        "cursor" : {                                                -- 在WiredTiger游标上返回统计信息的文档
            "cached cursor count" : 43,
            "cursor bulk loaded cursor insert calls" : 0,
            "cursor close calls that result in cache" : 69336,
            "cursor create calls" : 84645,
            "cursor insert calls" : 5974,
            "cursor insert key and value bytes" : 2708353,
            "cursor modify calls" : 0,
            "cursor modify key and value bytes affected" : 0,
            "cursor modify value bytes modified" : 0,
            "cursor next calls" : 86761,
            "cursor operation restarted" : 0,
            "cursor prev calls" : 479,
            "cursor remove calls" : 19,
            "cursor remove key bytes removed" : 484,
            "cursor reserve calls" : 0,
            "cursor reset calls" : 304050,
            "cursor search calls" : 185985,
            "cursor search near calls" : 591,
            "cursor sweep buckets" : 26167,
            "cursor sweep cursors closed" : 1,
            "cursor sweep cursors examined" : 533,
            "cursor sweeps" : 4361,
            "cursor truncate calls" : 0,
            "cursor update calls" : 0,
            "cursor update key and value bytes" : 0,
            "cursor update value size change" : 0,
            "cursors reused from cache" : 68813,
            "open cursor count" : 26
        },
        "data-handle" : {                                        -- 返回有关数据句柄和扫描的统计信息的文档。
            "connection data handle size" : 432,
            "connection data handles currently active" : 61,
            "connection sweep candidate became referenced" : 0,
            "connection sweep dhandles closed" : 1,
            "connection sweep dhandles removed from hash list" : 1984,
            "connection sweep time-of-death sets" : 5948,
            "connection sweeps" : 3015,
            "session dhandles swept" : 2,
            "session sweep attempts" : 572
        },
        "lock" : {
            "checkpoint lock acquisitions" : 503,
            "checkpoint lock application thread wait time (usecs)" : 0,
            "checkpoint lock internal thread wait time (usecs)" : 0,
            "dhandle lock application thread time waiting (usecs)" : 0,
            "dhandle lock internal thread time waiting (usecs)" : 0,
            "dhandle read lock acquisitions" : 128469,
            "dhandle write lock acquisitions" : 4030,
            "durable timestamp queue lock application thread time waiting (usecs)" : 0,
            "durable timestamp queue lock internal thread time waiting (usecs)" : 0,
            "durable timestamp queue read lock acquisitions" : 0,
            "durable timestamp queue write lock acquisitions" : 2822,
            "metadata lock acquisitions" : 473,
            "metadata lock application thread wait time (usecs)" : 0,
            "metadata lock internal thread wait time (usecs)" : 0,
            "read timestamp queue lock application thread time waiting (usecs)" : 1,
            "read timestamp queue lock internal thread time waiting (usecs)" : 0,
            "read timestamp queue read lock acquisitions" : 0,
            "read timestamp queue write lock acquisitions" : 490,
            "schema lock acquisitions" : 511,
            "schema lock application thread wait time (usecs)" : 0,
            "schema lock internal thread wait time (usecs)" : 0,
            "table lock application thread time waiting for the table lock (usecs)" : 193,
            "table lock internal thread time waiting for the table lock (usecs)" : 0,
            "table read lock acquisitions" : 0,
            "table write lock acquisitions" : 28145,
            "txn global lock application thread time waiting (usecs)" : 0,
            "txn global lock internal thread time waiting (usecs)" : 9,
            "txn global read lock acquisitions" : 8837,
            "txn global write lock acquisitions" : 12689
        },
        "log" : {                                    -- 返回WiredTiger的预写日志(即日志)统计信息的文档,https://docs.mongodb.com/v4.2/core/journaling/#journaling-wiredtiger
            "busy returns attempting to switch slots" : 0,
            "force archive time sleeping (usecs)" : 0,
            "log bytes of payload data" : 1181490,
            "log bytes written" : 1635200,
            "log files manually zero-filled" : 0,
            "log flush operations" : 63118,
            "log force write operations" : 96155,
            "log force write operations skipped" : 92857,
            "log records compressed" : 513,
            "log records not compressed" : 2886,
            "log records too small to compress" : 1446,
            "log release advances write LSN" : 507,
            "log scan operations" : 0,
            "log scan records requiring two reads" : 0,
            "log server thread advances write LSN" : 3298,
            "log server thread write LSN walk skipped" : 48737,
            "log sync operations" : 3806,
            "log sync time duration (usecs)" : 4251984,
            "log sync_dir operations" : 1,
            "log sync_dir time duration (usecs)" : 1423,
            "log write operations" : 4845,
            "logging bytes consolidated" : 1634688,
            "maximum log file size" : 104857600,
            "number of pre-allocated log files to create" : 2,
            "pre-allocated log files not ready and missed" : 1,
            "pre-allocated log files prepared" : 2,
            "pre-allocated log files used" : 0,
            "records processed by log scan" : 0,
            "slot close lost race" : 0,
            "slot close unbuffered waits" : 0,
            "slot closures" : 3805,
            "slot join atomic update races" : 0,
            "slot join calls atomic updates raced" : 0,
            "slot join calls did not yield" : 4845,
            "slot join calls found active slot closed" : 0,
            "slot join calls slept" : 0,
            "slot join calls yielded" : 0,
            "slot join found active slot closed" : 0,
            "slot joins yield time (usecs)" : 0,
            "slot transitions unable to find free slot" : 0,
            "slot unbuffered writes" : 0,
            "total in-memory size of compressed records" : 2320998,
            "total log buffer size" : 33554432,
            "total size of compressed records" : 691677,
            "written slots coalesced" : 0,
            "yields waiting for previous log file close" : 0
        },
        "perf" : {
            "file system read latency histogram (bucket 1) - 10-49ms" : 0,
            "file system read latency histogram (bucket 2) - 50-99ms" : 0,
            "file system read latency histogram (bucket 3) - 100-249ms" : 0,
            "file system read latency histogram (bucket 4) - 250-499ms" : 0,
            "file system read latency histogram (bucket 5) - 500-999ms" : 0,
            "file system read latency histogram (bucket 6) - 1000ms+" : 0,
            "file system write latency histogram (bucket 1) - 10-49ms" : 0,
            "file system write latency histogram (bucket 2) - 50-99ms" : 0,
            "file system write latency histogram (bucket 3) - 100-249ms" : 0,
            "file system write latency histogram (bucket 4) - 250-499ms" : 0,
            "file system write latency histogram (bucket 5) - 500-999ms" : 0,
            "file system write latency histogram (bucket 6) - 1000ms+" : 0,
            "operation read latency histogram (bucket 1) - 100-249us" : 0,
            "operation read latency histogram (bucket 2) - 250-499us" : 0,
            "operation read latency histogram (bucket 3) - 500-999us" : 0,
            "operation read latency histogram (bucket 4) - 1000-9999us" : 0,
            "operation read latency histogram (bucket 5) - 10000us+" : 0,
            "operation write latency histogram (bucket 1) - 100-249us" : 0,
            "operation write latency histogram (bucket 2) - 250-499us" : 0,
            "operation write latency histogram (bucket 3) - 500-999us" : 0,
            "operation write latency histogram (bucket 4) - 1000-9999us" : 0,
            "operation write latency histogram (bucket 5) - 10000us+" : 0
        },
        "reconciliation" : {                            -- 返回和解过程统计信息的文档
            "fast-path pages deleted" : 0,
            "page reconciliation calls" : 3000,
            "page reconciliation calls for eviction" : 6,
            "pages deleted" : 32,
            "split bytes currently awaiting free" : 0,
            "split objects currently awaiting free" : 0
        },
        "session" : {                                    -- 返回会话的打开游标计数和打开会话数的文档。
            "open session count" : 21,
            "session query timestamp calls" : 0,
            "table alter failed calls" : 0,
            "table alter successful calls" : 0,
            "table alter unchanged and skipped" : 0,
            "table compact failed calls" : 0,
            "table compact successful calls" : 0,
            "table create failed calls" : 0,
            "table create successful calls" : 30,
            "table drop failed calls" : 0,
            "table drop successful calls" : 1,
            "table import failed calls" : 0,
            "table import successful calls" : 0,
            "table rebalance failed calls" : 0,
            "table rebalance successful calls" : 0,
            "table rename failed calls" : 0,
            "table rename successful calls" : 0,
            "table salvage failed calls" : 0,
            "table salvage successful calls" : 0,
            "table truncate failed calls" : 0,
            "table truncate successful calls" : 0,
            "table verify failed calls" : 0,
            "table verify successful calls" : 0
        },
        "thread-state" : {
            "active filesystem fsync calls" : 0,
            "active filesystem read calls" : 0,
            "active filesystem write calls" : 0
        },
        "thread-yield" : {                                    -- 在页面获取过程中返回产量统计信息的文档
            "application thread time evicting (usecs)" : 0,
            "application thread time waiting for cache (usecs)" : 0,
            "connection close blocked waiting for transaction state stabilization" : 0,
            "connection close yielded for lsm manager shutdown" : 0,
            "data handle lock yielded" : 0,
            "get reference for page index and slot time sleeping (usecs)" : 0,
            "log server sync yielded for log write" : 0,
            "page access yielded due to prepare state change" : 0,
            "page acquire busy blocked" : 0,
            "page acquire eviction blocked" : 0,
            "page acquire locked blocked" : 0,
            "page acquire read blocked" : 0,
            "page acquire time sleeping (usecs)" : 0,
            "page delete rollback time sleeping for state change (usecs)" : 0,
            "page reconciliation yielded due to child modification" : 0
        },
        "transaction" : {                                    -- 返回有关事务检查点和操作的统计信息的文档
            "Number of prepared updates" : 0,
            "Number of prepared updates added to cache overflow" : 0,
            "durable timestamp queue entries walked" : 1085,
            "durable timestamp queue insert to empty" : 1737,
            "durable timestamp queue inserts to head" : 1085,
            "durable timestamp queue inserts total" : 2822,
            "durable timestamp queue length" : 1,
            "number of named snapshots created" : 0,
            "number of named snapshots dropped" : 0,
            "prepared transactions" : 0,
            "prepared transactions committed" : 0,
            "prepared transactions currently active" : 0,
            "prepared transactions rolled back" : 0,
            "query timestamp calls" : 92170,
            "read timestamp queue entries walked" : 248,
            "read timestamp queue insert to empty" : 242,
            "read timestamp queue inserts to head" : 248,
            "read timestamp queue inserts total" : 490,
            "read timestamp queue length" : 1,
            "rollback to stable calls" : 0,
            "rollback to stable updates aborted" : 0,
            "rollback to stable updates removed from cache overflow" : 0,
            "set timestamp calls" : 5636,
            "set timestamp durable calls" : 0,
            "set timestamp durable updates" : 0,
            "set timestamp oldest calls" : 2818,
            "set timestamp oldest updates" : 2818,
            "set timestamp stable calls" : 2818,
            "set timestamp stable updates" : 2818,
            "transaction begins" : 87358,
            "transaction checkpoint currently running" : 0,
            "transaction checkpoint generation" : 474,
            "transaction checkpoint max time (msecs)" : 35,
            "transaction checkpoint min time (msecs)" : 5,
            "transaction checkpoint most recent time (msecs)" : 12,        -- 创建最新检查点的时间(以毫秒为单位)。在稳定的写负载下,该值的增加可能表示IO子系统已饱和。
            "transaction checkpoint scrub dirty target" : 0,
            "transaction checkpoint scrub time (msecs)" : 0,
            "transaction checkpoint total time (msecs)" : 5855,
            "transaction checkpoints" : 503,
            "transaction checkpoints skipped because database was clean" : 30,
            "transaction failures due to cache overflow" : 0,
            "transaction fsync calls for checkpoint after allocating the transaction ID" : 473,
            "transaction fsync duration for checkpoint after allocating the transaction ID (usecs)" : 3815,
            "transaction range of IDs currently pinned" : 0,
            "transaction range of IDs currently pinned by a checkpoint" : 0,
            "transaction range of IDs currently pinned by named snapshots" : 0,
            "transaction range of timestamps currently pinned" : 21474836480,
            "transaction range of timestamps pinned by a checkpoint" : NumberLong("6860396028344926209"),
            "transaction range of timestamps pinned by the oldest active read timestamp" : 0,
            "transaction range of timestamps pinned by the oldest timestamp" : 21474836480,
            "transaction read timestamp of the oldest active reader" : 0,
            "transaction sync calls" : 0,
            "transactions committed" : 3318,
            "transactions rolled back" : 84391,
            "update conflicts" : 0
        },
        "concurrentTransactions" : {                -- 返回有关允许WiredTiger存储引擎进行的并发读写事务数的信息
            "write" : {
                "out" : 0,
                "available" : 128,
                "totalTickets" : 128
            },
            "read" : {
                "out" : 1,
                "available" : 127,
                "totalTickets" : 128
            }
        },
        "snapshot-window-settings" : {
            "cache pressure percentage threshold" : 95,
            "current cache pressure percentage" : NumberLong(0),
            "total number of SnapshotTooOld errors" : NumberLong(0),
            "max target available snapshots window size in seconds" : 5,
            "target available snapshots window size in seconds" : 5,
            "current available snapshots window size in seconds" : 5,
            "latest majority snapshot timestamp available" : "Aug 13 17:20:23:1",
            "oldest majority snapshot timestamp available" : "Aug 13 17:20:18:1"
        },
        "oplog" : {
            "visibility timestamp" : Timestamp(1597310423, 1)
        }
    },
    "mem" : {                -- 有关mongod的系统体系结构和当前内存使用情况的文档
        "bits" : 64,        -- DB实例是64位还是32位体系结构编译的。
        "resident" : 89,    -- 大致等于数据库进程当前使用的RAM量(以M为单位)。在正常使用期间,该值趋于增加。在专用数据库服务器中,此数字趋向于接近系统内存总量。
        "virtual" : 1879,    -- 显示mongod进程使用的虚拟内存量(以M为单位)。
        "supported" : true  -- 是否支持扩展的内存信息
    },
    "metrics" : {                    -- 返回各种统计信息的文档,这些统计信息反映了正在运行的mongod实例的当前使用情况和状态。
        "aggStageCounters" : {        -- 报告聚合管道阶段使用情况的文档。 其中的字段是聚合管道阶段的名称,报告该阶段已执行的次数。
            "$_internalInhibitOptimization" : NumberLong(0),
            "$_internalSplitPipeline" : NumberLong(0),
            "$addFields" : NumberLong(0),
            "$bucket" : NumberLong(0),
            "$bucketAuto" : NumberLong(0),
            "$changeStream" : NumberLong(0),
            "$collStats" : NumberLong(0),
            "$count" : NumberLong(0),
            "$currentOp" : NumberLong(3),
            "$facet" : NumberLong(0),
            "$geoNear" : NumberLong(0),
            "$graphLookup" : NumberLong(0),
            "$group" : NumberLong(3),
            "$indexStats" : NumberLong(0),
            "$limit" : NumberLong(0),
            "$listLocalSessions" : NumberLong(0),
            "$listSessions" : NumberLong(0),
            "$lookup" : NumberLong(0),
            "$match" : NumberLong(3),
            "$merge" : NumberLong(0),
            "$mergeCursors" : NumberLong(0),
            "$out" : NumberLong(0),
            "$planCacheStats" : NumberLong(0),
            "$project" : NumberLong(0),
            "$redact" : NumberLong(0),
            "$replaceRoot" : NumberLong(0),
            "$replaceWith" : NumberLong(0),
            "$sample" : NumberLong(0),
            "$set" : NumberLong(0),
            "$skip" : NumberLong(0),
            "$sort" : NumberLong(0),
            "$sortByCount" : NumberLong(0),
            "$unset" : NumberLong(0),
            "$unwind" : NumberLong(0)
        },
        "commands" : {                    -- 报告命令使用情况的文档。 其中的字段是数据库命令的名称。 对于每个命令,报告执行的总数和失败的执行次数。
            "<UNKNOWN>" : NumberLong(0),
            "_addShard" : {
                "failed" : NumberLong(0),        -- 失败的次数
                "total" : NumberLong(0)            -- 执行的次数
            },
            "_cloneCatalogData" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_cloneCollectionOptionsFromPrimaryShard" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrAddShard" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrAddShardToZone" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrBalancerStart" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrBalancerStatus" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrBalancerStop" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrClearJumboFlag" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrCommitChunkMerge" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrCommitChunkMigration" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrCommitChunkSplit" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrCommitMovePrimary" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrCreateCollection" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrCreateDatabase" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrDropCollection" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrDropDatabase" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrEnableSharding" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrMoveChunk" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrMovePrimary" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrRemoveShard" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrRemoveShardFromZone" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrShardCollection" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_configsvrUpdateZoneKeyRange" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_flushDatabaseCacheUpdates" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_flushRoutingTableCacheUpdates" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_getNextSessionMods" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_getUserCacheGeneration" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_isSelf" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(2)
            },
            "_mergeAuthzCollections" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_migrateClone" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_movePrimary" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_recvChunkAbort" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_recvChunkCommit" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_recvChunkStart" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_recvChunkStatus" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_shardsvrShardCollection" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "_transferMods" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "abortTransaction" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "aggregate" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "appendOplogNote" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "applyOps" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "authenticate" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "availableQueryOptions" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(2)
            },
            "buildInfo" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(45)
            },
            "checkShardingIndex" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "cleanupOrphaned" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "cloneCollection" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "cloneCollectionAsCapped" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "collMod" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "collStats" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "commitTransaction" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "compact" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "connPoolStats" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "connPoolSync" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "connectionStatus" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(3)
            },
            "convertToCapped" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "coordinateCommitTransaction" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "count" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(2)
            },
            "create" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "createIndexes" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(1)
            },
            "createRole" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "createUser" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(1)
            },
            "currentOp" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(3)
            },
            "dataSize" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dbHash" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dbStats" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "delete" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(2)
            },
            "distinct" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "driverOIDTest" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "drop" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dropAllRolesFromDatabase" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dropAllUsersFromDatabase" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dropConnections" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dropDatabase" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dropIndexes" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dropRole" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "dropUser" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "endSessions" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(2)
            },
            "explain" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "features" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "filemd5" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "find" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(113)
            },
            "findAndModify" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "flushRouterConfig" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "fsync" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "fsyncUnlock" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "geoSearch" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "getCmdLineOpts" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(7)
            },
            "getDatabaseVersion" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "getDiagnosticData" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "getFreeMonitoringStatus" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(6)
            },
            "getLastError" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "getLog" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(6)
            },
            "getMore" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(8489)
            },
            "getParameter" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "getShardMap" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "getShardVersion" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "getnonce" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "grantPrivilegesToRole" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "grantRolesToRole" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "grantRolesToUser" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "hostInfo" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "insert" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(3)
            },
            "invalidateUserCache" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "isMaster" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(2456)
            },
            "killAllSessions" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "killAllSessionsByPattern" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "killCursors" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "killOp" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "killSessions" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "listCollections" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(21)
            },
            "listCommands" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "listDatabases" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(4)
            },
            "listIndexes" : {
                "failed" : NumberLong(9),
                "total" : NumberLong(197)
            },
            "lockInfo" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "logRotate" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "logout" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "mapReduce" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "mapreduce" : {
                "shardedfinish" : {
                    "failed" : NumberLong(0),
                    "total" : NumberLong(0)
                }
            },
            "mergeChunks" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "moveChunk" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "ping" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "planCacheClear" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "planCacheClearFilters" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "planCacheListFilters" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "planCacheListPlans" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "planCacheListQueryShapes" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "planCacheSetFilter" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "prepareTransaction" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "profile" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "reIndex" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "refreshSessions" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "renameCollection" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "repairCursor" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "repairDatabase" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetAbortPrimaryCatchUp" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetFreeze" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetGetConfig" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(9)
            },
            "replSetGetRBID" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(5)
            },
            "replSetGetStatus" : {
                "failed" : NumberLong(7),
                "total" : NumberLong(87)
            },
            "replSetHeartbeat" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(28146)
            },
            "replSetInitiate" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(1)
            },
            "replSetMaintenance" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetReconfig" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetRequestVotes" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetResizeOplog" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetStepDown" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetStepDownWithForce" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetStepUp" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetSyncFrom" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "replSetUpdatePosition" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(15491)
            },
            "resetError" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "revokePrivilegesFromRole" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "revokeRolesFromRole" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "revokeRolesFromUser" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "rolesInfo" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "saslContinue" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(1924)
            },
            "saslStart" : {
                "failed" : NumberLong(1),
                "total" : NumberLong(963)
            },
            "serverStatus" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(5)
            },
            "setFeatureCompatibilityVersion" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "setFreeMonitoring" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "setParameter" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "setShardVersion" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "shardConnPoolStats" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "shardingState" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "shutdown" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "splitChunk" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "splitVector" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "startRecordingTraffic" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "startSession" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "stopRecordingTraffic" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "top" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "touch" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "unsetSharding" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "update" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(9)
            },
            "updateRole" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "updateUser" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "usersInfo" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "validate" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "voteCommitIndexBuild" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "waitForFailPoint" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(0)
            },
            "whatsmyuri" : {
                "failed" : NumberLong(0),
                "total" : NumberLong(15)
            }
        },
        "cursor" : {                        -- 包含有关游标状态和使用的数据的文档
            "timedOut" : NumberLong(2),        -- 自服务器进程启动以来已超时的游标总数。如果此数字很大或以固定速度增长,则可能表明应用程序错误。
            "open" : {                        -- 包含有关打开的游标的数据的文档
                "noTimeout" : NumberLong(0),-- 选项DBQuery.Option.noTimeout的打开游标的数量,以防止一段时间不活动后发生超时。
                "pinned" : NumberLong(1),    -- “固定”打开的游标的数量
                "total" : NumberLong(1)        -- MongoDB为客户端维护的游标数
            }
        },
        "document" : {                        -- 反映文档访问和修改的总数
            "deleted" : NumberLong(1),        -- 删除的文档总数
            "inserted" : NumberLong(3),        -- 插入的文档总数
            "returned" : NumberLong(2840),    -- 查询返回的文档总数
                "updated" : NumberLong(3)    -- 更新的文档总数
        },
        "getLastError" : {                    -- 报告getLastError使用情况的文档
            "wtime" : {                        -- 报告getLastError操作的文档的w参数大于1
                "num" : 13,                    -- 等待副本集的一个或多个成员确认写操作(即w值大于1)的具有指定写关注点(即w)的getLastError操作的总数。
                "totalMillis" : 204            -- 消耗总时间(以毫秒为单位),该时间以写关注点(即w)执行等待复制副本的一个或多个成员确认写操作(即w值大于1)的getLastError操作。
            },
            "wtimeouts" : NumberLong(0)        -- 由于getLastError的wtimeout阈值,导致写入关注操作超时的次数
        },
        "operation" : {                        -- 包含MongoDB使用特殊操作类型处理的计数器。
            "scanAndOrder" : NumberLong(1),    -- 返回无法使用索引执行排序操作的排序数字的查询总数
            "writeConflicts" : NumberLong(0)-- 遇到写冲突的查询总数
        },
        "query" : {
            "planCacheTotalSizeEstimateBytes" : NumberLong(0),
            "updateOneOpStyleBroadcastWithExactIDCount" : NumberLong(0)
        },
        "queryExecutor" : {                        -- 报告来自查询执行系统的数据的文档
            "scanned" : NumberLong(6),            -- 在查询和查询计划评估期间扫描的索引项总数。 该计数器与explain()输出中的totalKeysExamined相同。
            "scannedObjects" : NumberLong(2841)    -- 在查询和查询计划评估期间扫描的文档总数。 该计数器与explain()输出中的totalDocsExamined相同。
        },
        "record" : {                            -- 报告磁盘上的内存文件中与记录分配有关的数据的文档
            "moves" : NumberLong(0)
        },
        "repl" : {                                -- 报告与复制过程相关的指标的文档
            "executor" : {
                "pool" : {
                    "inProgressCount" : 0
                },
                "queues" : {
                    "networkInProgress" : 0,
                    "sleepers" : 3
                },
                "unsignaledEvents" : 0,
                "shuttingDown" : false,
                "networkInterface" : "DEPRECATED: getDiagnosticString is deprecated in NetworkInterfaceTL"
            },
            "apply" : {                            -- 报告复制操作日志中的操作应用程序的文档
                "attemptsToBecomeSecondary" : NumberLong(1),
                "batchSize" : NumberLong(0),    -- 应用的oplog操作总数。在批处理边界处随批处理中的操作数增加,而不是在每次操作后均增加一
                "batches" : {                    -- 有关副本集的辅助成员的oplog应用程序过程的报告
                    "num" : 0,                    -- 所有数据库应用的批次总数
                    "totalMillis" : 0            -- 从操作日志应用操作所花费的总时间(以毫秒为单位)
                },
                "ops" : NumberLong(0)            -- 应用的oplog操作总数
            },
            "buffer" : {                        -- 在批量应用oplog条目之前,MongoDB会从复制同步源缓冲区中缓冲oplog操作
                "count" : NumberLong(0),        -- oplog缓冲区中的当前操作数
                "maxSizeBytes" : NumberLong(268435456),    -- oplog缓冲区的最大大小,不可配置
                "sizeBytes" : NumberLong(0)                -- oplog缓冲区内容的当前大小
            },
            "initialSync" : {
                "completed" : NumberLong(0),
                "failedAttempts" : NumberLong(0),
                "failures" : NumberLong(0)
            },
            "network" : {                        -- 报告复制过程中的网络使用情况
                "bytes" : NumberLong(0),        -- 报告从复制同步源读取的数据总量
                "getmores" : {                    -- 报告有关getmore操作的信息,这些操作是操作日志复制过程的一部分,要求操作日志游标提供其他结果
                    "num" : 0,                    -- 报告getmore操作的总数,这些操作是从复制同步源请求其他操作集的操作
                    "totalMillis" : 0            -- 报告从getmore操作收集数据所需的总时间
                },
                "notMasterLegacyUnacknowledgedWrites" : NumberLong(0),  -- 由于当前mongod不在PRIMARY状态而失败的未确认(w:0)旧写入操作数。
                "notMasterUnacknowledgedWrites" : NumberLong(0),        -- 由于当前mongod不在PRIMARY状态而失败的未确认(w:0)写操作数。
                "ops" : NumberLong(0),                                    -- 从复制源读取的操作总数
                "readersCreated" : NumberLong(0),                        -- 创建的oplog查询进程的总数
                "replSetUpdatePosition" : {
                    "num" : NumberLong(0)
                }
            },
            "stateTransition" : {                                        -- 成员状态转换的用户操作信息
                "lastStateTransition" : "stepUp",                        -- 成员状态转换说明。stepUp:主;stepDown:副本;rollback:回滚
                "userOperationsKilled" : NumberLong(0),                    -- 实例状态更改期间杀死的用户操作数
                "userOperationsRunning" : NumberLong(0)                    -- 状态更改期间保持运行的用户操作数
            },
            "syncSource" : {
                "numSelections" : NumberLong(11),
                "numTimesChoseDifferent" : NumberLong(0),
                "numTimesChoseSame" : NumberLong(0),
                "numTimesCouldNotFind" : NumberLong(11)
            }
        },
        "ttl" : {
            "deletedDocuments" : NumberLong(3),
            "passes" : NumberLong(469)
        }
    },
    "ok" : 1,
    "$clusterTime" : {
        "clusterTime" : Timestamp(1597310423, 1),
        "signature" : {
            "hash" : BinData(0,"oyQFyHGe1RHLqSQkSNOrDlZ8gyg="),
            "keyId" : NumberLong("6860275335468941315")
        }
    },
    "operationTime" : Timestamp(1597310423, 1)
}
View Code

可以查看通过子项来进行针对信息的查看:

  • 查看锁信息:db.runCommand( { serverStatus: 1 } ).locks
  • 查看全局锁:db.runCommand( { serverStatus: 1 } ).globalLock
  • 查看内存信息:db.runCommand( { serverStatus: 1 } ).mem
  • 查看连接信息:db.runCommand( { serverStatus: 1 } ).connections
  • 查看网络信息:db.runCommand( { serverStatus: 1, repl: 1, metrics: 1, locks: 1 } ).network
  • 查看操作信息:db.runCommand( { serverStatus: 1, repl: 1, metrics: 1, locks: 1 } ).opcounters
  • 查看复制信息:db.runCommand( { serverStatus: 1, repl: 1, metrics: 1, locks: 1 } ).repl
  • 查看复制集成员的操作信息:db.runCommand( { serverStatus: 1, repl: 1, metrics: 1, locks: 1 } ).opcountersRepl

根据自己的需要来查看相应的信息,并且可以通过该命令来进行监控指标的定制。

rs.initiate(cfg):根据配置初始化副本集。

rs.conf()  == db.adminCommand({replSetGetConfig:1}):返回副本集的配置文档。 

XYZ:PRIMARY> db.adminCommand({replSetGetConfig:1})
{
    "config" : {
        "_id" : "XYZ",    -- 副本集名
        "version" : 1,    -- 递增的数字,用于区分副本集配置版本
        "protocolVersion" : NumberLong(1),  -- 副本集协议版本,从4.0开始,MongoDB仅支持protocolVersion:1,并且不再支持protocolVersion:0。
        "writeConcernMajorityJournalDefault" : true,  -- 如果写关注未明确指定日记选项j,则确定{w:"majority"}写关注的行为。true:在大多数有投票权的成员将其写入磁盘日志后才确认该写入操作。false:在大多数投票成员在内存中应用了该操作之后才确认该写操作。
        "members" : [    -- 副本集成员
            {
                "_id" : 0,   -- 成员标识,范围是0~255。
                "host" : "11.11.11.11:27017",  -- 成员地址
                "arbiterOnly" : false,   -- 是否为仲裁节点
                "buildIndexes" : true,   -- 是否在成员上创建索引,对于接受查询的实例,不能设置成false。如果设置为false,priority也需要是0,并且不能从该成员上进行复制
                "hidden" : false,        -- 是否为隐藏节点
                "priority" : 1,          -- 优先级,越大优先级越高,范围是0~1000
                "tags" : {               -- 标签,用来写关注
                    
                },
                "slaveDelay" : NumberLong(0),   -- 是否为延迟节点
                "votes" : 1                        -- 是否有投票权限
            },
            {
                "_id" : 1,
                "host" : "11.11.11.12:27017",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 1,
                "tags" : {
                    
                },
                "slaveDelay" : NumberLong(0),
                "votes" : 1
            },
            {
                "_id" : 2,
                "host" : "11.11.11.13:27017",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 1,
                "tags" : {
                    
                },
                "slaveDelay" : NumberLong(0),
                "votes" : 1
            }
        ],
        "settings" : {             -- 相关设置
            "chainingAllowed" : true,  --是否支持链式复制,true:副本集允许辅助成员从其他辅助成员进行复制;false:辅助服务器只能从主服务器复制
            "heartbeatIntervalMillis" : 2000, -- 心跳间隔,单位毫秒
            "heartbeatTimeoutSecs" : 10,      -- 心跳超时时间
            "electionTimeoutMillis" : 10000,  -- 选举检测副本集主数据库何时不可用的时间限制(以毫秒为单位),单位毫秒。在protocolVersion为1是可用。参数enableElectionHandoff为true,rs.stepDown会立即选举。不然等10s选举。
            "catchUpTimeoutMillis" : -1,      -- 新选择的主数据库与其他可能具有更近期写入操作的副本集成员同步(追赶)的时间限制(以毫秒为单位)-1:无限追赶时间。在protocolVersion为1是可用。版本3.6中启动的副本集降级为3.4,请将catchUpTimeoutMillis从-1更改为正数,不然导致运行版本3.4的节点既不重新启动也不加入副本集。
            "catchUpTakeoverDelayMillis" : 30000,  -- 新选择的主数据库追赶的超时时间,单位毫秒。在改时间内未完成追赶则当前主节点之前的节点会发起选举以成为副本集的新主节点
            "getLastErrorModes" : {   -- 自定义写关注点的文档,<number>是指满足写关注所需的不同标签值的数量。定义好的写关注名字,可以带入到getLastErrorDefaults参数中的w选项。
              <name of write concern> : { <tag1>: <number>, .... },   -- 参考 https://docs.mongodb.com/v4.2/tutorial/configure-replica-set-tag-sets/
              ...  
            },
            "getLastErrorDefaults" : { -- 写关注文档,如未设置,则副本集的默认写关注仅需要主数据库的确认。可以设置getLastErrorModes定义的。
                                       -- https://docs.mongodb.com/v4.2/reference/write-concern/
                "w" : 1,
                "wtimeout" : 0
            },
            "replicaSetId" : ObjectId("5f3498078ce4089ec0948365")  -- 自动创建的ObjectId
        }
    },
    "ok" : 1,
    "$clusterTime" : {
        "clusterTime" : Timestamp(1597297052, 1),
        "signature" : {
            "hash" : BinData(0,"LqYQwo/Nrx+gQrnnzJnYRMf8+78="),
            "keyId" : NumberLong("6860275335468941315")
        }
    },
    "operationTime" : Timestamp(1597297052, 1)       -- 操作执行时间
}
View Code

rs.status()  == db.adminCommand({replSetGetStatus:1}):查看副本集状态。

XYZ:PRIMARY> db.adminCommand({replSetGetStatus:1})
{
    "set" : "XYZ",  -- 复制集名(replSetName)
    "date" : ISODate("2020-08-13T02:24:38.530Z"),  -- 当前时间
    "myState" : 1,  -- 0到10之间的整数,表示当前成员的副本状态:https://docs.mongodb.com/manual/reference/replica-states/
    "term" : NumberLong(1),  -- 副本集成员的选举计数
    "syncingTo" : "",  -- 在MongoDB 4.4中删除,同syncSourceHost
    "syncSourceHost" : "",  -- 同步的成员的主机名
    "syncSourceId" : -1,    -- 如果此实例是主实例,则syncSourceHost为空字符串,且syncSourceId -1
    "heartbeatIntervalMillis" : NumberLong(2000),   -- 心跳的频率(以毫秒为单位)
    "majorityVoteCount" : 2,    -- 选举中所需的多数票的数字
    "writeMajorityCount" : 2,   -- 满足写关注“多数”需要的投票成员(即非仲裁员)的数量
    "optimes" : {
        "lastCommittedOpTime" : {  -- 写入大多数副本集成员的最新操作的信息
            "ts" : Timestamp(1597285472, 1),  -- 时间戳
            "t" : NumberLong(1)     -- 一个term里主上生成操作的次数
        },
        "lastCommittedWallTime" : ISODate("2020-08-13T02:24:32.634Z"), --和lastCommittedOpTime关联
        "readConcernMajorityOpTime" : {   -- 完成读取操作的最新操作的信息涉及“多数”查询
            "ts" : Timestamp(1597285472, 1),
            "t" : NumberLong(1)
        },
        "readConcernMajorityWallTime" : ISODate("2020-08-13T02:24:32.634Z"),  --和readConcernMajorityOpTime关联
        "appliedOpTime" : {               -- 应用于副本集此成员的最新操作的信息
            "ts" : Timestamp(1597285472, 1),
            "t" : NumberLong(1)
        },
        "durableOpTime" : {               -- 写入副本集此成员的日记中的最新操作的信息
            "ts" : Timestamp(1597285472, 1),
            "t" : NumberLong(1)
        },
        "lastAppliedWallTime" : ISODate("2020-08-13T02:24:32.634Z"),  --和appliedOpTime关联
        "lastDurableWallTime" : ISODate("2020-08-13T02:24:32.634Z")   --和durableOpTime关联
    },
    "lastStableRecoveryTimestamp" : Timestamp(1597285442, 1),
    "lastStableCheckpointTimestamp" : Timestamp(1597285442, 1),  -- 4.2版起弃用,适用于WiredTiger存储引擎,当前或上一个持久检查点所在的时间戳
    "electionCandidateMetrics" : {      -- 与选举相关的指标。 只有在主要候选人或候选人身上,才可以使用竞选候选人资格指标。 对于候选人,一旦候选人失去选举,该指标将不可用。
        "lastElectionReason" : "electionTimeout",   -- 该成员召集了选举
        "lastElectionDate" : ISODate("2020-08-13T01:32:02.522Z"),  -- 选举的日期和时间
        "electionTerm" : NumberLong(1),   -- 该成员要求进行新选举时的选举计数(即任期)
        "lastCommittedOpTimeAtElection" : {  -- 最近一次多数派承诺的optime要求进行新的选举
            "ts" : Timestamp(0, 0),
            "t" : NumberLong(-1)
        },
        "lastSeenOpTimeAtElection" : {  -- 该成员在要求进行新选举时最近一次使用optime
            "ts" : Timestamp(1597282312, 1),
            "t" : NumberLong(-1)
        },
        "numVotesNeeded" : 2,    -- 赢得选举所需的票数
        "priorityAtElection" : 1,   -- 成员在进行选举时的优先级
        "electionTimeoutMillis" : NumberLong(10000),   --成员选举的超时时间,单位毫秒,默认10s。
        "numCatchUpOps" : NumberLong(0),   -- 新当选的主其追赶过程时所应用的操作数
        "newTermStartDate" : ISODate("2020-08-13T01:32:02.560Z"),  -- 新任期条目写入操作日志的日期和时间
        "wMajorityWriteAvailabilityDate" : ISODate("2020-08-13T01:32:02.703Z")   --选择副本集后,可以使用写关注点“多数”的日期和时间(即,新任期oplog条目被提交了多数的日期和时间)。
    },
    "members" : [    -- 副本集中每个成员的文档
        {
            "_id" : 0,   -- 成员的标识符
            "name" : "11.11.11.11:27017",  --成员的名称
            "health" : 1,   -- 成员是否存活
            "state" : 1,    -- 0到10之间的整数,表示成员的副本状态,https://docs.mongodb.com/manual/reference/replica-states/
            "stateStr" : "PRIMARY",  -- 描述状态的字符串
            "uptime" : 5203,   -- 运行时间
            "optime" : {       -- 应用的操作日志中有关最后操作的信息
                "ts" : Timestamp(1597285472, 1), -- 操作日志中应用于副本集的此成员的最后一个操作的时间戳。
                "t" : NumberLong(1)               -- 最后一次应用的操作次数
            },
            "optimeDate" : ISODate("2020-08-13T02:24:32Z"),  -- 操作日志中的最后一个记录。 如果与lastHeartbeat明显不同,则该成员正在经历“复制滞后”,或者自上次更新以来没有任何新操作。
            "syncingTo" : "", -- 同步的成员的ip
            "syncSourceHost" : "",  -- 同步的成员的主机名,如果成员是Primary,则显示空格
            "syncSourceId" : -1, -- 如果成员是Primary,则显示-1,否则显示对应的member._id
            "infoMessage" : "", -- 复制集信息
            "electionTime" : Timestamp(1597282322, 1), -- 对于当前主数据库,有关操作日志中选举时间戳
            "electionDate" : ISODate("2020-08-13T01:32:02Z"), -- 对于当前主数据库,有关操作日志中选举时间
            "configVersion" : 1,  -- 副本集配置版本
            "self" : true,     -- 是否为当前mongod实例
            "lastHeartbeatMessage" : ""  -- 当最后一个心跳包括额外的消息时,lastHeartbeatMessage将包含该消息的字符串表示形式。
        },
        {
            "_id" : 1,
            "name" : "11.11.22.22:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 3166,
            "optime" : {
                "ts" : Timestamp(1597285472, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {    -- 对其日记(journal)应用的操作日志中有关最后操作的信息
                "ts" : Timestamp(1597285472, 1),   -- 操作的时间戳
                "t" : NumberLong(1)   -- 生产的操作次数
            },
            "optimeDate" : ISODate("2020-08-13T02:24:32Z"),
            "optimeDurableDate" : ISODate("2020-08-13T02:24:32Z"),
            "lastHeartbeat" : ISODate("2020-08-13T02:24:36.549Z"), -- 最后一次收到心跳的响应并发送给成员。将此值与date和lastHeartBeatRecv字段的值进行比较,以跟踪这些副本集成员之间的延迟。
            "lastHeartbeatRecv" : ISODate("2020-08-13T02:24:38.071Z"),  -- 同上
            "pingMs" : NumberLong(0),  -- 表示往返数据包在远程成员和本地实例之间传播所需的毫秒数。
            "lastHeartbeatMessage" : "",
            "syncingTo" : "11.11.22.23:27017",
            "syncSourceHost" : "11.11.22.23:27017",
            "syncSourceId" : 2,
            "infoMessage" : "",
            "configVersion" : 1
        },
        {
            "_id" : 2,
            "name" : "11.11.22.23:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 3166,
            "optime" : {
                "ts" : Timestamp(1597285472, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1597285472, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-08-13T02:24:32Z"),
            "optimeDurableDate" : ISODate("2020-08-13T02:24:32Z"),
            "lastHeartbeat" : ISODate("2020-08-13T02:24:36.591Z"),
            "lastHeartbeatRecv" : ISODate("2020-08-13T02:24:37.162Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "11.11.11.11:27017",
            "syncSourceHost" : "11.11.11.11:27017",
            "syncSourceId" : 0,
            "infoMessage" : "",
            "configVersion" : 1
        }
    ],
    "ok" : 1,  -- 是否执行成
    "$clusterTime" : {
        "clusterTime" : Timestamp(1597285472, 1),
        "signature" : {
            "hash" : BinData(0,"lbLV7xyYk7NJHtg6EFD/E7Jy+dE="),
            "keyId" : NumberLong("6860275335468941315")
        }
    },
    "operationTime" : Timestamp(1597285472, 1)   -- 命令执行时间
}
View Code

rs.slaveOk() 允许对从节点执行读取操作。

8. 维护模式,启用或禁用副本集从节点的维护模式,之后会进入RECOVERING状态:replSetMaintenance必须在从节点上的admin数据库下执行。

进入维护模式:

shard1:SECONDARY> db.adminCommand({"replSetMaintenance":true})
{ "ok" : 1 }
shard1:RECOVERING> 

RECOVERING状态的成员能复制,但是不允许读,可以用隐藏节点来替换该模式。

退出维护模式:

shard1:RECOVERING> db.adminCommand({"replSetMaintenance":false})
{ "ok" : 1 }
shard1:SECONDARY> 

9. OpLog大小设置replSetResizeOplog:动态调整,size参数以M为单位,而OpLog的大小以字节为单位。只能在与Wired Tiger存储引擎一起运行,减小操作日志的大小不会自动回收该磁盘空间。

db.adminCommand({replSetResizeOplog:1, size: 16384})

MongoDB 3.4和更早版本中,通过删除并重新创建local.oplog.rs集合来调整操作日志的大小,具体的操作可以看 MongoDB的oplogSize修改

MongoDB 3.6及更高版本中,请使用replSetResizeOplog命令来调整操作日志的大小。从MongoDB 4.0开始,MongoDB禁止drop local.oplog.rs集合。从Secondary成员开始,然后再进行Primary操作。

① 查看当前OpLog大小:

shard1:SECONDARY> use local
switched to db local
shard1:SECONDARY> db.oplog.rs.stats().maxSize
104857600   -- 100M

②:修改OpLog大小:

shard1:SECONDARY> db.adminCommand({replSetResizeOplog: 1, size: 1000})
{ "ok" : 1 }
shard1:SECONDARY> db.oplog.rs.stats().maxSize
1048576000   -- 1000M

在从节点上执行完之后,再去主节点上执行(先rs.stepDown)。

注意:对于MongoDB 4.2.2和更高版本,replSetResizeOplog在操作日志上获得排他(W)锁,并阻止对集合的其他操作,直到完成。对于MongoDB 4.2.1和更早版本,replSetResizeOplog采用全局排他(W)锁定并阻止所有其他操作,直到完成。

10. 回收磁盘空间压缩oplog.rs以回收磁盘空间,减小oplog的大小不会回收已经分配的磁盘空间,必须压缩oplog.rs来回收磁盘空间:

use local
db.runCommand({"compact" : "oplog.rs"})

注意:当执行压缩时,从节点无法复制oplog条目,会导致主节点的操作日志被覆盖,导致节点无法同步数据而产生重新完全同步,建议在无业务的时间段内执行压缩操作。 

11. settings的设置settings

rs.config().settings:修改副本集的一些设置,可以看上面的rs.conf()说明:

  • chainingAllowed:默认ture。只有true才能使用参数initialSyncSourceReadPreference
    当settings.chainingAllowed为true时,副本集允许辅助成员从其他辅助成员进行复制(链式复制)。 当settings.chainingAllowed为false时,辅助节点只能从主节点复制。
  • heartbeatIntervalMillis:默认2000
    各个副本间的心跳间隔,单位毫秒,默认2秒。
  • heartbeatTimeoutSecs:默认10秒
    副本集成员等待彼此成功发出心跳的秒数。 如果某个成员未及时响应,则其他成员会将该成员标记为不可访问。
  • electionTimeoutMillis:默认1000毫秒,即10秒
    检测副本集主库不可用的时间限制(以毫秒为单位),较高的值会导致较慢的故障转移,会降低对主节点或网络的速度的敏感度。
    较低的值将导致更快的故障转移,会增加对主节点或网络的速度的敏感性。
    在版本4.0.2中:如果参数enableElectionHandoff为true(默认值),则当主节点从rs.stepDown降级时,已降级的主节点将指定合格的辅助节点立即选举。否则,辅助节点在调用选举之前先等待settings.electionTimeoutMillis。
  • catchUpTimeoutMillis:单位毫秒,默认-1,不限制追赶时间
    新选择的主数据库与其他可能具有更近期写入操作的副本集成员同步(追赶)的时间限制(以毫秒为单位)。无限或高时间限制可能会减少选举后其他成员需要回滚的数据量,但可能会增加故障转移时间。
    一旦新当选的主要成员完全赶上集合中的其他成员,他们就会提前结束赶超阶段。在追赶期间,新选择的主服务器不可用于来自客户端的写入。使用replSetAbortPrimaryCatchUp中止追赶,然后完成向主要角色的过渡。
  • catchUpTakeoverDelayMillis:默认30000毫秒,即30秒
    接管的节点确定它在当前主节点之前,然后等待指定的毫秒数,发起选举。选举验证以下内容:
    它仍然领先于当前的主要数据库,
    它是所有可用节点中最新的节点,
    当前的主数据库正在赶上它。
    一旦确定满足所有这些条件,发起接管的节点将立即运行以进行选举。
  • getLastErrorModes:通过使用member[n].tags自定义写关注点的文档,定制写关注点可以提供数据中心的概念。
    格式:
    { getLastErrorModes: {
       <name of write concern> : { <tag1>: <number>, .... },
       ...
    } }

    <number>是指满足写关注所需的不同标签值的数量。 例如,以下settings.getLastErrorModes定义了一个名为datacenter的写关注点,该写关注点要求该写传播到dc tag不同的两个成员:

    { getLastErrorModes: { datacenter: { "dc": 2 } } }

    要使用自定义写关注点,请将写关注点名称传递给w选项:

    { w: "datacenter" }

    tag的设置就在member[n].tags中定义,即副本集成员中的属性。如何配置tags请看文档说明

    db.collection.insert( { id: "xyz", status: "A" }, { writeConcern: { w: "datacenter" } } )
  • getLastErrorDefaults
    指定副本集写关注点的文档。 仅当写入操作或getLastError没有指定其他写入时,副本集才会使用此写关注。
    
    如果未设置settings.getLastErrorDefaults,则副本集的默认写关注点仅需要主数据库的确认。{"w" : 1},如:
    db..insert(    { item: "envelopes", qty : 100, type: "Clasp" },    { writeConcern: { w: 4 , wtimeout: 5000 } } )
    如果数量不足4个,则会报错:Not enough data-bearing nodes
  • replicaSetId
    与副本集关联并在rs.initiate()或replSetInitate期间自动创建的ObjectId

local数据库:

MongoDB实例都有其自己的本地数据库,副本集中各个成员的复制数据时都是把local数据库排除在外将其他数据库的数据复制到自己的数据库中。关于local的数据库介绍可以看文档。现在来看下local数据库下存的是哪些集合:

① local.startup_log:startup_log是一个capped文档,记录实例启动的一些诊断信息

> db.startup_log.find().pretty()
{
    "_id" : "test4-1614219412340",
    "hostname" : "test4",
    "startTime" : ISODate("2021-02-25T02:16:52Z"),
    "startTimeLocal" : "Thu Feb 25 02:16:52.340",
    "cmdLine" : {
        "config" : "/usr/local/mongodb_2/mongo.conf",
        "net" : {
            "bindIp" : "0.0.0.0",
            "maxIncomingConnections" : 65536,
            "port" : 27018,
            "unixDomainSocket" : {
                "enabled" : true,
                "filePermissions" : 448,
                "pathPrefix" : "/tmp"
            },
            "wireObjectCheck" : true
        },
        "operationProfiling" : {
            "mode" : "slowOp",
            "slowOpSampleRate" : 1,
            "slowOpThresholdMs" : 100
        },
        "processManagement" : {
            "fork" : true,
            "pidFilePath" : "/usr/local/mongodb_2/mongodb.pid"
        },
        "replication" : {
            "enableMajorityReadConcern" : false,
            "oplogSizeMB" : 100,
            "replSetName" : "shard1"
        },
        "security" : {
            "authorization" : "enabled",
            "keyFile" : "/usr/local/mongodb_2/xx_keyfile"
        },
        "sharding" : {
            "archiveMovedChunks" : false,
            "clusterRole" : "shardsvr"
        },
        "storage" : {
            "dbPath" : "/usr/local/mongodb_2/data",
            "directoryPerDB" : true,
            "engine" : "wiredTiger",
            "journal" : {
                "commitIntervalMs" : 500,
                "enabled" : true
            },
            "syncPeriodSecs" : 60,
            "wiredTiger" : {
                "collectionConfig" : {
                    "blockCompressor" : "snappy"
                },
                "engineConfig" : {
                    "cacheSizeGB" : 1,
                    "directoryForIndexes" : false,
                    "journalCompressor" : "snappy",
                    "maxCacheOverflowFileSizeGB" : 0
                },
                "indexConfig" : {
                    "prefixCompression" : true
                }
            }
        },
        "systemLog" : {
            "destination" : "file",
            "logAppend" : true,
            "logRotate" : "rename",
            "path" : "/usr/local/mongodb_2/logs/mongodb.log",
            "quiet" : false,
            "timeStampFormat" : "iso8601-local",
            "traceAllExceptions" : false,
            "verbosity" : 0
        }
    },
    "pid" : NumberLong(70856),
    "buildinfo" : {
        "version" : "4.2.8",
        "gitVersion" : "43d25964249164d76d5e04dd6cf38f6111e21f5f",
        "modules" : [ ],
        "allocator" : "tcmalloc",
        "javascriptEngine" : "mozjs",
        "sysInfo" : "deprecated",
        "versionArray" : [
            4,
            2,
            8,
            0
        ],
        "openssl" : {
            "running" : "OpenSSL 1.1.1  11 Sep 2018",
            "compiled" : "OpenSSL 1.1.1  11 Sep 2018"
        },
        "buildEnvironment" : {
            "distmod" : "ubuntu1804",
            "distarch" : "x86_64",
            "cc" : "/opt/mongodbtoolchain/v3/bin/gcc: gcc (GCC) 8.2.0",
            "ccflags" : "-fno-omit-frame-pointer -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-local-typedefs -Wno-unused-function -Wno-deprecated-declarations -Wno-unused-const-variable -Wno-unused-but-set-variable -Wno-missing-braces -fstack-protector-strong -fno-builtin-memcmp",
            "cxx" : "/opt/mongodbtoolchain/v3/bin/g++: g++ (GCC) 8.2.0",
            "cxxflags" : "-Woverloaded-virtual -Wno-maybe-uninitialized -fsized-deallocation -std=c++17",
            "linkflags" : "-pthread -Wl,-z,now -rdynamic -Wl,--fatal-warnings -fstack-protector-strong -fuse-ld=gold -Wl,--build-id -Wl,--hash-style=gnu -Wl,-z,noexecstack -Wl,--warn-execstack -Wl,-z,relro",
            "target_arch" : "x86_64",
            "target_os" : "linux"
        },
        "bits" : 64,
        "debug" : false,
        "maxBsonObjectSize" : 16777216,
        "storageEngines" : [
            "biggie",
            "devnull",
            "ephemeralForTest",
            "wiredTiger"
        ]
    }
}
View Code

② local.system.replset:副本集的配置信息,信息和rs.conf()输出一样

③ local.oplog.rs:用来保存oplog的capped集合,类似于MySQL的Binlog

④ local.replset.minvalid:副本集在内部使用该集合来跟踪复制状态 

复制集读写:

关于标签集(tags set)的读写方式可以看官网例子

1. 读

① 读首选项:Read Preference :控制客户端 Driver API 从复制集的哪个节点读取数据,方便的实现读写分离、就近读取等策略。默认读主节点。策略有:

  • primary只从 primary 节点读数据(默认设置),和使用tag或maxStalenessSeconds的模式不兼容。
  • primaryPreferred优先从 primary 读取,primary 不可服务,从 secondary 读:
  • secondary只从 scondary 节点读数据。
  • secondaryPreferred优先从 secondary 读取,没有 secondary 成员时,从 primary 读取。
  • nearest根据网络距离就近读取,距离最近的成员不超过15毫秒。

注意:读取操作多文档事务必须使用primary模式,给定事务中的所有操作都必须路由到同一成员。除primary外,其他模式可以包含 maxStalenessSecondstag sets

  • 当包含maxStalenessSeconds值时,会对比主和从的延迟是否大于该值,小于则直接从节点读取,该值需要大于90秒。
  • 当包含 tag sets 时,会在匹配标签的从上进行读取。可以在副本集成员的属性中修改tag。具体的使用可以看文档说明。
  • 当包含maxStalenessSeconds和 tag set 时,先根据数据的延迟maxStalenessSeconds过滤,再根据tag set读取。

从地理分布的成员进行查询

如果副本集的成员在地理位置上分散,则可以基于副本集标记来反映实例的位置,然后将应用程序配置为查询附近的成员。如,如果“东部”和“西部”数据中心中的成员被标记为{'dc''east'}和{'dc''west'},则东部数据中心中的应用程序服务器可以从附近的成员中读取 具有以下读取首选项:
> db.collection.find().readPref('nearest', [ { 'dc': 'east' } ])

除primary模式外,其他模式都可能返回陈旧数据,因为辅助数据库在异步过程中从主数据库复制操作。虽然可以通过maxStalenessSeconds来控制延迟。但可以配合 read concern 使用来解决延迟导的问题。

② 读关注:Read Concern:通过写入关注点和读取关注点,控制从副本集和副本集分片读取的数据的一致性和隔离性。决定到某个读取数据时,能读到什么样的数据。

  • "local":该查询从实例返回数据,但不能保证该数据已被写入大多数副本集成员(即可以回滚),默认。
  • "available":该查询从实例返回数据,但不能保证该数据已被写入大多数副本集成员(即可以回滚)。
  • "majority":该查询返回大多数副本集成员已确认的数据。即使发生故障也很不影响。副本集必须使用WiredTiger存储引擎。对于具有三名成员的主从仲裁器(PSA)架构的部署,可以禁用“读取关注”的“多数”功能。对于多文档事务中的操作,仅当事务以write Concern “多数”提交时,Read Concern “多数”才提供其保证。否则,“多数”读取问题不能保证事务中读取的数据。
  • "linearizable":该查询返回的数据反映了在读取操作开始之前完成的所有成功的多数确认写入。在返回结果之前,查询可以等待并发执行的写入传播到大多数副本集成员。
    writeConcernMajorityJournalDefault为true(默认):持久,不丢失回滚
    writeConcernMajorityJournalDefault为false:可能丢失回滚
  • "snapshot":仅可用于多文档事务。

readPreference 和 readConcern 可以配合使用。

readConcern 解决什么问题

readConcern 的初衷在于解决『脏读』的问题,比如用户从 MongoDB 的 primary 上读取了某一条数据,但这条数据并没有同步到大多数节点,然后 primary 就故障了,重新恢复后 这个primary 节点会将未同步到大多数节点的数据回滚掉,导致用户读到了『脏数据』。

当指定 readConcern 级别为 majority 时,能保证用户读到的数据『已经写入到大多数节点』,而这样的数据肯定不会发生回滚,避免了脏读的问题。

需要注意的是,readConcern 能保证读到的数据『不会发生回滚』,但并不能保证读到的数据是最新的,这个官网上也有说明。有用户误以为,readConcern 指定为 majority 时,客户端会从大多数的节点读取数据,然后返回最新的数据。

实际上并不是这样,无论何种级别的 readConcern,客户端都只会从『某一个确定的节点』(具体是哪个节点由 readPreference 决定)读取数据,该节点根据自己看到的同步状态视图,只会返回已经同步到大多数节点的数据。

readConcern 实现原理:

MongoDB 要支持 majority 的 readConcern 级别,必须设置replication.enableMajorityReadConcern参数,加上这个参数后,MongoDB 会起一个单独的snapshot 线程,会周期性的对当前的数据集进行 snapshot,并记录 snapshot 时最新 oplog的时间戳,得到一个映射表。

最新 oplog 时间戳snapshot状态
t0 snapshot0 committed
t1 snapshot1 uncommitted
t2 snapshot2 uncommitted
t3 snapshot3 uncommitted

只有确保 oplog 已经同步到大多数节点时,对应的 snapshot 才会标记为 commmited,用户读取时,从最新的 commited 状态的 snapshot 读取数据,就能保证读到的数据一定已经同步到的大多数节点。

关键的问题就是如何确定『oplog 已经同步到大多数节点』?

primary 节点

secondary 节点在自身oplog发生变化时,会通过 replSetUpdatePosition 命令来将 oplog 进度立即通知给 primary,另外心跳的消息里也会包含最新 oplog 的信息;通过上述方式,primary 节点能很快知道 oplog 同步情况,知道『最新一条已经同步到大多数节点的 oplog』,并更新 snapshot 的状态。比如当t2已经写入到大多数据节点时,snapshot1、snapshot2都可以更新为 commited 状态。(不必要的 snapshot也会定期被清理掉)

secondary 节点

secondary 节点拉取 oplog 时,primary 节点会将『最新一条已经同步到大多数节点的 oplog』的信息返回给 secondary 节点,secondary 节点通过这个oplog时间戳来更新自身的 snapshot 状态。

注意:

  • 目前 readConcern 主要用于 mongos 与 config server 的交互上
  • 使用 readConcern 需要配置replication.enableMajorityReadConcern选项
  • 只有支持 readCommited 隔离级别的存储引擎才能支持 readConcern,比如 wiredtiger 引擎。

2. 写

写关注:Write Concern MongoDB请求对独立mongod或副本集或分片集群的写操作的确认级别。 在分片集群中,mongos实例会将写关注事项传递给分片。

4.4开始,副本集和分片群集支持设置全局默认写入,未指定显式写关注点的操作将继承全局默认写关注点设置

格式:可以在命令行里指定,也可以修改settings里的默认模式来修改。

{ w: <value>, j: <boolean>, wtimeout: <number> }
  • w:请求确认写入操作已传播到指定数量的mongod实例或具有指定标签的mongod实例,如果实例不足,则写入报错。
  • j:请求确认已将写操作写入磁盘日志中。
  • wtimeout:指定一个时间限制,以防止无限期地阻止写操作。

w:

value 含义
num

1:是MongoDB的默认写关注点,写自身Primary节点。可回滚;

0:不要求确认写入操作。但可能会将有关套接字异常和网络错误的信息返回给应用程序。可回滚。

>1:需要>1个节点确认,比如3,则需要1Primary和2Secondary确认。

注意:Hidden, delayed, and priority 0的节点可以确认

副本集的任何带有数据的投票成员都可以对“多数”写操作进行写确认。

 majority

请求确认写入操作已传播到所计算的大多数带有数据的投票成员(具有投票属性)。

比如P-S-S架构,需要写入P和一个S

 自定义写关注名 请求确认写操作已传播到满足settings.getLastErrorModes中定义的自定义写关注点的标记成员。

 j: 

value  含义
true true: 请求确认已将w:<value>中指定的mongod实例写入磁盘日志中。仅在请求数量的成员(包括主要成员)写入日志后才返回,副本集中表现为需要将操作写入磁盘日志
false false:不需要确认写入。副本集中表现为需要将操作写入内存

wtimeout

指定写关注的时间限制(以毫秒为单位)。 wtimeout仅适用于大于1的w值。如果写操作超过指定时间之后则返回错误,即使最终成功完成了必需的写操作。 当这些写操作返回时,MongoDB不会撤消在写关注超出wtimeout时间限制之前执行的成功数据修改。如果未指定wtimeout选项(0),并且无法达到写关注级别,则写操作将无限期阻塞。 例:

-- 在P-S-S架构中,摸一个S宕机,需要写入3个节点
XYZ:PRIMARY> db.xx.insert({"aaa":3},{writeConcern:{w:3 ,j:true , wtimeout:5000 }})
WriteResult({
    "nInserted" : 1,
    "writeConcernError" : {
        "code" : 64,
        "codeName" : "WriteConcernFailed",
        "errmsg" : "waiting for replication timed out",
        "errInfo" : {
            "wtimeout" : true
        }
    }
})

-- 需要写入2个节点
XYZ:PRIMARY> db.xx.insert({"aaa":3},{writeConcern:{w:2 ,j:true , wtimeout:5000 }})
WriteResult({ "nInserted" : 1 })
View Code
-- 副本集包含3个有投票权的成员(P-S-S):
所有投票成员中大多数为2。
所有有数据投票的成员人数为3。
多数为2,最小值为2和3。写入必须传播到主和一个从,以向客户端确认写入关注“多数”。

-- 副本集包含3个投票成员,主要-次要仲裁员(P-S-A)
所有投票成员中大多数为2。
所有有数据投票的成员人数为2。
计算得出的多数为2,最小值为2和2。由于该写操作只能应用于数据承载成员,因此该写操作必须传播到主和从,以向客户端确认写关注点“多数”。

避免对(P-S-A)或其他拓扑使用 majority write concern 问题,以为一个从节点失效之后,写入就失败了。使用 majority write concern方式来保证持久性的应改用不要求所有具有数据投票权的成员都可用的拓扑(例如P-S-S)。

参数设置:

参数除了在配置文件中设置外,部分动态参数也可以直接在命令行里修改。

① 查看参数getParameter

用于在命令行上查看参数,必须在admin数据库下执行,并以以下形式对管理数据库发出setParameter命令:

db.adminCommand( { getParameter : 1, <parameter> : <value> } )

查看指定参数saslHostName的值:

> db.adminCommand( { getParameter : 1, "saslHostName" : 1 } )
{ "saslHostName" : "test4", "ok" : 1 }

查看所有参数:

db.adminCommand( { getParameter : '*' } )

② 修改参数setParameter

用于在命令行上修改参数,必须在admin数据库下执行,以以下形式对管理数据库发出setParameter命令:

db.adminCommand( { setParameter: 1, <parameter> : <value> } )

对应在配置文件中的为:

setParameter:
   <parameter1>: <value1>

对应命令行启动的为:

mongod --setParameter <parameter>=<value>
mongos --setParameter <parameter>=<value>

修改指定参数:logLevel

> db.adminCommand( { setParameter: 1, logLevel: 2 } )

关于其他一些可修改的参数,可以看:服务器可调参数

 

参考文档:

Replication

Replication Methods

Replication Commands

MongoDB 副本集的原理、搭建、应用

MongoDB 副本集管理

 

posted @ 2021-03-04 16:42  jyzhou  阅读(1871)  评论(0编辑  收藏  举报