summaryrefslogtreecommitdiff
path: root/jstests/replsets/recover_prepared_txn_with_multikey_write.js
blob: d9b496f8aa501821b47715ba7aa4c9121967c43a (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
/**
 * Test that replication recovery can reconstruct a prepared transaction that includes a write that
 * sets the multikey flag.
 *
 * @tags: [
 *  uses_transactions,
 *  uses_prepare_transaction,
 *  requires_persistence,
 *  # Multiversion testing does not support tests that kill and restart nodes.
 *  multiversion_incompatible
 * ]
 */
(function() {
"use strict";
load("jstests/core/txns/libs/prepare_helpers.js");

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

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

let primary = rst.getPrimary();

const session = primary.getDB("test").getMongo().startSession();
const sessionDB = session.getDatabase("test");
const sessionColl = sessionDB.getCollection("coll");

// Create an index that will later be made multikey.
sessionColl.createIndex({x: 1});
session.startTransaction();

// Make the index multikey.
jsTestLog("Making the index multikey.");
sessionColl.insert({x: [1, 2, 3]});
// Make sure { w: "majority" } is always used, otherwise the prepare may not get journaled before
// the shutdown below.
PrepareHelpers.prepareTransaction(session);

// Do an unclean shutdown so we don't force a checkpoint, and then restart.
jsTestLog("Killing the primary.");
rst.stop(0, 9, {allowedExitCode: MongoRunner.EXIT_SIGKILL});
rst.restart(0);

jsTestLog("Waiting for the node to get elected again.");
primary = rst.getPrimary();

jsTestLog("Making sure no prepare conflicts are generated on the catalog.");
assert.commandWorked(primary.adminCommand({listDatabases: 1}));

jsTestLog("Aborting the prepared transaction.");
assert.commandWorked(primary.adminCommand({
    abortTransaction: 1,
    lsid: session.getSessionId(),
    txnNumber: session.getTxnNumber_forTesting(),
    autocommit: false
}));

rst.stopSet();
}());