[v7.0] Resharding doesn't create a shard key index if a multikey index exists prefixed by the shard key

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: 7.0.25
    • Component/s: None
    • None
    • Cluster Scalability
    • ALL
    • Hide
      /**
       * Tests that an incompatible shard key index can't be the only shard key index on a sharded
       * collection.
       *
       * @tags: [
       *  requires_fcv_70,
       * ]
       */
      
      (function() {
      "use strict";
      
      const shardKeyPattern = {
          skey: 1,
      };
      
      const st = new ShardingTest({shards: 1});
      const coll = st.s.getDB("test").coll;
      
      function getIndexByKey(keyPattern) {
          const indexes = coll.getIndexes().filter((index) => friendlyEqual(index.key, keyPattern));
          assert.lte(
              indexes.length,
              1,
              `Found multiple indexes matching key pattern ${tojsononeline(keyPattern)}. Index list: ${
                  tojson(indexes)}`,
          );
          assert.eq(
              indexes.length,
              1,
              `Index ${tojsononeline(keyPattern)} not found.`,
          );
          return indexes.pop();
      }
      
      const incompatibleShardKeyIndex = {
          key: {skey: 1, multiKeyField: 1},
          options: {},
          isMultiKey: true,
      };
      
      {
          jsTestLog("Verify reshardCollection will attempt to create a shard key index");
      
          // Insert a document that will make the index on 'multiKeyField' multikey.
          coll.insert({skey: 22, multiKeyField: [1, 2, 3]});
      
          // Create the incompatible index.
          assert.commandWorked(
              coll.createIndex(incompatibleShardKeyIndex.key, incompatibleShardKeyIndex.options),
          );
      
          // Shard the collection first with shard key {_id: 1}.
          assert.commandWorked(
              st.s.adminCommand({shardCollection: coll.getFullName(), key: {"_id": 1}}),
          );
      
          // Attempt to reshard the collection to shard key 'shardKeyPattern'.
          const res = st.s.adminCommand({
              reshardCollection: coll.getFullName(),
              key: shardKeyPattern,
              numInitialChunks: 1,
          });
      
          assert.commandWorkedOrFailedWithCode(res, [
              ErrorCodes.InvalidOptions,
              ErrorCodes.IndexKeySpecsConflict,
          ]);
      
          if (res.ok) {
              // The reshardCollection command succeeded, check that the shard key index was
              // created and it's not the incompatible index.
      
              assert(
                  incompatibleShardKeyIndex.canCoexistWithShardKeyIndex,
                  "reshardCollection succeeded when it should have failed",
              );
      
              const shardKeyIndex = getIndexByKey(shardKeyPattern);
              const incompatibleIndex = getIndexByKey(incompatibleShardKeyIndex.key);
      
              assert.neq(shardKeyIndex, null, "shard key index was not created");
              assert.neq(incompatibleIndex, null, "incompatible index is missing");
              assert.neq(
                  incompatibleIndex, shardKeyIndex, "shard key index mustn't be the incompatible index");
          }
      }
      
      st.stop();
      })();
      
      Show
      /** * Tests that an incompatible shard key index can't be the only shard key index on a sharded * collection. * * @tags: [ * requires_fcv_70, * ] */ (function() { "use strict" ; const shardKeyPattern = { skey: 1, }; const st = new ShardingTest({shards: 1}); const coll = st.s.getDB( "test" ).coll; function getIndexByKey(keyPattern) { const indexes = coll.getIndexes().filter((index) => friendlyEqual(index.key, keyPattern)); assert .lte( indexes.length, 1, `Found multiple indexes matching key pattern ${tojsononeline(keyPattern)}. Index list: ${ tojson(indexes)}`, ); assert .eq( indexes.length, 1, `Index ${tojsononeline(keyPattern)} not found.`, ); return indexes.pop(); } const incompatibleShardKeyIndex = { key: {skey: 1, multiKeyField: 1}, options: {}, isMultiKey: true , }; { jsTestLog( "Verify reshardCollection will attempt to create a shard key index" ); // Insert a document that will make the index on 'multiKeyField' multikey. coll.insert({skey: 22, multiKeyField: [1, 2, 3]}); // Create the incompatible index. assert .commandWorked( coll.createIndex(incompatibleShardKeyIndex.key, incompatibleShardKeyIndex.options), ); // Shard the collection first with shard key {_id: 1}. assert .commandWorked( st.s.adminCommand({shardCollection: coll.getFullName(), key: { "_id" : 1}}), ); // Attempt to reshard the collection to shard key 'shardKeyPattern' . const res = st.s.adminCommand({ reshardCollection: coll.getFullName(), key: shardKeyPattern, numInitialChunks: 1, }); assert .commandWorkedOrFailedWithCode(res, [ ErrorCodes.InvalidOptions, ErrorCodes.IndexKeySpecsConflict, ]); if (res.ok) { // The reshardCollection command succeeded, check that the shard key index was // created and it's not the incompatible index. assert ( incompatibleShardKeyIndex.canCoexistWithShardKeyIndex, "reshardCollection succeeded when it should have failed" , ); const shardKeyIndex = getIndexByKey(shardKeyPattern); const incompatibleIndex = getIndexByKey(incompatibleShardKeyIndex.key); assert .neq(shardKeyIndex, null , "shard key index was not created" ); assert .neq(incompatibleIndex, null , "incompatible index is missing" ); assert .neq( incompatibleIndex, shardKeyIndex, "shard key index mustn't be the incompatible index" ); } } st.stop(); })();
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Thanks to backporting the new tests introduced under SERVER-103774  to v7.0, we discovered that resharding does not create a valid shard key index when a multikey index is prefixed by the shard key.

      As a result, after the resharding operation completes, the collection will lack a valid shard key index.

      Note that this bug only affects v7.0

            Assignee:
            Cheahuychou Mao
            Reporter:
            Silvia Surroca
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: