race condition on array $push

0

Hello --

At work we are trying out DocumentDB and I believe I have found a race condition involving arrays and the $push operator.

I've made a simplified example in the form of the following shell script (note that it relies on https://www.gnu.org/software/parallel/):

mongoExec () {
  cmd="mongo <CONNECTION CONFIG REDACTED> --quiet --eval $1"
  $cmd
}

pushElem () {
  mongoExec "db.arrayTest.update({id:'test_id',array:{\$not:{\$elemMatch:{name:'$1'}}}},{\$push:{array:{name:'$1'}}})" > /dev/null
}

export -f pushElem mongoExec

mongoExec "db.createCollection('arrayTest')" > /dev/null
mongoExec "db.arrayTest.insert({id:'test_id',array:[]})" > /dev/null

parallel --jobs 9 pushElem ::: A A A B B B C C C

result=`mongoExec "db.arrayTest.find({id:'test_id'})"`
echo $result

mongoExec "db.arrayTest.drop()" > /dev/null

if [ `echo $result | grep -o name | wc -l | xargs` -ne 3 ]
then
  exit 1
fi

The script creates a collection arrayTest and inserts the following document containing an empty array:

{
  "id": "test_id",
  "array": []
}

It then attempts to conditionally push an element to the array inside that document, using the following query, in parallel 9 times -- 3 times each with A, B, and C in place of $1:

db.arrayTest.update(
  {id:'test_id', array:{$not:{$elemMatch:{name:'$1'}}}},
  {$push:{array:{name:'$1'}}}
)

At the end, it prints out the final state of the document. An example of a successful result (the order of the array entries is irrelevant):

{ "_id" : ObjectId("5c895f5053527cc28b122451"), "id" : "test_id", "array" : [ { "name" : "B" }, { "name" : "C" }, { "name" : "A" } ] }

An example of an unsuccessful result:

{ "_id" : ObjectId("5c89616a4470486421678fa7"), "id" : "test_id", "array" : [ { "name" : "A" }, { "name" : "B" }, { "name" : "B" }, { "name" : "C" } ] }

We've found that, in practice, we're seeing successes about half of the time (in batches of a few hundred runs). Running the same script against the Docker image mongo:latest has not yet ever failed.

Please let me know if you need any more info. Thanks so much for looking into this!

gefragt vor 5 Jahren364 Aufrufe
3 Antworten
0

Thanks for taking the time to report the issue.We are working on a fix. We will post an update to this thread once the fix is rolled out.

AWS
beantwortet vor 5 Jahren
0

Thanks for providing the feedback. We have rolled out the fix to both to our existing and new clusters.

AWS
beantwortet vor 5 Jahren
0

Thanks. I can no longer reproduce the issue.

beantwortet vor 5 Jahren

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen