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

Updating a document shard key value can fail if the document has a $ prefixed field

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Query Optimization
    • ALL
    • Hide

      Run this test in the shell and the final "assert.commandWorked" will fail:

      (function() {
      "use strict";
      
      const st = new ShardingTest({shards: 2, config: 1});
      const dbName = "testDb";
      
      const collName = "testColl";
      const ns = dbName + "." + collName;
      const db = st.getDB(dbName);
      
      // Set up a sharded collection with two shards and a chunk on each.
      assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
      assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {skey: 1}}));
      assert.commandWorked(st.s.adminCommand({split: ns, middle: {skey: 0}}));
      assert.commandWorked(
          st.s.adminCommand({moveChunk: ns, find: {skey: MinKey}, to: st.shard0.shardName}));
      assert.commandWorked(st.s.adminCommand({moveChunk: ns, find: {skey: 1}, to: st.shard1.shardName}));
      
      // Inserting with a dollar prefixed field works.
      assert.commandWorked(db.runCommand({
          insert: collName,
          documents: [{skey: -1, dollarPrefixedField: {"$date": "2012-02-29T00:00:00Z"}}]
      }));
      
      // But an update that uses a transaction to move the document across shards fails with: "unknown
      // operator: $date"
      assert.commandWorked(db.runCommand({
          update: collName,
          updates: [{q: {skey: -1}, u: {"$set": {skey: 1}}, upsert: false}],
          txnNumber: NumberLong(1),
          lsid: {id: UUID()},
      }));
      
      st.stop();
      })(); 
      Show
      Run this test in the shell and the final "assert.commandWorked" will fail: (function() { "use strict" ; const st = new ShardingTest({shards: 2, config: 1}); const dbName = "testDb" ; const collName = "testColl" ; const ns = dbName + "." + collName; const db = st.getDB(dbName); // Set up a sharded collection with two shards and a chunk on each. assert .commandWorked(st.s.adminCommand({enableSharding: dbName})); assert .commandWorked(st.s.adminCommand({shardCollection: ns, key: {skey: 1}})); assert .commandWorked(st.s.adminCommand({split: ns, middle: {skey: 0}})); assert .commandWorked(     st.s.adminCommand({moveChunk: ns, find: {skey: MinKey}, to: st.shard0.shardName})); assert .commandWorked(st.s.adminCommand({moveChunk: ns, find: {skey: 1}, to: st.shard1.shardName})); // Inserting with a dollar prefixed field works. assert .commandWorked(db.runCommand({     insert: collName,     documents: [{skey: -1, dollarPrefixedField: { "$date" : "2012-02-29T00:00:00Z" }}] })); // But an update that uses a transaction to move the document across shards fails with: "unknown // operator : $date" assert .commandWorked(db.runCommand({     update: collName,     updates: [{q: {skey: -1}, u: { "$set" : {skey: 1}}, upsert: false }],     txnNumber: NumberLong(1),     lsid: {id: UUID()}, })); st.stop(); })();
    • Sharding NYC 2023-02-06, Sharding NYC 2023-02-20, Sharding NYC 2023-03-06, Sharding NYC 2023-03-20, Sharding NYC 2023-04-03, Sharding NYC 2023-04-17, Sharding NYC 2023-05-01, Sharding NYC 2023-05-15, Sharding NYC 2023-05-29, Sharding NYC 2023-06-12, Sharding NYC 2023-06-26, Sharding NYC 2023-07-10, Sharding NYC 2023-07-24
    • 3

      If an update to a document's shard key value changes the shard that owns the document, the update transparently spawns a transaction to delete the document and insert it on its new owning shard with the update modifications. This transaction will use the current value of the document as the query for the transactional delete, and this will fail if the document contains a "$" prefixed field that isn't a valid query operator, e.g. $date. Confusingly for users this will not fail if the update does not require spawning a transaction.

            Assignee:
            backlog-query-optimization [DO NOT USE] Backlog - Query Optimization
            Reporter:
            jack.mulrow@mongodb.com Jack Mulrow
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated: