summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/initial_sync_aborts_two_phase_index_builds_hide_index.js
blob: f1e2eae9caf3eeb6b3ceb8ae365d86cb5bd7ef9a (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
/**
 * Verifies that an initial syncing node can abort in-progress two phase index builds during the
 * oplog replay phase.
 *
 * @tags: [requires_replication]
 */
(function() {
"use strict";

load("jstests/noPassthrough/libs/index_build.js");

const dbName = jsTest.name();
const collName = "test";

const rst = new ReplSetTest({
    nodes: [
        {},
        {
            // Disallow elections on secondary.
            rsConfig: {
                priority: 0,
            },
        },
    ]
});

rst.startSet();
rst.initiate();

const primary = rst.getPrimary();

if (!(IndexBuildTest.supportsTwoPhaseIndexBuild(primary) &&
      IndexBuildTest.indexBuildCommitQuorumEnabled(primary))) {
    jsTestLog(
        'Skipping test because two phase index build and index build commit quorum are not supported.');
    rst.stopSet();
    return;
}

const db = primary.getDB(dbName);
const coll = db.getCollection(collName);

assert.commandWorked(coll.insert({a: 1}));
assert.commandWorked(coll.createIndex({a: 1}, {}, "votingMembers"));
rst.awaitReplication();

// Forcefully re-sync the secondary.
let secondary = rst.restart(1, {
    startClean: true,
    setParameter: {
        'failpoint.initialSyncHangDuringCollectionClone': tojson(
            {mode: 'alwaysOn', data: {namespace: "admin.system.version", numDocsToClone: 0}}),
    }
});

// Wait until we block on cloning 'admin.system.version'.
checkLog.containsJson(secondary, 21138);

assert.commandWorked(coll.insert({a: 2}));
assert.commandWorked(coll.hideIndex({a: 1}));
assert.commandWorked(coll.unhideIndex({a: 1}));
assert.commandWorked(coll.dropIndex({a: 1}));

IndexBuildTest.pauseIndexBuilds(secondary);

// Start an index build on the primary, so that when initial sync is cloning the user collection it
// sees an in-progress two phase index build.
TestData.dbName = dbName;
TestData.collName = collName;
const awaitIndexBuild = startParallelShell(() => {
    const coll = db.getSiblingDB(TestData.dbName).getCollection(TestData.collName);
    assert.commandWorked(coll.createIndex({a: 1}, {}, "votingMembers"));
}, primary.port);

IndexBuildTest.waitForIndexBuildToStart(db, collName, "a_1");

assert.commandWorked(secondary.adminCommand(
    {configureFailPoint: "initialSyncHangDuringCollectionClone", mode: "off"}));

rst.awaitReplication();
rst.awaitSecondaryNodes();

// Check the that secondary hit the background operation in progress error.
checkLog.containsJson(
    secondary, 5500800, {reason: "Aborting two phase index builds during initial sync"});

IndexBuildTest.resumeIndexBuilds(secondary);

awaitIndexBuild();

let indexes = secondary.getDB(dbName).getCollection(collName).getIndexes();
assert.eq(2, indexes.length);

indexes = coll.getIndexes();
assert.eq(2, indexes.length);

rst.stopSet();
return;
}());