2

我已经设置了一个包含 4 个服务器的副本集。

出于测试目的,我编写了一个脚本来使用 GridFS 将我的数据库填充到大约 1.5 亿行照片。我的照片约为 15KB。(将gridfs用于小文件应该不是问题吗?!)

几个小时后,大约有 5000 万行,但我在日志中有这条消息

replSet error RS102 too stale to catch up, at least from 192.168.0.1:27017

这是 replSet 状态:

 rs.status();
{
"set" : "rsdb",
"date" : ISODate("2012-07-18T09:00:48Z"),
"myState" : 1,
"members" : [
    {
        "_id" : 0,
        "name" : "192.168.0.1:27017",
        "health" : 1,
        "state" : 1,
        "stateStr" : "PRIMARY",
        "optime" : {
            "t" : 1342601552000,
            "i" : 245
        },
        "optimeDate" : ISODate("2012-07-18T08:52:32Z"),
        "self" : true
    },
    {
        "_id" : 1,
        "name" : "192.168.0.2:27018",
        "health" : 1,
        "state" : 3,
        "stateStr" : "RECOVERING",
        "uptime" : 64770,
        "optime" : {
            "t" : 1342539026000,
            "i" : 5188
        },
        "optimeDate" : ISODate("2012-07-17T15:30:26Z"),
        "lastHeartbeat" : ISODate("2012-07-18T09:00:47Z"),
        "pingMs" : 0,
        "errmsg" : "error RS102 too stale to catch up"
    },
    {
        "_id" : 2,
        "name" : "192.168.0.3:27019",
        "health" : 1,
        "state" : 3,
        "stateStr" : "RECOVERING",
        "uptime" : 64735,
        "optime" : {
            "t" : 1342539026000,
            "i" : 5188
        },
        "optimeDate" : ISODate("2012-07-17T15:30:26Z"),
        "lastHeartbeat" : ISODate("2012-07-18T09:00:47Z"),
        "pingMs" : 0,
        "errmsg" : "error RS102 too stale to catch up"
    },
    {
        "_id" : 3,
        "name" : "192.168.0.4:27020",
        "health" : 1,
        "state" : 3,
        "stateStr" : "RECOVERING",
        "uptime" : 65075,
        "optime" : {
            "t" : 1342539085000,
            "i" : 3838
        },
        "optimeDate" : ISODate("2012-07-17T15:31:25Z"),
        "lastHeartbeat" : ISODate("2012-07-18T09:00:46Z"),
        "pingMs" : 0,
        "errmsg" : "error RS102 too stale to catch up"
    }
],
"ok" : 1

该设备仍在接受数据,但是由于我的 3 台服务器“停机”,我应该如何进行修复(比删除数据和重新同步要好,这需要很长时间,但会起作用)?

尤其是: 这是因为剧本过于暴力吗?这意味着它几乎从未在生产中发生过?

4

1 回答 1

10

您无需修复,只需执行完全重新同步即可。

在辅助上,您可以:

  1. 停止失败的mongod
  2. 删除 dbpath 中的所有数据(包括子目录)
  3. 重新启动它,它会自动重新同步自己

按照此处的说明进行操作。

在您的情况下发生的情况是您的辅助节点已经过时,即它们的 oplog 和主节点上的 oplog 没有共同点。查看此文档,其中详细说明了各种状态。对主要成员的写入必须复制到辅助节点,而您的辅助节点无法跟上,直到它们最终变得陈旧。您将需要考虑调整oplog的大小。

关于 oplog 大小,这取决于您随时间插入/更新的数据量。我会选择一个允许您使用数小时甚至数天的 oplog 的大小。

此外,我不确定您正在运行哪个操作系统。但是,对于 64 位 Linux、Solaris 和 FreeBSD 系统,MongoDB 会将 5% 的可用可用磁盘空间分配给 oplog。如果此数量小于 1 GB,则 MongoDB 将分配 1 GB 的空间。对于 64 位 OS X 系统,MongoDB 为 oplog 分配 183 MB 的空间,对于 32 位系统,MongoDB 为 oplog 分配大约 48 MB 的空间。

记录有多大,你想要多少?这取决于您只是在测试的这种数据插入是典型的还是异常的。

例如,对于 1KB 的文档,如果每秒处理 2000 个文档,那么每分钟可以净赚 120MB,而 5GB 的 oplog 将持续大约 40 分钟。这意味着如果辅助节点离线 40 分钟或落后超过 40 分钟,那么您已经过时并且必须进行完全重新同步。

我建议在这里阅读 Replica Set Internals 文档。您的副本集中有 4 个成员,不建议这样做。您应该有一个奇数的投票选举(主要)过程,因此您需要添加一个仲裁器、另一个辅助节点或删除一个辅助节点。

最后,这里有一份关于RS 管理的详细文档。

于 2012-07-18T10:21:38.167 回答