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

Document growth of "key too large" document makes it disappear from the index

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 2.6.11
    • Affects Version/s: 2.6.9
    • Component/s: Index Maintenance
    • Labels:
      None
    • Fully Compatible
    • ALL
    • Hide

      The document

      > db.users.find()
      { "_id" : ObjectId("54876097ebb87b0aeb001e66"), "email" : "someone@somewhere.com", "appId" : 101430, "userId" : "5485adffab2a47502832c735", "customData" : { "subField" : "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } }
      

      The indexes:

      > db.users.getIndexes()
      [
      	{
      		"v" : 1,
      		"key" : {
      			"_id" : 1
      		},
      		"name" : "_id_",
      		"ns" : "test.users"
      	},
      	{
      		"v" : 1,
      		"key" : {
      			"appId" : 1,
      			"customData.subField" : 1
      		},
      		"name" : "appId_1_customData.subField_1",
      		"ns" : "test.users"
      	},
      	{
      		"v" : 1,
      		"unique" : true,
      		"key" : {
      			"appId" : 1,
      			"userId" : 1,
      			"email" : 1
      		},
      		"name" : "appId_1_userId_1_email_1",
      		"ns" : "test.users",
      		"background" : true,
      		"dropDups" : true
      	}
      ]
      

      Finding by _id works

      > db.users.find({}, {_id:1}).showDiskLoc()
      { "_id" : ObjectId("54876097ebb87b0aeb001e66"), "$diskLoc" : { "file" : 0, "offset" : 16816 } }
      

      Make the document grow, the update seems to fail:

      > var s2k = "a"; for (i=0;i<11;i++) s2k += s2k; print(s2k.length);
      2048
      > db.users.update({email: "someone@somewhere.com", appId:101430}, { $set: {"somethingNew" : s2k} });
      WriteResult({
      	"nMatched" : 0,
      	"nUpserted" : 0,
      	"nModified" : 0,
      	"writeError" : {
      		"code" : 17280,
      		"errmsg" : "Btree::insert: key too large to index, failing test.users.$appId_1_customData.subField_1 2071 { : 101430.0, : \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...\" }"
      	}
      })
      

      Finding by index finds nothing:

      > db.users.find({ "_id" : ObjectId("54876097ebb87b0aeb001e66") }, {_id:1})
      >  
      

      The document is still there:

      > db.users.find({}, {_id:1}).showDiskLoc()
      { "_id" : ObjectId("54876097ebb87b0aeb001e66"), "$diskLoc" : { "file" : 0, "offset" : 16816 } }
      

      You can now insert another document with the same _id:

      > db.users.insert(newDoc);
      WriteResult({ "nInserted" : 1 })
      > db.users.find({}, {_id:1}).showDiskLoc()
      { "_id" : ObjectId("54876097ebb87b0aeb001e66"), "$diskLoc" : { "file" : 0, "offset" : 16816 } }
      { "_id" : ObjectId("54876097ebb87b0aeb001e66"), "$diskLoc" : { "file" : 0, "offset" : 16560 } }
      
      Show
      The document > db.users.find() { "_id" : ObjectId( "54876097ebb87b0aeb001e66" ), "email" : "someone@somewhere.com" , "appId" : 101430, "userId" : "5485adffab2a47502832c735" , "customData" : { "subField" : "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } } The indexes: > db.users.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_" , "ns" : "test.users" }, { "v" : 1, "key" : { "appId" : 1, "customData.subField" : 1 }, "name" : "appId_1_customData.subField_1" , "ns" : "test.users" }, { "v" : 1, "unique" : true , "key" : { "appId" : 1, "userId" : 1, "email" : 1 }, "name" : "appId_1_userId_1_email_1" , "ns" : "test.users" , "background" : true , "dropDups" : true } ] Finding by _id works > db.users.find({}, {_id:1}).showDiskLoc() { "_id" : ObjectId( "54876097ebb87b0aeb001e66" ), "$diskLoc" : { "file" : 0, "offset" : 16816 } } Make the document grow, the update seems to fail: > var s2k = "a" ; for (i=0;i<11;i++) s2k += s2k; print(s2k.length); 2048 > db.users.update({email: "someone@somewhere.com" , appId:101430}, { $set: { "somethingNew" : s2k} }); WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 17280, "errmsg" : "Btree::insert: key too large to index, failing test.users.$appId_1_customData.subField_1 2071 { : 101430.0, : \" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...\ " }" } }) Finding by index finds nothing: > db.users.find({ "_id" : ObjectId( "54876097ebb87b0aeb001e66" ) }, {_id:1}) > The document is still there: > db.users.find({}, {_id:1}).showDiskLoc() { "_id" : ObjectId( "54876097ebb87b0aeb001e66" ), "$diskLoc" : { "file" : 0, "offset" : 16816 } } You can now insert another document with the same _id: > db.users.insert(newDoc); WriteResult({ "nInserted" : 1 }) > db.users.find({}, {_id:1}).showDiskLoc() { "_id" : ObjectId( "54876097ebb87b0aeb001e66" ), "$diskLoc" : { "file" : 0, "offset" : 16816 } } { "_id" : ObjectId( "54876097ebb87b0aeb001e66" ), "$diskLoc" : { "file" : 0, "offset" : 16560 } }
    • Quint Iteration 7

      This could happen for example of you upgrade from 2.4 with a document that has a "key too large" and didn't run or fix db.upgradeCheckAllDBs().

      Changing the document to make it grow causes the document to get cleared from the indexes. The document still exists but can't be found by _id.

      This can have strange effects downstream and on secondaries. For example another document with the same _id can be created.

      It also seems to result in the following on secondaries after a number of other operations:

      [repl writer worker 3] ERROR: writer worker caught exception:  :: caused by :: 10287 btree: key+recloc already in index on...
      

            Assignee:
            mathias@mongodb.com Mathias Stearn
            Reporter:
            ger.hartnett@mongodb.com Ger Hartnett
            Votes:
            0 Vote for this issue
            Watchers:
            10 Start watching this issue

              Created:
              Updated:
              Resolved: