summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/sbe_plan_cache_clear_on_param_change.js
blob: 09b94049c97dc89682a1307b147318a71c7add6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
 * Tests that when certain planning-related server parameters are changed at runtime, the SBE plan
 * cache is cleared.
 * @tags: [
 *   # TODO SERVER-67607: Test plan cache with CQF enabled.
 *   cqf_incompatible,
 * ]
 */
(function() {
"use strict";

load("jstests/libs/analyze_plan.js");
load("jstests/libs/sbe_util.js");

// Lists the names of the setParameters which should result in the SBE plan cache being cleared when
// the parameter is modified. Along with each parameter, includes a valid new value of the parameter
// that the test can use when invoking the 'setParameter' command.
const paramList = [
    {name: "internalQueryPlanEvaluationWorksSbe", value: 10},
    {name: "internalQueryPlanEvaluationCollFractionSbe", value: 0.3},
    {name: "internalQueryPlanEvaluationMaxResults", value: 200},
    {name: "internalQueryForceIntersectionPlans", value: true},
    {name: "internalQueryPlannerEnableIndexIntersection", value: false},
    {name: "internalQueryPlannerEnableHashIntersection", value: true},
    {name: "internalQueryCacheEvictionRatio", value: 11.0},
    {name: "internalQueryCacheWorksGrowthCoefficient", value: 3.0},
    {name: "internalQueryCacheDisableInactiveEntries", value: true},
    {name: "internalQueryPlannerMaxIndexedSolutions", value: 32},
    {name: "internalQueryEnumerationPreferLockstepOrEnumeration", value: true},
    {name: "internalQueryEnumerationMaxOrSolutions", value: 5},
    {name: "internalQueryEnumerationMaxIntersectPerAnd", value: 10},
    {name: "internalQueryPlanOrChildrenIndependently", value: false},
    {name: "internalQueryMaxScansToExplode", value: 100},
    {name: "internalQueryPlannerGenerateCoveredWholeIndexScans", value: true},
    {name: "internalQueryMaxBlockingSortMemoryUsageBytes", value: 1024},
    {name: "internalQuerySlotBasedExecutionMaxStaticIndexScanIntervals", value: 20},
    {name: "internalQueryDefaultDOP", value: 2},
    {name: "internalQueryCollectionMaxNoOfDocumentsToChooseHashJoin", value: 1},
    {name: "internalQueryCollectionMaxDataSizeBytesToChooseHashJoin", value: 100},
    {name: "internalQueryCollectionMaxStorageSizeBytesToChooseHashJoin", value: 100},
    {name: "internalQueryDisableLookupExecutionUsingHashJoin", value: true},
    {name: "internalQuerySlotBasedExecutionDisableLookupPushdown", value: true},
    {name: "internalQuerySlotBasedExecutionDisableGroupPushdown", value: true},
    {name: "allowDiskUseByDefault", value: false},
    {name: "internalQueryMaxNumberOfFieldsToChooseUnfilteredColumnScan", value: 100},
    {name: "internalQueryMaxNumberOfFieldsToChooseFilteredColumnScan", value: 100},
    {name: "internalCostModelCoefficients", value: '{"filterIncrementalCost": 1.0}'},
    {name: "internalQueryColumnScanMinAvgDocSizeBytes", value: 2048},
    {name: "internalQueryColumnScanMinCollectionSizeBytes", value: 2048},
    {name: "internalQueryColumnScanMinNumColumnFilters", value: 5},
];

const conn = MongoRunner.runMongod();
assert.neq(conn, null, "mongod failed to start up");

const dbName = jsTestName();
const db = conn.getDB(dbName);

// This test is specifically verifying the behavior of the SBE plan cache.
if (!checkSBEEnabled(db)) {
    jsTestLog("Skipping test because SBE is not enabled");
    MongoRunner.stopMongod(conn);
    return;
}

assert.commandWorked(db.dropDatabase());

const coll = db.coll;
assert.commandWorked(coll.createIndex({a: 1}));

const filter = {
    a: 1,
    b: 1
};
const cacheKey = getPlanCacheKeyFromShape({query: filter, collection: coll, db: db});

function createCacheEntry() {
    assert.eq(0, coll.find(filter).itcount());
    const cacheContents =
        coll.aggregate([{$planCacheStats: {}}, {$match: {planCacheKey: cacheKey}}]).toArray();
    // We expect to see a single SBE cache entry.
    assert.eq(cacheContents.length, 1, cacheContents);
    const cacheEntry = cacheContents[0];
    // Since there is just a single indexed plan available, we expect the cache entry to be pinned
    // and active after running the query just once.
    assert.eq(cacheEntry.version, "2", cacheContents);
    assert.eq(cacheEntry.isActive, true, cacheContents);
    assert.eq(cacheEntry.isPinned, true, cacheContents);
}

function assertCacheCleared() {
    const cacheContents = coll.aggregate([{$planCacheStats: {}}]).toArray();
    assert.eq(cacheContents.length, 0, cacheContents);
}

for (let param of paramList) {
    createCacheEntry();
    const res = assert.commandWorked(db.adminCommand({setParameter: 1, [param.name]: param.value}));
    assertCacheCleared();

    // Verify that the value actually changed away from the default.
    assert.neq(param.value, res.was);

    // Restore the old value of the parameter.
    assert.commandWorked(db.adminCommand({setParameter: 1, [param.name]: res.was}));
}

MongoRunner.stopMongod(conn);
}());