【问题标题】:MongoDB currentOp() and Cursor.explain() shows different result for the same queryMongoDB currentOp() 和 Cursor.explain() 显示相同查询的不同结果
【发布时间】:2019-10-13 16:04:25
【问题描述】:

我已经使用 MongoDB 3.2 多年,我发现 currentOp()Cursor.explain() 显示相同查询的不同结果。

我发现几个查询正在执行很长时间(20+ 秒),我认为这是不可能的,因为我测试了很多并且有索引。据我所知,查询通常是相同的。我认为它们会导致整个数据库锁定,因为当某些查询变慢时,几乎 40-50 个查询会卡在 currentOp() 中。

但是当我在 shell 中执行相同的读取操作时,它运行得非常快,正如我所期望的那样。我从currentOp 获取了相同的查询并执行了。

当数据库锁定(我认为它已锁定)时,CPU 利用率会持续数小时达到 100%,我的应用程序将会非常缓慢。我每 1 分钟监视一次currentOp,当它持续几秒钟没有结束时,我必须重新启动应用程序然后它才能正常运行。

这是一个需要很长时间的查询。一旦发生这种情况,40-50 个其他但类似的查询也会卡在currentOp

{
    "desc"              : "conn32882",
    "threadId"          : "140677207643904",
    "connectionId"      : 32882,
    "client"            : "client",
    "active"            : true,
    "opid"              : 1374027609,
    "secs_running"      : 20,
    "microsecs_running" : NumberLong(20560351),
    "op"                : "query",
    "ns"                : "db.collection",
    "query"             : {
        "find"         : "collection",
        "filter"       : {
            "p"    : {
                "$gt" : 0
            },
            "type" : "canvas",
            "id"   : {
                "$in" : [
                    576391,
                    570391,
                    767422
                ]
            }
        },
        "sort"         : {
            "_id" : -1
        },
        "projection"   : {
        
        },
        "limit"        : 5000,
        "returnKey"    : false,
        "showRecordId" : false
    },
    "numYields"         : 2761,
    "locks"             : {
        "Global"     : "r",
        "Database"   : "r",
        "Collection" : "r"
    },
    "waitingForLock"    : false,
    "lockStats"         : {
        "Global"     : {
            "acquireCount"        : {
                "r" : NumberLong(5524)
            },
            "acquireWaitCount"    : {
                "r" : NumberLong(349)
            },
            "timeAcquiringMicros" : {
                "r" : NumberLong(6613952)
            }
        },
        "Database"   : {
            "acquireCount" : {
                "r" : NumberLong(2762)
            }
        },
        "Collection" : {
            "acquireCount" : {
                "r" : NumberLong(2762)
            }
        }
    }
}

这是带有executionStats 选项的shell 中相同查询的输出。

命令:

db.canvasdatas.find({
        "p"   : {
            "$gt": 0
        },
        "type": "canvas",
        "id"  : {
            "$in": [
                576391,
                570391,
                767422
            ]
        }
    }, {}).sort({ _id: -1 }).limit(5000).explain('executionStats');

输出:

{
    "queryPlanner"   : {
        "plannerVersion" : 1,
        "namespace"      : "db.collection",
        "indexFilterSet" : false,
        "parsedQuery"    : {
            "$and" : [
                {
                    "type" : {
                        "$eq" : "canvas"
                    }
                },
                {
                    "p" : {
                        "$gt" : 0
                    }
                },
                {
                    "id" : {
                        "$in" : [
                            570391,
                            576391,
                            767422
                        ]
                    }
                }
            ]
        },
        "winningPlan"    : {
            "stage"       : "SORT",
            "sortPattern" : {
                "_id" : -1
            },
            "limitAmount" : 5000,
            "inputStage"  : {
                "stage"      : "SORT_KEY_GENERATOR",
                "inputStage" : {
                    "stage"      : "FETCH",
                    "filter"     : {
                        "$and" : [
                            {
                                "type" : {
                                    "$eq" : "canvas"
                                }
                            },
                            {
                                "p" : {
                                    "$gt" : 0
                                }
                            }
                        ]
                    },
                    "inputStage" : {
                        "stage"        : "IXSCAN",
                        "keyPattern"   : {
                            "id" : 1
                        },
                        "indexName"    : "id_1",
                        "isMultiKey"   : false,
                        "isUnique"     : false,
                        "isSparse"     : false,
                        "isPartial"    : false,
                        "indexVersion" : 1,
                        "direction"    : "forward",
                        "indexBounds"  : {
                            "id" : [
                                "[570391.0, 570391.0]",
                                "[576391.0, 576391.0]",
                                "[767422.0, 767422.0]"
                            ]
                        }
                    }
                }
            }
        },
        "rejectedPlans"  : [
            {
                "stage"       : "SORT",
                "sortPattern" : {
                    "_id" : -1
                },
                "limitAmount" : 5000,
                "inputStage"  : {
                    "stage"      : "SORT_KEY_GENERATOR",
                    "inputStage" : {
                        "stage"      : "FETCH",
                        "filter"     : {
                            "id" : {
                                "$in" : [
                                    570391,
                                    576391,
                                    767422
                                ]
                            }
                        },
                        "inputStage" : {
                            "stage"        : "IXSCAN",
                            "keyPattern"   : {
                                "p"    : 1,
                                "type" : 1
                            },
                            "indexName"    : "p_1_type_1",
                            "isMultiKey"   : false,
                            "isUnique"     : false,
                            "isSparse"     : false,
                            "isPartial"    : false,
                            "indexVersion" : 1,
                            "direction"    : "forward",
                            "indexBounds"  : {
                                "p"    : [
                                    "(0.0, inf.0]"
                                ],
                                "type" : [
                                    "[\"canvas\", \"canvas\"]"
                                ]
                            }
                        }
                    }
                }
            },
            {
                "stage"       : "SORT",
                "sortPattern" : {
                    "_id" : -1
                },
                "limitAmount" : 5000,
                "inputStage"  : {
                    "stage"      : "SORT_KEY_GENERATOR",
                    "inputStage" : {
                        "stage"      : "FETCH",
                        "filter"     : {
                            "$and" : [
                                {
                                    "type" : {
                                        "$eq" : "canvas"
                                    }
                                },
                                {
                                    "id" : {
                                        "$in" : [
                                            570391,
                                            576391,
                                            767422
                                        ]
                                    }
                                }
                            ]
                        },
                        "inputStage" : {
                            "stage"        : "IXSCAN",
                            "keyPattern"   : {
                                "p" : 1
                            },
                            "indexName"    : "p_1",
                            "isMultiKey"   : false,
                            "isUnique"     : false,
                            "isSparse"     : false,
                            "isPartial"    : false,
                            "indexVersion" : 1,
                            "direction"    : "forward",
                            "indexBounds"  : {
                                "p" : [
                                    "(0.0, inf.0]"
                                ]
                            }
                        }
                    }
                }
            },
            {
                "stage"       : "SORT",
                "sortPattern" : {
                    "_id" : -1
                },
                "limitAmount" : 5000,
                "inputStage"  : {
                    "stage"      : "SORT_KEY_GENERATOR",
                    "inputStage" : {
                        "stage"      : "FETCH",
                        "filter"     : {
                            "$and" : [
                                {
                                    "p" : {
                                        "$gt" : 0
                                    }
                                },
                                {
                                    "id" : {
                                        "$in" : [
                                            570391,
                                            576391,
                                            767422
                                        ]
                                    }
                                }
                            ]
                        },
                        "inputStage" : {
                            "stage"        : "IXSCAN",
                            "keyPattern"   : {
                                "type" : 1
                            },
                            "indexName"    : "type_1",
                            "isMultiKey"   : false,
                            "isUnique"     : false,
                            "isSparse"     : false,
                            "isPartial"    : false,
                            "indexVersion" : 1,
                            "direction"    : "forward",
                            "indexBounds"  : {
                                "type" : [
                                    "[\"canvas\", \"canvas\"]"
                                ]
                            }
                        }
                    }
                }
            },
            {
                "stage"       : "LIMIT",
                "limitAmount" : 5000,
                "inputStage"  : {
                    "stage"      : "FETCH",
                    "filter"     : {
                        "$and" : [
                            {
                                "type" : {
                                    "$eq" : "canvas"
                                }
                            },
                            {
                                "p" : {
                                    "$gt" : 0
                                }
                            },
                            {
                                "id" : {
                                    "$in" : [
                                        570391,
                                        576391,
                                        767422
                                    ]
                                }
                            }
                        ]
                    },
                    "inputStage" : {
                        "stage"        : "IXSCAN",
                        "keyPattern"   : {
                            "_id" : 1
                        },
                        "indexName"    : "_id_",
                        "isMultiKey"   : false,
                        "isUnique"     : true,
                        "isSparse"     : false,
                        "isPartial"    : false,
                        "indexVersion" : 1,
                        "direction"    : "backward",
                        "indexBounds"  : {
                            "_id" : [
                                "[MaxKey, MinKey]"
                            ]
                        }
                    }
                }
            }
        ]
    },
    "executionStats" : {
        "executionSuccess"    : true,
        "nReturned"           : 2,
        "executionTimeMillis" : 0,
        "totalKeysExamined"   : 5,
        "totalDocsExamined"   : 2,
        "executionStages"     : {
            "stage"                       : "SORT",
            "nReturned"                   : 2,
            "executionTimeMillisEstimate" : 0,
            "works"                       : 10,
            "advanced"                    : 2,
            "needTime"                    : 6,
            "needYield"                   : 0,
            "saveState"                   : 0,
            "restoreState"                : 0,
            "isEOF"                       : 1,
            "invalidates"                 : 0,
            "sortPattern"                 : {
                "_id" : -1
            },
            "memUsage"                    : 906,
            "memLimit"                    : 33554432,
            "limitAmount"                 : 5000,
            "inputStage"                  : {
                "stage"                       : "SORT_KEY_GENERATOR",
                "nReturned"                   : 0,
                "executionTimeMillisEstimate" : 0,
                "works"                       : 6,
                "advanced"                    : 0,
                "needTime"                    : 3,
                "needYield"                   : 0,
                "saveState"                   : 0,
                "restoreState"                : 0,
                "isEOF"                       : 1,
                "invalidates"                 : 0,
                "inputStage"                  : {
                    "stage"                       : "FETCH",
                    "filter"                      : {
                        "$and" : [
                            {
                                "type" : {
                                    "$eq" : "canvas"
                                }
                            },
                            {
                                "p" : {
                                    "$gt" : 0
                                }
                            }
                        ]
                    },
                    "nReturned"                   : 2,
                    "executionTimeMillisEstimate" : 0,
                    "works"                       : 5,
                    "advanced"                    : 2,
                    "needTime"                    : 2,
                    "needYield"                   : 0,
                    "saveState"                   : 0,
                    "restoreState"                : 0,
                    "isEOF"                       : 1,
                    "invalidates"                 : 0,
                    "docsExamined"                : 2,
                    "alreadyHasObj"               : 0,
                    "inputStage"                  : {
                        "stage"                       : "IXSCAN",
                        "nReturned"                   : 2,
                        "executionTimeMillisEstimate" : 0,
                        "works"                       : 5,
                        "advanced"                    : 2,
                        "needTime"                    : 2,
                        "needYield"                   : 0,
                        "saveState"                   : 0,
                        "restoreState"                : 0,
                        "isEOF"                       : 1,
                        "invalidates"                 : 0,
                        "keyPattern"                  : {
                            "id" : 1
                        },
                        "indexName"                   : "id_1",
                        "isMultiKey"                  : false,
                        "isUnique"                    : false,
                        "isSparse"                    : false,
                        "isPartial"                   : false,
                        "indexVersion"                : 1,
                        "direction"                   : "forward",
                        "indexBounds"                 : {
                            "id" : [
                                "[570391.0, 570391.0]",
                                "[576391.0, 576391.0]",
                                "[767422.0, 767422.0]"
                            ]
                        },
                        "keysExamined"                : 5,
                        "dupsTested"                  : 0,
                        "dupsDropped"                 : 0,
                        "seenInvalidated"             : 0
                    }
                }
            }
        }
    },
    "serverInfo"     : {
        "host"       : "host",
        "port"       : 27017,
        "version"    : "3.2.21",
        "gitVersion" : ""
    },
    "ok"             : 1
}

我用谷歌搜索了这种意外行为,但没有找到任何解决方案。所以当它挂起时我不得不重新启动服务器..

为了帮助理解,这是我的情况:

  1. 我正在使用 MongoDB 云管理器,并且数据库实例托管在 AWS EC2 上
  2. 我正在使用 ReplicaSet,我的阅读偏好是 secondaryPreferred。所以所有的读取操作都向辅助节点进行。
  3. MongoDB 版本为 3.2
  4. 我为查询中使用的每个字段(每个字段)创建了索引
  5. 我在主节点和辅助节点中都执行了相同的查询(使用slaveOk
  6. 该集合有 20M 个对象。

对于同一个查询,并非每次都发生这种情况。我认为还有其他因素会对性能产生影响(例如复制?)

但我不知道如何调试这种情况。有没有更好的办法解决这个问题或调试方法?

谢谢,

编辑:我仍然不明白是什么原因,但尝试通过进行任何更改来解决它。我删除了$gt,它似乎有效。但是$gt在我之前的执行中没有问题,我认为是因为此时用户很少。

编辑:我有 MongoDB 云管理器,所以我可以做一些指标更改,我认为查询目标增加了,但我仍然不知道。通常每个文档大约有 100 个,但今天它达到了 2K 以上。可能有关系?

Query targeting for 2month

【问题讨论】:

    标签: mongodb mongodb-query mongodb-replica-set


    【解决方案1】:

    我认为这解释了你所看到的:

    "lockStats"         : {
            "Global"     : {
                "acquireCount"        : {
                    "r" : NumberLong(5524)
                },
                "acquireWaitCount"    : {
                    "r" : NumberLong(349)
                },
                "timeAcquiringMicros" : {
                    "r" : NumberLong(6613952)
                }
            },
    

    似乎停滞的读取需要时间来尝试获取读取意图锁。这在旧版本的 MongoDB(4.0 之前)中是预期的,因为从辅助读取会在 oplog 应用操作正在进行时等待。这样做是为了在应用 oplog 时,辅助读取不会以不一致的形式读取数据。

    这是从最早的 MongoDB 版本开始的长期二次读取行为,我猜您现在看到了这种情况,因为您的数据库已经达到了足够繁忙的程度,以至于成为一个问题。

    这种情况在 MongoDB 4.0 和更新版本中通过 SERVER-34192 得到了改善,允许在 oplog 应用正在进行时进行二次读取。

    【讨论】:

    • 嗨@kevinadi 感谢您的大力帮助。是的,我的数据酶比以前更忙,因为我们插入的内容比以前更多。但金额并没有那么不同。 dropbox.com/s/eqn9u5wj2tu7v6g/…
    • 我也接受了你的回答并阅读了一些关于良好阅读偏好的文档,它说 MongoDB 不建议使用辅助阅读偏好,因为它会导致你上面提到的问题。但它会导致 Primary 的操作缓慢,我仍在调试它。我认为我的查询本身引起了问题,所以我正在修改它。将更新问题!
    猜你喜欢
    • 2015-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多