Description:
The ticket changes the routing behaviour for updates on sharded clusters.
1. Replacement-style updates will now attempt to target by the query first.
2. If we cannot target a single shard, and if the op is NOT an upsert, we fall back to targeting by the replacement document in order to maintain backwards-compatible behaviour.
3. If the op is an upsert, then we do NOT fall back to targeting by replacement; an upsert must always target a single shard by query and must have full shard key in query. If we cannot do so, we throw an operation-fatal exception.
4. This change also enforces the requirement of needing a full shard key in the query to update a shard key value.
Engineering Ticket Description:
Currently, replacement style updates target using the update rather than the query. We should change this to target using the query instead.
As of today, we do not allow users to change the shard key for a document. If shard 1 owns the chunk with range (shardKey : min, shardKey : 500) and shard 2 owns the chunk with range (shardKey : 500, shardKey : max) and a user sends
db.coll.update({shardKey : 100}, {shardKey : 800})
|
the update will be sent to shard 2 and we return
We should actually get an ImmutableField error.
Once we allow a user to update the shard key for a document (PM-1163), the above update should cause the document to change shards. However, since the update would be sent to shard 2, shard 1 will never actually see this update and the update will not be applied.