summaryrefslogtreecommitdiff
path: root/jstests/sharding/resharding_write_when_temp_ns_routing_info_unknown.js
blob: eaae0da6accf417963d23d0660161f147cf9ed12 (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
110
111
112
113
114
/**
 * Tests that write operations on the collection being resharded succeed even when the routing
 * information for the associated temporary resharding collection isn't currently known.
 *
 * @tags: [
 *   uses_atclustertime,
 *   uses_transactions,
 * ]
 */
(function() {
"use strict";

load("jstests/libs/auto_retry_transaction_in_sharding.js");
load("jstests/libs/discover_topology.js");
load("jstests/sharding/libs/resharding_test_fixture.js");

const reshardingTest = new ReshardingTest();
reshardingTest.setup();

const testCases = [
    {
        desc: "Test ordinary insert when donor does not have temporary resharding collection " +
            "routing info cached",
        ns: "reshardingDb.coll_no_txn",
        opFn: (sourceCollection) => {
            const docToInsert = {_id: 0, oldKey: 5, newKey: 15};
            assert.commandWorked(sourceCollection.insert(docToInsert));
            assert.eq(sourceCollection.findOne({_id: 0}), docToInsert);
        },
    },
    {
        desc: ("Test insert in a multi-statement transaction when donor does not have temporary " +
               "resharding collection routing info cached"),
        ns: "reshardingDb.coll_in_txn_first_stmt",
        opFn: (sourceCollection) => {
            const mongos = sourceCollection.getMongo();
            const session = mongos.startSession();
            const sessionCollection = session.getDatabase(sourceCollection.getDB().getName())
                                          .getCollection(sourceCollection.getName());

            const docToInsert = {_id: 0, oldKey: 5, newKey: 15};
            session.startTransaction();
            assert.commandWorked(sessionCollection.insert(docToInsert));
            assert.commandWorked(session.commitTransaction_forTesting());
            assert.eq(sourceCollection.findOne({_id: 0}), docToInsert);
        },
    },
    {
        desc: ("Test insert in second statement of a multi-statement transaction when donor does " +
               "not have temporary resharding collection routing info cached"),
        ns: "reshardingDb.coll_in_txn_second_stmt",
        opFn: (sourceCollection) => {
            const mongos = sourceCollection.getMongo();
            const session = mongos.startSession();
            const sessionCollection = session.getDatabase(sourceCollection.getDB().getName())
                                          .getCollection(sourceCollection.getName());

            const sessionCollectionB =
                session.getDatabase(sourceCollection.getDB().getName()).getCollection('foo');
            assert.commandWorked(sessionCollectionB.insert({a: 1}));

            const docToInsert = {_id: 0, oldKey: 5, newKey: 15};
            session.startTransaction();
            withTxnAndAutoRetryOnMongos(session, () => {
                assert.commandWorked(sessionCollectionB.insert({a: 2}));
                assert.commandWorked(sessionCollection.insert(docToInsert));
            });
            assert.commandWorked(session.commitTransaction_forTesting());
            assert.eq(sourceCollection.findOne({_id: 0}), docToInsert);
        },
    }
];

for (const {desc, ns, opFn} of testCases) {
    jsTest.log(desc);

    const donorShardNames = reshardingTest.donorShardNames;
    const sourceCollection = reshardingTest.createShardedCollection({
        ns,
        shardKeyPattern: {oldKey: 1},
        chunks: [{min: {oldKey: MinKey}, max: {oldKey: MaxKey}, shard: donorShardNames[0]}],
    });

    const mongos = sourceCollection.getMongo();
    const topology = DiscoverTopology.findConnectedNodes(mongos);
    const donor0 = new Mongo(topology.shards[donorShardNames[0]].primary);

    const recipientShardNames = reshardingTest.recipientShardNames;
    reshardingTest.withReshardingInBackground(  //
        {
            newShardKeyPattern: {newKey: 1},
            newChunks:
                [{min: {newKey: MinKey}, max: {newKey: MaxKey}, shard: recipientShardNames[0]}],
        },
        (tempNs) => {
            // Wait for the recipients to have finished cloning so the temporary resharding
            // collection is known to exist.
            assert.soon(() => {
                const coordinatorDoc = mongos.getCollection("config.reshardingOperations").findOne({
                    ns: sourceCollection.getFullName()
                });

                return coordinatorDoc !== null && coordinatorDoc.state === "applying";
            });

            // Make the routing info for the temporary sharding collection unknown
            donor0.adminCommand({flushRouterConfig: tempNs});

            opFn(sourceCollection);
        });
}

reshardingTest.teardown();
})();