summaryrefslogtreecommitdiff
path: root/jstests/sharding/analyze_shard_key/persist_sampled_queries_failover.js
blob: 79f1aceb949c688525cf9847e1255e6fd88312eb (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
/**
 * Tests that the periodic job for persisting sampled queries on shardsvr mongods can handle
 * failover.
 *
 * @tags: [requires_fcv_62, featureFlagAnalyzeShardKey]
 */
(function() {
"use strict";

load("jstests/libs/fail_point_util.js");
load("jstests/sharding/analyze_shard_key/libs/query_sampling_util.js");

function testStepDown(rst) {
    const dbName = "testDb";
    const collName = "testCollStepDown";
    const ns = dbName + "." + collName;

    let primary = rst.getPrimary();
    let primaryDB = primary.getDB(dbName);

    assert.commandWorked(primaryDB.getCollection(collName).insert({a: 0}));
    const collectionUuid = QuerySamplingUtil.getCollectionUuid(primaryDB, collName);

    const localWriteFp =
        configureFailPoint(primary, "hangQueryAnalysisWriterBeforeWritingLocally", {}, {times: 1});

    const originalCmdObj =
        {findAndModify: collName, query: {a: 0}, update: {a: 1}, sampleId: UUID()};
    const expectedSampledQueryDocs =
        [{sampleId: originalCmdObj.sampleId, cmdName: "findAndModify", cmdObj: originalCmdObj}];
    const expectedDiff = {a: "u"};

    assert.commandWorked(primaryDB.getCollection(collName).runCommand(originalCmdObj));

    localWriteFp.wait();

    assert.commandWorked(
        primary.adminCommand({replSetStepDown: ReplSetTest.kForeverSecs, force: true}));
    primary = rst.getPrimary();
    primaryDB = primary.getDB(dbName);

    localWriteFp.off();

    // Verify that the sampled query above did not go missing because of the retryable error caused
    // by stepdown.
    QuerySamplingUtil.assertSoonSampledQueryDocuments(
        primary, ns, collectionUuid, expectedSampledQueryDocs);
    QuerySamplingUtil.assertSoonSingleSampledDiffDocument(
        primary, originalCmdObj.sampleId, ns, collectionUuid, [expectedDiff]);
}

function testStepUp(rst) {
    const dbName = "testDb";
    const collName = "testCollStepUp";
    const ns = dbName + "." + collName;

    let primary = rst.getPrimary();
    const secondary = rst.getSecondary();
    const primaryDB = primary.getDB(dbName);
    const secondaryTestDB = secondary.getDB(dbName);

    assert.commandWorked(primaryDB.createCollection(collName));
    const collectionUuid = QuerySamplingUtil.getCollectionUuid(primaryDB, collName);
    // Wait for the collection to also exist on secondaries.
    rst.awaitReplication();

    const originalCmdObj = {count: collName, query: {a: 2}, sampleId: UUID()};
    const expectedSampledQueryDocs = [{
        sampleId: originalCmdObj.sampleId,
        cmdName: "count",
        cmdObj: {filter: originalCmdObj.query}
    }];

    const remoteWriteFp =
        configureFailPoint(secondary, "hangQueryAnalysisWriterBeforeWritingRemotely");
    assert.commandWorked(secondaryTestDB.getCollection(collName).runCommand(originalCmdObj));

    remoteWriteFp.wait();
    assert.commandWorked(secondary.adminCommand({replSetFreeze: 0}));
    assert.commandWorked(
        primary.adminCommand({replSetStepDown: ReplSetTest.kForeverSecs, force: true}));
    primary = rst.getPrimary();

    remoteWriteFp.off();

    // Verify that the sampled query above did not go missing because the node stepped up.
    QuerySamplingUtil.assertSoonSampledQueryDocuments(
        primary, ns, collectionUuid, expectedSampledQueryDocs);
}

const st = new ShardingTest({
    shards: 1,
    rs: {
        nodes: 2,
        // Make the periodic job for writing sampled queries have a period of 1 second to speed up
        // the test.
        setParameter: {queryAnalysisWriterIntervalSecs: 1}
    }
});

testStepDown(st.rs0);
testStepUp(st.rs0);

st.stop();
})();