[SERVER-58738] Update command response does not properly reflect number of documents updated when updating a document fails due to exceeding the BSON size limit Created: 21/Jul/21  Updated: 18/Jul/23

Status: Backlog
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Gregory Noma Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to SERVER-78914 multi-deletes might return incorrect ... Investigating
Assigned Teams:
Query Execution
Operating System: ALL
Steps To Reproduce:

MongoDB Enterprise > db.c.insert({_id: 0, a: 0})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise > db.c.insert({_id: 1, a: 0, b: "i".repeat(1024*1024*10)})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise > db.c.insert({_id: 2, a: 0})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise > db.runCommand({update: "c", updates: [{q: {a: 0}, u: {$set: {c: "j".repeat(1024*1024*10)}}, multi: true}]})
{
	"n" : 0,
	"writeErrors" : [
		{
			"index" : 0,
			"code" : 10334,
			"errmsg" : "BSONObj size: 20971565 (0x140002D) is invalid. Size must be between 0 and 16793600(16MB) First element: _id: 1.0"
		}
	],
	"nModified" : 0,
	"ok" : 1
}
MongoDB Enterprise > db.c.find({c: {$exists: true}}).itcount()
1
MongoDB Enterprise > db.c.find({c: {$exists: true}}).toArray()[0]._id
0

Sprint: QE 2021-08-23, QE 2021-09-06, QE 2021-09-20, QE 2021-10-04, QE 2021-10-18, QE 2021-11-01, QE 2021-11-15, QE 2021-11-29, QE 2021-12-13, QE 2021-12-27, QE 2022-01-10, QE 2022-04-04, QE 2022-03-21, QE 2022-01-24, QE 2022-04-18, QE 2022-05-02, QE 2022-05-16, QE 2022-05-30
Participants:

 Description   

When attempting to update a document fails due to exceeding the BSON size limit, the number documents that were successfully updated before reaching the failing document are not reflected in the update command response; instead, it reports that 0 documents were updated. I have not tested whether this affects other types of write errors as well.



 Comments   
Comment by Romans Kasperovics [ 11/Mar/22 ]

I have tried some relevant commands, and they show transactional behaviour (restore the state on error):

  • db.coll.updateMany({}, {$set: {c: "i".repeat(1024 * 1024 * 10)); does not update anything if there is an error
  • Unknown macro: {{db.coll.insertMany([

    {a: 0}

    , {a: "i".repeat(1024 * 1024 * 20)}]); does not insert anything

In contrast, db.command({update: "coll", updates: [

{ ..., multi: true}

]}); updates a part of the collection until it hits an error based on the matching order.

Such a behaviour is common for imperative programming languages, but not for databases for few reasons. Is it intended? Or perhaps legacy?

Comment by Romans Kasperovics [ 08/Feb/22 ]

kyle.suarez, david.storch: no, my fix for SERVER-51456 is not fixing this issue. It is related, because nModified is also part of CurOp::AdditiveMetrics, but:

  • it is updated in a different stack frame
  • may be we don't need to use onRollback callbacks to fix this
    Anyways, it is good to have some improvements on exception safety there.
Comment by Kyle Suarez [ 08/Feb/22 ]

romans.kasperovics could you please check if your work in SERVER-51456 addresses this, or perhaps could be slightly modified to address this? CC david.storch

Comment by Ana Meza [ 23/Jul/21 ]

Kyle, could you please look for similar tickets?

Generated at Thu Feb 08 05:45:19 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.