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

Using $set with upsert against sharded cluster behaves differently to non-sharded cluster

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 2.5.5
    • Affects Version/s: 2.2.1
    • Component/s: Sharding, Write Ops
    • None
    • Environment:
      RHEL 5
    • Fully Compatible
    • ALL
    • Hide

      On a shared collection, sharded on 'symbol' you get:

      document = {'symbol': 'random_symbol', 'value': 'val'}
      col.update({'symbol': document['symbol']}, {'$set': document}, w=1, upsert=True)
      Traceback (most recent call last):
        File "/users/is/jblackburn/pyenvs/research/lib/python2.6/site-packages/ipython-0.11_5-py2.6.egg/IPython/core/interactiveshell.py", line 2400, in run_code
          exec code_obj in self.user_global_ns, self.user_ns
        File "<ipython-input-50-74f5bdbf4070>", line 1, in <module>
          col.update({'symbol': document['symbol']}, {'$set': document}, w=1, upsert=True)
        File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/collection.py", line 481, in update
          check_keys, self.__uuid_subtype), safe)
        File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/mongo_client.py", line 852, in _send_message
          rv = self.__check_response_to_last_error(response)
        File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/mongo_client.py", line 795, in __check_response_to_last_error
          raise OperationFailure(details["err"], details["code"])
      OperationFailure: Can't modify shard key's value. field: symbol: "random_symbol" collection: mongoose_jblackburn.centaur
      

      On an unsharded collection, you get:

      col.update({'symbol': document['symbol']}, {'$set': document}, w=1, upsert=True)
      Out[54]: 
      {u'connectionId': 63367,
       u'err': None,
       u'lastOp': Timestamp(1359483484, 1),
       u'n': 1,
       u'ok': 1.0,
       u'singleShard': u'rs0/cn14-ib:27118,cn17-ib:27118,cn53-ib:27118',
       u'updatedExisting': False,
       u'upserted': ObjectId('5108125c5fa01f07fcb07c5f')}
      
      Show
      On a shared collection, sharded on 'symbol' you get: document = { 'symbol' : 'random_symbol' , 'value' : 'val' } col.update({ 'symbol' : document[ 'symbol' ]}, { '$set' : document}, w=1, upsert=True) Traceback (most recent call last): File "/users/is/jblackburn/pyenvs/research/lib/python2.6/site-packages/ipython-0.11_5-py2.6.egg/IPython/core/interactiveshell.py" , line 2400, in run_code exec code_obj in self.user_global_ns, self.user_ns File "<ipython-input-50-74f5bdbf4070>" , line 1, in <module> col.update({ 'symbol' : document[ 'symbol' ]}, { '$set' : document}, w=1, upsert=True) File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/collection.py" , line 481, in update check_keys, self.__uuid_subtype), safe) File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/mongo_client.py" , line 852, in _send_message rv = self.__check_response_to_last_error(response) File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/mongo_client.py" , line 795, in __check_response_to_last_error raise OperationFailure(details[ "err" ], details[ "code" ]) OperationFailure: Can 't modify shard key' s value. field: symbol: "random_symbol" collection: mongoose_jblackburn.centaur On an unsharded collection, you get: col.update({ 'symbol' : document[ 'symbol' ]}, { '$set' : document}, w=1, upsert=True) Out[54]: {u 'connectionId' : 63367, u 'err' : None, u 'lastOp' : Timestamp(1359483484, 1), u 'n' : 1, u 'ok' : 1.0, u 'singleShard' : u 'rs0/cn14-ib:27118,cn17-ib:27118,cn53-ib:27118' , u 'updatedExisting' : False, u 'upserted' : ObjectId( '5108125c5fa01f07fcb07c5f' )}

      If you do an update with upsert on a sharded cluster, and the update document contains only update operators, but the '$set' update also includes the shard key, you get an error even if the key-value hasn't changed:

          exec code_obj in self.user_global_ns, self.user_ns
        File "<ipython-input-50-74f5bdbf4070>", line 1, in <module>
          col.update({'symbol': document['symbol']}, {'$set': document}, w=1, upsert=True)
        File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/collection.py", line 481, in update
          check_keys, self.__uuid_subtype), safe)
        File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/mongo_client.py", line 852, in _send_message
          rv = self.__check_response_to_last_error(response)
        File "/local/home/jblackburn/net/pymongo-2.4.1/pymongo/mongo_client.py", line 795, in __check_response_to_last_error
          raise OperationFailure(details["err"], details["code"])
      OperationFailure: Can't modify shard key's value. field: symbol: "random_symbol" collection: mongoose_jblackburn.centaur
      

      The bad thing is that the code works fine on an unsharded collection, and only breaks when the collection is sharded - making it difficult to test.

            Assignee:
            scotthernandez Scott Hernandez (Inactive)
            Reporter:
            jblackburn James Blackburn
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: