MongoDB复制集简介(二)--内部信息

来源:互联网 发布:电脑软件设置密码 编辑:程序博客网 时间:2024/05/16 13:59

MongoDB复制集简介(二)

MongoDB内部有一个Local数据库,其中存储了与复制有关的内部信息。Local数据库本身对复制不可见,即其中的集合、文档不会被复制到其他机器。

Local数据库与复制集有关的集合如下:

local.system.replset:存储了复制集的配置信息,我们使用rs.conf()查看内容,也可以直接查询该集合。

local.oplog.rs:存储了用于复制的日志信息,该集合是一个固定大小、循环使用的集合。

local.replset.minvalid:存储了用于跟踪复制状态的内部信息
local.slaves:存储了复制集的成员信息以及最近同步的时间点


test:PRIMARY> use local
switched to db local

test:PRIMARY> show collections   
oplog.rs
replset.minvalid
slaves
startup_log
system.indexes
system.replset

 

一、复制集配置

MongoDB复制集配置主要有_id、version、members和属性settings组成,可以通过rs.conf()查看,也可以直接查询local.system.replset集合。

     test:SECONDARY> use local
     switched to db local
     test:SECONDARY> db.system.replset.find()
     
     { "_id" : "test",
       "version" : 6,
       "members" : [ 
               {       "_id" : 1,      "host" : "localhost.localdomain:27217",         "priority" : 2 },  
               {       "_id" : 2,      "host" : "localhost.localdomain:27317",         "priority" : 3 },      
               {       "_id" : 3,      "host" : "localhost.localdomain:27117" }
                 ]
     }

 

 其中,_id属性表示了复制集的名字,与启动mongod进程时指定的复制集名字相同;members为一个数组,复制集中的每个成员都作为一个文档被包含在这个数组中。members具有以下属性:

    {
       _id : <ordinal>,
       host : hostname<:port>,
       <arbiterOnly : <boolean>,>
       <buildIndexes : <boolean>,>
       <hidden : <boolean>,>
       <priority: <priority>,>
       <tags: { <document> },>
       <slaveDelay : <number>,>
       <votes : <number>>
    }

 

其中host指出成员所在的主机名和端口号,属性arbiterOnly表示该成员是否仲裁者,默认为false。属性buildIndexes表示mongod进程是否在该成员上构建索引,默认为true。在成员仅仅用于备份或者不接受查询的情况下,忽略索引是有帮助的。属性hidden表示成员是否可见,包括读操作都不能到达该成员,默认为false。属性priority用于选举主机,该值越大表示优先级越高,越有可能成为主机,默认值为1。属性tags用于一组标记,用于描述成员的用途。属性slaveDelay表示该成员延迟几秒从主机复制。votes一般1或0,表示该成员是否参与主机选举。

我们可以直接修改members的成员属性对复制集进行配置,如修改优先级(注意members数组下标从0开始,与_id不是一个含义):

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

 

复制集配置中settings具有以下属性

settings: {
 <getLastErrorDefaults : <lasterrdefaults>,>
 <chainingAllowed : <boolean>,>
 <getLastErrorModes : <modes>>
}

其中getLastErrorDefaults用于设置getLastError返回的默认值。chainingAllowed表示该成员是否可以级联从其他从机复制,默认为true。getLastErrorModes描述了名字和成员组合用于应用层使用getLastError方法对是否成功写入数据的确认。

 

二、复制集日志

 

MongoDB的复制集日志是通过local数据库下的oplog.rs保存的,oplog.rs是一个固定大小的集合,可以在启动mongodb时通过参数oplogSize指定大小。oplog.rs结构如下:

 

       { ts : ..., h: ..., v: ..., op: ..., ns: ..., o: ... o2: ...  }

 

其中 ts为时间戳,h为hash值,v为oplog的版本号,op表示操作,可能的取值如下:

        "i" : 表示插入操作
        "u" :表示更新操作
        "d" :表示删除操作
        "c" :表示db cmd,表示运行db.runCommand()
        "n" :表示无操作,一般用于复制集本身的配置修改或初始化。

 

oplog.rs中ns表示命名空间,也就是操作的集合名,o表示文档的具体内容。

我们通过修改复制成员的优先级,查看一下oplog.rs的内容。

test:PRIMARY> db.oplog.rs.find().limit(1).sort( { ts : -1 } ).pretty()
{
        "ts" : Timestamp(1382374260, 1),
        "h" : NumberLong("-2381899609645775674"),
        "v" : 2,
        "op" : "n",
        "ns" : "",
        "o" : {
                "msg" : "Reconfig set",
                "version" : 8
        }
}

在修改之前,我们看到oplog.rs的最后一条记录内容是一条复制集配置操作,当前复制集版本号为8.

 

test:PRIMARY>cfg=rs.conf()
test:PRIMARY>cfg.members[0].priority=3
test:PRIMARY>cfg.members[1].priority=2
test:PRIMARY>cfg.members[2].priority=1

test:PRIMARY>rs.reconfig(cfg)

 

修改完成以后,我们再查看一下oplog.rs的最后两条记录,发现新的配置操作已经记录到oplog.rs中,并且复制集的配置版本已经变成9。

test:SECONDARY> db.oplog.rs.find().limit(2).sort( { ts :-1 } ).pretty()db.oplog.rs.find().limit(2).sort( { ts :-1 } ).pretty()
{
        "ts" : Timestamp(1382376712, 1),
        "h" : NumberLong("-1575134825584687483"),
        "v" : 2,
        "op" : "n",
        "ns" : "",
        "o" : {
                "msg" : "Reconfig set",
                "version" : 9
        }
}
{
        "ts" : Timestamp(1382374260, 1),
        "h" : NumberLong("-2381899609645775674"),
        "v" : 2,
        "op" : "n",
        "ns" : "",
        "o" : {
                "msg" : "Reconfig set",
                "version" : 8
        }
}

 

我们测试在主机上插入一条记录,查看oplog的内容:

test:PRIMARY> use test

switched to db test

test:PRIMARY> db.test.insert({empno:100,name:100,address:' it is a test!!!!'})

test:PRIMARY> use local
switched to db local
test:PRIMARY> db.oplog.rs.find().limit(1).sort( { ts :-1 } ).pretty()
{
        "ts" : Timestamp(1382377459, 1),
        "h" : NumberLong("5755918670421899025"),
        "v" : 2,
        "op" : "i",
        "ns" : "test.test",
        "o" : {
                "_id" : ObjectId("526567f3a1c239e61e9bdda2"),
                "empno" : 100,
                "name" : 100,
                "address" : " it is a test!!!!"
        }
}

 

我们发现oplog中已经将插入的文档完整记录下来,并且op类型为i,表示是插入操作,ns为“test.test"表示test库上的test集合。


 

 

 

 

 


 

 

 

 

 

原创粉丝点击