[SERVER-23981] Incompatible to update capped collection after upgrade to MongoDB-3.2 Created: 29/Apr/16  Updated: 15/Nov/21  Resolved: 29/Apr/16

Status: Closed
Project: Core Server
Component/s: Storage
Affects Version/s: 3.2.6
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Zhang Youdong Assignee: Stennie Steneker (Inactive)
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-20529 WiredTiger allows capped collection o... Closed
Operating System: ALL
Steps To Reproduce:

use mongo shell to create a capped collection

db.createCollection("capped", {capped: 1, max: 5000, size: 1000000})
db.capped.insert({id: "test", x: 0})

when use nodejs client to update this document, db.capped.update(

{id: "test}

, {$set: {x: 1}}), it will receive an error.

Cannot change the size of a document in a capped collection: 33 != 29

Participants:

 Description   

Background

Different drivers may have different way to encode a integer to BSON, eg: when insert a document

{status: 1}

* mongoshell encode 1 to a 8bytes data,  server received a request {status: 1.0}.
* nodejs driver encode 1 to 4bytes data, server received a request {status: 1}

MongoDB 3.2 behaivor

MongoDB-3.2 added on a new condition check when update a capped collection, this is suitable for all storage engines. Which means user "Cannot change the size of a document in a capped collection".

db/catalog/collection.cpp:556
    const auto oldSize = oldDoc.value().objsize();
    if (_recordStore->isCapped() && oldSize != newDoc.objsize())
        return {ErrorCodes::CannotGrowDocumentInCappedNamespace,
                str::stream() << "Cannot change the size of a document in a capped collection: "
                              << oldSize << " != " << newDoc.objsize()};

MongoDB 3.0 behaivor

In mongodb 3.0, only mmapv1 have limitation to update a capped collection, that is "objects in a capped ns cannot grow(no need have the same size with old document".

 
if (isCapped())
        return StatusWith<RecordId>(
            ErrorCodes::InternalError, "failing update: objects in a capped ns cannot grow", 10003);



 Comments   
Comment by Max Hirschhorn [ 29/Apr/16 ]

I'd also like to clarify what's happening with the mongo shell.

* mongoshell encode 1 to a 8bytes data,  server received a request {status: 1.0}.

This is because the representation for Number literals is as a double-precision 64-bit binary format IEEE 754 value. This is required by the ECMAScript specification: http://www.ecma-international.org/ecma-262/6.0/#sec-terms-and-definitions-number-value.

The reason why 8 bytes of data are being sent to the server is because the number is encoded as a double (BSON type 0x01) and not a 32-bit integer (BSON type 0x10). If you want to use 32-bit integers within the mongo shell, you must use the NumberInt constructor. This is described in our documentation and an example can be seen below:

> db.mycoll.insert({_id: 1})
> db.mycoll.insert({_id: 2.0})
> db.mycoll.insert({_id: NumberInt(3)})
> db.mycoll.find()
{ "_id" : 1 }
{ "_id" : 2 }
{ "_id" : 3 }
> db.mycoll.find({_id: {$type: 'double'}})
{ "_id" : 1 }
{ "_id" : 2 }
> db.mycoll.find({_id: {$type: 'int'}})
{ "_id" : 3 }

Comment by Ramon Fernandez Marina [ 29/Apr/16 ]

zyd_com, as per SERVER-20529 this is now expected behavior in 3.2. Unfortunately this backwards-breaking change is necessary to support replica sets with different storage engines.

Regards,
Ramón.

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