summaryrefslogtreecommitdiff
path: root/jstests/sharding/database_versioning_cache_entry_without_version_updated_with_version.js
blob: f6dc4560462232aaddac4e544ff0f9d58f50247f (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
// This ensures that if a shard had cached a database entry without a version in a 4.0 cluster while
// in FCV 3.6, then upgrading the cluster to 4.2 binaries will cause the next request that has a
// database version attached to cause the shard to refresh and pick up the version and write it to
// its on-disk cache so that the version can also be picked up by secondaries.
(function() {

    const st = new ShardingTest({shards: 1, rs: {nodes: 2}, other: {verbose: 2}});

    assert.commandWorked(st.s.getDB("test").getCollection("foo").insert({x: 1}));

    // The database is created with a version.
    const versionOnConfig =
        st.s.getDB("config").getCollection("databases").findOne({_id: "test"}).version;
    assert.neq(null, versionOnConfig);

    // Before the shard refreshes, it does not have a cache entry for the database.
    assert.eq(null,
              st.shard0.getDB("config").getCollection("cache.databases").findOne({_id: "test"}));

    // After the shard refreshes, it has a cache entry for the database with version matching the
    // version on the config server.
    assert.commandWorked(st.shard0.adminCommand({_flushDatabaseCacheUpdates: "test"}));
    const versionOnShard =
        st.shard0.getDB("config").getCollection("cache.databases").findOne({_id: "test"}).version;
    assert.docEq(versionOnConfig, versionOnShard);

    // The shard primary's in-memory version matches the on-disk version.
    assert.eq(versionOnShard, st.shard0.adminCommand({getDatabaseVersion: "test"}).dbVersion);

    jsTest.log("Remove the database version from the shard's cache entry");
    assert.commandWorked(
        st.shard0.getDB("config").getCollection("cache.databases").update({_id: "test"}, {
            $unset: {version: ""}
        }));
    assert.eq(
        null,
        st.shard0.getDB("config").getCollection("cache.databases").findOne({_id: "test"}).version);

    // Deleting the version field from the on-disk entry did not affect the in-memory version.
    assert.eq(versionOnShard, st.shard0.adminCommand({getDatabaseVersion: "test"}).dbVersion);

    // The shard secondary does not have a version cached in memory.
    assert.eq({}, st.rs0.getSecondary().adminCommand({getDatabaseVersion: "test"}).dbVersion);

    // A versioned request against the shard secondary makes the shard primary refresh and update
    // the on-disk cache entry with a version, even though it already had an on-disk cache entry and
    // had the up-to-date version cached in memory.
    // Use readConcern 'local' because the default on secondaries is 'available'.
    assert.commandWorked(st.s.getDB("test").runCommand(
        {listCollections: 1, $readPreference: {mode: "secondary"}, readConcern: {level: "local"}}));
    const versionOnShard2 =
        st.shard0.getDB("config").getCollection("cache.databases").findOne({_id: "test"}).version;
    assert.docEq(versionOnConfig, versionOnShard2);

    // The shard secondary's in-memory version now matches the on-disk version.
    assert.eq(versionOnShard,
              st.rs0.getSecondary().adminCommand({getDatabaseVersion: "test"}).dbVersion);

    st.stop();

})();