If a findAndModify command requests a sort, we pass a limit of 1 to that sort so that it will only keep track of the top document, reducing it's memory footprint.
This can lead to lots of retrying when there are many findAndModify operations which all specify a sort and are trying to update the same document, which is a common pattern for some sort of work queue.
What happens is that each findAndModify operation will chug along doing it's sort (I think this is only a problem if it's an in-memory sort, not an index-provided sort), each one periodically yielding, and one will eventually finish first and update the document. Each other operation will eventually find that the matching document has already been modified, so cannot update it themselves. Since there was a limit of 1, the sort stage does not have the next matching document, and the operations have to restart, and re-sort everything.
This is particularly bad on MMAPv1, since the updates have to take an exclusive lock on the collection. The logic to retry operations on MMAPv1 was only introduced in
SERVER-21434. We should revert this change, instead allowing clients to continue to retry (as they likely are already).
As part of this work, it was discovered that there are cases where we do not retry the operation, even on WiredTiger. We should fix those places as well.