Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-22739

Sharding SecondaryPreferred read commands routed to a primary do not handle StaleConfigException

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 3.0.9, 3.2.13, 3.4.4
    • Component/s: Sharding
    • None
    • ALL
    • Hide

      Run the following JS script:

      // Tests that SecondaryPreferred queries routed to the primary of a shard will handle stale metadata
      (function() {
      'use strict';
      
      // Start a sharding cluster with a single shard, which has one node
      var st = new ShardingTest({ mongos: 2, shards: 2, other: { rs: { nodes: 1 } } });
      
      // Shard a collection by the first mongos
      assert.commandWorked(st.s0.adminCommand({ enableSharding: 'TestDB' }));
      st.ensurePrimaryShard('TestDB', st.shard0.shardName);
      assert.commandWorked(st.s0.adminCommand({ shardCollection: 'TestDB.TestColl', key: { Key: 1 } }));
      
      // Insert some documents
      assert.writeOK(st.s0.getDB('TestDB').TestColl.insert({ Key: 0, Value: 'Value 0' }));
      assert.writeOK(st.s0.getDB('TestDB').TestColl.insert({ Key: 1, Value: 'Value 1' }));
      
      // Make sure the second mongos has the most up-to-date metadata
      assert.eq(2, st.s0.getDB('TestDB').TestColl.find().itcount());
      assert.eq(2, st.s1.getDB('TestDB').TestColl.find().itcount());
      
      // Make sure the second mongos has cached a versioned collection with the stale version
      var slaveOkConnection = new Mongo(st.s1.host);
      slaveOkConnection.setSlaveOk();
      assert.eq(2, slaveOkConnection.getDB('TestDB').TestColl.distinct('Value').length);
      
      // Split the chunk on the first mongos
      assert.commandWorked(st.s0.adminCommand({ split: 'TestDB.TestColl', find: { Key: 0 } }));
      assert.commandWorked(st.s0.adminCommand({ moveChunk: 'TestDB.TestColl',
                                                find: { Key: 1 },
                                                to: st.shard1.shardName }));
      
      // Now do the distinct again and use the same connection as the one on which we ran distinct
      // earlier, because sharded/versioned connections are cached per thread.
      assert.eq(2, slaveOkConnection.getDB('TestDB').TestColl.distinct('Value').length);
      
      st.stop();
      
      })();
      
      Show
      Run the following JS script: // Tests that SecondaryPreferred queries routed to the primary of a shard will handle stale metadata (function() { 'use strict' ; // Start a sharding cluster with a single shard, which has one node var st = new ShardingTest({ mongos: 2, shards: 2, other: { rs: { nodes: 1 } } }); // Shard a collection by the first mongos assert .commandWorked(st.s0.adminCommand({ enableSharding: 'TestDB' })); st.ensurePrimaryShard( 'TestDB' , st.shard0.shardName); assert .commandWorked(st.s0.adminCommand({ shardCollection: 'TestDB.TestColl' , key: { Key: 1 } })); // Insert some documents assert .writeOK(st.s0.getDB( 'TestDB' ).TestColl.insert({ Key: 0, Value: 'Value 0' })); assert .writeOK(st.s0.getDB( 'TestDB' ).TestColl.insert({ Key: 1, Value: 'Value 1' })); // Make sure the second mongos has the most up-to-date metadata assert .eq(2, st.s0.getDB( 'TestDB' ).TestColl.find().itcount()); assert .eq(2, st.s1.getDB( 'TestDB' ).TestColl.find().itcount()); // Make sure the second mongos has cached a versioned collection with the stale version var slaveOkConnection = new Mongo(st.s1.host); slaveOkConnection.setSlaveOk(); assert .eq(2, slaveOkConnection.getDB( 'TestDB' ).TestColl.distinct( 'Value' ).length); // Split the chunk on the first mongos assert .commandWorked(st.s0.adminCommand({ split: 'TestDB.TestColl' , find: { Key: 0 } })); assert .commandWorked(st.s0.adminCommand({ moveChunk: 'TestDB.TestColl' , find: { Key: 1 }, to: st.shard1.shardName })); // Now do the distinct again and use the same connection as the one on which we ran distinct // earlier, because sharded/versioned connections are cached per thread. assert .eq(2, slaveOkConnection.getDB( 'TestDB' ).TestColl.distinct( 'Value' ).length); st.stop(); })();
    • Sharding 11 (03/11/16), Sharding 2017-08-21
    • 0

      SecondaryPreferred reads are allowed to be routed to a primary host if this is deemed the most appropriate.

      Legacy style queries disable the version checking and so they go over unversioned connections. However other command implementations, such as distinct or count which use ShardCollection will fail with a cryptic NodeNotFound error if they get routed to a primary with the SecondaryPreferred preference set, because they do not expect to see StaleConfigException.

      See the included repro script for more information.

            Assignee:
            esha.maharishi@mongodb.com Esha Maharishi (Inactive)
            Reporter:
            kaloian.manassiev@mongodb.com Kaloian Manassiev
            Votes:
            0 Vote for this issue
            Watchers:
            10 Start watching this issue

              Created:
              Updated:
              Resolved: