[SERVER-7547] _id is null when upserting into local system.users collection Created: 04/Nov/12  Updated: 06/Dec/22  Resolved: 18/Jul/16

Status: Closed
Project: Core Server
Component/s: Storage, Write Ops
Affects Version/s: 2.2.0, 2.2.1
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Abdul Alkhatib Assignee: Backlog - Storage Execution Team
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Assigned Teams:
Storage Execution
Operating System: OS X
Participants:

 Description   

An upsert into the "local.system.users" collection creates documents with no _id. Since there is an index on _id, this will create an index key of

{ "_id" : null}

for the first upserted user document. So upserting another user document will fail with the following error.

E11000 duplicate key error index: local.system.users.$id dup key: { : null }

This happens only if local system.users is empty or there are no documents with _id set. If there is at least one document with _id set then it will work fine.

Since pymongo adds users using upserts, this will make pymongo fail when adding more than one local user

To replicate:
1- start a fresh 2.2.0 mongod server(nuke dbpath)

  1. mongod --dbpath /data/db --port 27017

2- mongo into server and use local db

  1. mongo

3- upsert a user document into system.users

  1. db.system.users.update( {"user":"abdul"}

    ,

    {"user":"abdul", "pwd":"xxxxxxxxx"}

    , true);

4- Note that inserted document does not have an _id

  1. db.system.users.find()

5- Insert another document

RESULT:

E11000 duplicate key error index: local.system.users.$id dup key: { : null }



 Comments   
Comment by Asya Kamsky [ 18/Jul/16 ]

Cannot reproduce with either 3.2.7 or 3.3.9.

Comment by Abdul Alkhatib [ 12/Nov/12 ]

Yes. Thanks. I am currently working around it my own until the next pymongo is released.

Thanks!

-abdul

Comment by Stephen Lee [ 12/Nov/12 ]

Abdul, have you had a chance to look at Bernie's findings?

Comment by Bernie Hackett [ 06/Nov/12 ]

Starting in version 2.3+ (current github master, what will become 2.4) pymongo uses save() to add users. This won't be a problem using pymongo:

>>> db = c.local
>>> db.system.users.remove()
>>> db.add_user('foo', 'pass')
>>> db.system.users.find_one()
{u'pwd': u'6d527721c7f54332643f2d328acfb328', u'_id': ObjectId('5099719afba5226126b0f92d'), u'readOnly': False, u'user': u'foo'}

The related change: https://github.com/mongodb/mongo-python-driver/commit/8637cfbe27e3dbdd2de77550bdc28bf0b3f6b638

Comment by Bernie Hackett [ 06/Nov/12 ]

Abdul, my apologies. Somehow I completely missed you specifically asking about local.system.users.

Comment by Bernie Hackett [ 06/Nov/12 ]

Hi, the reason you are seeing this is because you are upserting into the "local" database. If you use any other database you won't have this problem:

MongoDB shell version: 2.2.0
connecting to: test
> db.system.users.update({"user":"abdul"}, {"user":"abdul", "pwd":"xxxxxxxxx"}, true);
> db.system.users.find()
{ "_id" : ObjectId("50996ceedfe5d53b339dcbd0"), "user" : "abdul", "pwd" : "xxxxxxxxx" }
> db.system.users.update({"user":"abdul2"}, {"user":"abdul2", "pwd":"xxxxxxxxx"}, true);
> db.system.users.find()
{ "_id" : ObjectId("50996ceedfe5d53b339dcbd0"), "user" : "abdul", "pwd" : "xxxxxxxxx" }
{ "_id" : ObjectId("50996d0adfe5d53b339dcbd1"), "user" : "abdul2", "pwd" : "xxxxxxxxx" }

Now try the local database:

> use local
switched to db local
> db.system.users.update({"user":"abdul"}, {"user":"abdul", "pwd":"xxxxxxxxx"}, true);
> db.system.users.find()
{ "user" : "abdul", "pwd" : "xxxxxxxxx" }

I'm guessing you didn't mean to use the local database like this?

Generated at Thu Feb 08 03:14:50 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.