summaryrefslogtreecommitdiff
path: root/jstests/sharding/stale_mongos_and_restarted_shards_agree_on_shard_version.js
blob: 953ac20713ffaa2eea9454e9dcd25830036b790a (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * Tests that after a restart of a shard, multi write operations, finds and aggregations still work
 * as expected with a stale router
 *
 * This test requrires persistence because it asumes the shard will still have it's data after
 * restarting
 *
 * @tags: [
 *   requires_fcv_46,
 *   requires_persistence,
 * ]
 */
(function() {
'use strict';

const st = new ShardingTest({shards: 2, mongos: 2});

// Used to get the shard destination ids for the moveChunks commands
const shard0Name = st.shard0.shardName;
const shard1Name = st.shard1.shardName;

const kDatabaseName = 'TestDB';
st.enableSharding(kDatabaseName, st.shard1.shardName);

// Creates and shard collName with 2 chunks, one per shard. Only the router referenced by st.s0
// knows that collName is sharded, and all the shards are restarted so they don't have the
// collection's sharding status
function setupCollectionForTest(collName) {
    const ns = kDatabaseName + '.' + collName;
    assert.commandFailedWithCode(st.s0.adminCommand({getShardVersion: ns}),
                                 ErrorCodes.NamespaceNotSharded);
    assert.commandFailedWithCode(st.s1.adminCommand({getShardVersion: ns}),
                                 ErrorCodes.NamespaceNotSharded);
    st.shardCollection(ns, {Key: 1});

    st.s0.adminCommand({split: ns, middle: {Key: 0}});
    st.s0.adminCommand({moveChunk: ns, find: {Key: -1}, to: shard0Name});
    st.s0.adminCommand({moveChunk: ns, find: {Key: 0}, to: shard1Name});
    assert.commandFailedWithCode(st.s1.adminCommand({getShardVersion: ns}),
                                 ErrorCodes.NamespaceNotSharded);

    // This document will go to shard 0
    assert.commandWorked(
        st.s0.getDB(kDatabaseName).getCollection(collName).insert({Key: -1, inc: 0}));
    // This document will go to shard 1
    assert.commandWorked(
        st.s0.getDB(kDatabaseName).getCollection(collName).insert({Key: 0, inc: 0}));

    st.restartShardRS(0);
    st.restartShardRS(1);
}

const freshMongoS = st.s0;
const staleMongoS = st.s1;

{
    jsTest.log('Testing: Insert with sharded collection unknown on a stale mongos');
    setupCollectionForTest('TestInsertColl');

    var insertBulkOp = staleMongoS.getDB(kDatabaseName).TestInsertColl.initializeUnorderedBulkOp();
    insertBulkOp.insert({Key: -2});
    insertBulkOp.insert({Key: 1});
    insertBulkOp.execute();

    assert.eq(4, freshMongoS.getDB(kDatabaseName).TestInsertColl.find().itcount());
    assert.eq(4, staleMongoS.getDB(kDatabaseName).TestInsertColl.find().itcount());
}
{
    jsTest.log('Testing: Multi-update with sharded collection unknown on a stale mongos');
    setupCollectionForTest('TestUpdateColl');

    assert.commandWorked(staleMongoS.getDB(kDatabaseName)
                             .TestUpdateColl.update({}, {$inc: {inc: 1}}, {multi: true}));

    var s0Doc = freshMongoS.getDB(kDatabaseName).TestUpdateColl.findOne({Key: -1});
    assert.eq(1, s0Doc.inc);
    var s1Doc = freshMongoS.getDB(kDatabaseName).TestUpdateColl.findOne({Key: 0});
    assert.eq(1, s1Doc.inc);
}
{
    jsTest.log('Testing: Multi-remove with sharded collection unknown on a stale mongos');
    setupCollectionForTest('TestRemoveColl');

    assert.commandWorked(
        staleMongoS.getDB(kDatabaseName).TestRemoveColl.remove({}, {justOne: false}));

    assert.eq(0, freshMongoS.getDB(kDatabaseName).TestRemoveColl.find().itcount());
}
{
    jsTest.log('Testing: Find-and-modify with sharded collection unknown on a stale mongos');
    setupCollectionForTest('TestFindAndModifyColl');

    assert.eq(null, staleMongoS.getDB(kDatabaseName).TestFindAndModifyColl.findAndModify({
        query: {Key: -2},
        update: {Key: -2},
        upsert: true
    }));

    assert.eq({Key: -2},
              freshMongoS.getDB(kDatabaseName).TestFindAndModifyColl.findOne({Key: -2}, {_id: 0}));
}
{
    jsTest.log('Testing: Find with sharded collection unknown on a stale mongos');
    setupCollectionForTest('TestFindColl');

    var coll = staleMongoS.getDB(kDatabaseName).TestFindColl.find().toArray();
    assert.eq(2, coll.length);
}
{
    jsTest.log('Testing: Aggregate with sharded collection unknown on a stale mongos');
    setupCollectionForTest('TestAggregateColl');

    var count =
        staleMongoS.getDB(kDatabaseName).TestAggregateColl.aggregate([{$count: 'total'}]).toArray();
    assert.eq(2, count[0].total);
}
{
    jsTest.log('Testing: Transactions with unsharded collection, which is unknown on the shard');
    st.restartShardRS(0);
    st.restartShardRS(1);

    var session = staleMongoS.startSession();
    session.startTransaction();
    session.getDatabase(kDatabaseName).TestTransactionColl.insert({Key: 1});
    session.commitTransaction();
}

st.stop();
})();