mirror of https://github.com/mongodb/mongo
SERVER-115450 Update spill_to_disk_server_status.js to handle SBE generic scans (#45299)
GitOrigin-RevId: f247a29daa52cbc969aa5ffce39d18e450cb4454
This commit is contained in:
parent
9c4b72367f
commit
874182abea
|
|
@ -7,7 +7,7 @@
|
||||||
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
|
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
|
||||||
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
|
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
|
||||||
import {funWithArgs} from "jstests/libs/parallel_shell_helpers.js";
|
import {funWithArgs} from "jstests/libs/parallel_shell_helpers.js";
|
||||||
import {getPlanStages, getQueryPlanner, getWinningPlanFromExplain} from "jstests/libs/query/analyze_plan.js";
|
import {getEngine, getWinningPlanFromExplain, isCollscan} from "jstests/libs/query/analyze_plan.js";
|
||||||
import {checkSbeFullyEnabled} from "jstests/libs/query/sbe_util.js";
|
import {checkSbeFullyEnabled} from "jstests/libs/query/sbe_util.js";
|
||||||
import {setParameter} from "jstests/noPassthrough/libs/server_parameter_helpers.js";
|
import {setParameter} from "jstests/noPassthrough/libs/server_parameter_helpers.js";
|
||||||
|
|
||||||
|
|
@ -145,6 +145,21 @@ function getServerStatusSpillingMetrics(serverStatus, stageName, getLegacy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getClassicFailpointName(explain) {
|
||||||
|
const winningPlan = getWinningPlanFromExplain(explain);
|
||||||
|
return isCollscan(db, winningPlan) ? "hangCollScanDoWork" : "hangFetchDoWork";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSbeFailpointName(explain) {
|
||||||
|
const slotBasedPlan = getWinningPlanFromExplain(explain, true /* isSbePlan */);
|
||||||
|
const isScan = slotBasedPlan.stages.includes("scan");
|
||||||
|
if (isScan) {
|
||||||
|
const isGenericScan = slotBasedPlan.stages.includes("scan generic");
|
||||||
|
return isGenericScan ? "hangGenericScanGetNext" : "hangScanGetNext";
|
||||||
|
}
|
||||||
|
return "hangFetchGetNext";
|
||||||
|
}
|
||||||
|
|
||||||
function testSpillingMetrics({
|
function testSpillingMetrics({
|
||||||
stageName,
|
stageName,
|
||||||
expectedSpillingMetrics,
|
expectedSpillingMetrics,
|
||||||
|
|
@ -156,23 +171,14 @@ function testSpillingMetrics({
|
||||||
|
|
||||||
// Check whether the aggregation uses SBE.
|
// Check whether the aggregation uses SBE.
|
||||||
const explain = db[collName].explain().aggregate(pipeline);
|
const explain = db[collName].explain().aggregate(pipeline);
|
||||||
jsTestLog(explain);
|
const isSbePlan = getEngine(explain) === "sbe";
|
||||||
const queryPlanner = getQueryPlanner(explain);
|
|
||||||
const isSbe = queryPlanner.winningPlan.hasOwnProperty("slotBasedPlan");
|
|
||||||
const isCollScan = getPlanStages(getWinningPlanFromExplain(explain), "COLLSCAN").length > 0;
|
|
||||||
|
|
||||||
// Collect the serverStatus metrics before the aggregation runs.
|
// Collect the serverStatus metrics before the aggregation runs.
|
||||||
jsTestLog(stageName);
|
|
||||||
const spillingMetrics = [];
|
const spillingMetrics = [];
|
||||||
spillingMetrics.push(getServerStatusSpillingMetrics(db.serverStatus(), stageName, getLegacy));
|
spillingMetrics.push(getServerStatusSpillingMetrics(db.serverStatus(), stageName, getLegacy));
|
||||||
|
|
||||||
// Run an aggregation and hang at the fail point in the middle of the processing.
|
// Run an aggregation and hang at the fail point in the middle of the processing.
|
||||||
let failPointName;
|
const failPointName = isSbePlan ? getSbeFailpointName(explain) : getClassicFailpointName(explain);
|
||||||
if (isSbe) {
|
|
||||||
failPointName = isCollScan ? "hangScanGetNext" : "hangFetchGetNext";
|
|
||||||
} else {
|
|
||||||
failPointName = isCollScan ? "hangCollScanDoWork" : "hangFetchDoWork";
|
|
||||||
}
|
|
||||||
const failPoint = configureFailPoint(db, failPointName, {} /* data */, {"skip": nDocs / 2});
|
const failPoint = configureFailPoint(db, failPointName, {} /* data */, {"skip": nDocs / 2});
|
||||||
const awaitShell = startParallelShell(
|
const awaitShell = startParallelShell(
|
||||||
funWithArgs(
|
funWithArgs(
|
||||||
|
|
@ -204,7 +210,13 @@ function testSpillingMetrics({
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert the final spilling metrics are as expected.
|
// Assert the final spilling metrics are as expected.
|
||||||
assert.docEq(isSbe ? expectedSbeSpillingMetrics : expectedSpillingMetrics, spillingMetrics[2], spillingMetrics);
|
const expected = isSbePlan ? expectedSbeSpillingMetrics : expectedSpillingMetrics;
|
||||||
|
const actual = spillingMetrics[2];
|
||||||
|
assert.docEq(
|
||||||
|
expected,
|
||||||
|
actual,
|
||||||
|
`Expected ${expected} but found ${actual}. spillingMetrics=${tojson(spillingMetrics)}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
testSpillingMetrics({
|
testSpillingMetrics({
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@
|
||||||
#include "mongo/platform/compiler.h"
|
#include "mongo/platform/compiler.h"
|
||||||
#include "mongo/util/assert_util.h"
|
#include "mongo/util/assert_util.h"
|
||||||
#include "mongo/util/concurrency/admission_context.h"
|
#include "mongo/util/concurrency/admission_context.h"
|
||||||
|
#include "mongo/util/fail_point.h"
|
||||||
#include "mongo/util/overloaded_visitor.h" // IWYU pragma: keep
|
#include "mongo/util/overloaded_visitor.h" // IWYU pragma: keep
|
||||||
#include "mongo/util/str.h"
|
#include "mongo/util/str.h"
|
||||||
|
|
||||||
|
|
@ -58,6 +59,11 @@
|
||||||
#include <boost/optional/optional.hpp>
|
#include <boost/optional/optional.hpp>
|
||||||
|
|
||||||
namespace mongo {
|
namespace mongo {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
MONGO_FAIL_POINT_DEFINE(hangGenericScanGetNext);
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace sbe {
|
namespace sbe {
|
||||||
GenericScanStage::GenericScanStage(UUID collUuid,
|
GenericScanStage::GenericScanStage(UUID collUuid,
|
||||||
DatabaseName dbName,
|
DatabaseName dbName,
|
||||||
|
|
@ -108,6 +114,9 @@ std::unique_ptr<PlanStage> GenericScanStage::clone() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
PlanState GenericScanStage::getNext() {
|
PlanState GenericScanStage::getNext() {
|
||||||
|
if (MONGO_unlikely(hangGenericScanGetNext.shouldFail())) {
|
||||||
|
hangGenericScanGetNext.pauseWhileSet();
|
||||||
|
}
|
||||||
auto optTimer(getOptTimer(_opCtx));
|
auto optTimer(getOptTimer(_opCtx));
|
||||||
|
|
||||||
handleInterruptAndSlotAccess();
|
handleInterruptAndSlotAccess();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue