升级后,Mongodb Atlas 开始颠簸 IOPS 和页面错误,并且查询速度非常慢

After an upgrade, Mongodb Atlas starts thrashing IOPS and page faulting, and very slow queries build up

我们在 Mongodb Atlas 中遇到了一个偶发的性能问题,在我们升级集群之后或当主集群发生变化时。 [升级过程由 MongoDb Atlas 服务自动执行,因此我们对此机制的了解有限]

集群类型是: M30(8GB 内存) 升级 4.2 -> 4.4 预置 IOPS:1500

升级后(从 4.0 -> 4.2 也发生过这种情况)我们将看到有关 IOPS 超过 80% 预配置的警报,并出现页面错误,图表对此做了最好的解释:

另一个重要的观察是非常慢的查询似乎没有适当地利用索引:

例如这个查询(略有删节)

{
  "command": {
    "count": "projects",
    "query": {
      "$and": [
       {
          "account": {
            "$oid": "RETRACTED"
          }
        },
        ....
        ....
        ....
"planSummary": [
    {
      "IXSCAN": {
        "account": 1,
        "hasTemplateChildren": 1,
        "templateParent": 1,
        "lastEditedAt": -1
      }
    },
    {
      "IXSCAN": {
        "templateParent": 1
      }
    }
  ],
  "keysExamined": 1604628,
  "docsExamined": 1631743,

这表明正在使用所需的索引,但仍在检查超过 160 万个密钥和文档。整个projectstable有大约190万行,任何一个账户最多有30k行项目。

希望这是足够的信息。在此先感谢您的帮助。

一个更新,我们已经解决了这个问题,问题似乎出在我遗漏的部分查询上,为清楚起见,张贴在这里。查询计划器似乎因为特定的表达式而感到困惑:

{
   "$or": [
    {
      "templateParent": {
          "$exists": false
       }
    },
    {
       "templateParent": null
     }
    ]
 }

正是它导致整个索引(templateParent 上的索引)作为子 inputStage 的一部分被扫描。

将上面的表达式更改为:

  {
    "templateParent": null
  }

允许查询规划器执行更明智的查询。

如果有人想更深入地解释为什么这会使查询规划器表现得更好,请做。