[SERVER-21800] updates that implicitly change type may not replicate correctly Created: 08/Dec/15  Updated: 25/Apr/16  Resolved: 11/Dec/15

Status: Closed
Project: Core Server
Component/s: Write Ops
Affects Version/s: 3.0.7, 3.2.0
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Robert Guo (Inactive) Assignee: Charlie Swanson
Resolution: Duplicate Votes: 0
Labels: fuzzer-blocker
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-16801 update considers a change in numerica... Closed
Related
related to SERVER-21801 CheckReplDBHash testing hook should c... Closed
Operating System: ALL
Steps To Reproduce:

// start a replica set
db.test.insert({a:NumberLong('-9223372036854775808')});
db.test.update({}, { $inc: { a: 13 } });
// the number is different on the primary and secondary

Sprint: QuInt E (01/11/16)
Participants:
Linked BF Score: 0

 Description   

calling $inc on a large number from the shell may cause the number to be different on the primary and secondary.

Does not seem to occur when doing the repro with the Python driver. The result of the increment is correct.



 Comments   
Comment by Eric Milkie [ 10/Dec/15 ]

This is simply SERVER-16801.

Comment by Eric Milkie [ 10/Dec/15 ]

The problem appears to be that while $inc can utilize the implicit type conversion that SafeNum provides, $set does not work in an equivalent way and will not do implicit type conversion:

NumberLong $inc with NumberDouble -> NumberDouble
NumberLong $set to NumberDouble -> NumberLong (!!)

On the primary, it uses $inc to produce the result, but for idempotency, the secondary uses a $set to produce the same result.

One can see the problem with a simple test on a standalone node:

> db.a.insert({a1:NumberLong('-9223372036854775808')});
WriteResult({ "nInserted" : 1 })
> db.a.find()
{ "_id" : ObjectId("5669993a49e0557a277d9392"), "a1" : NumberLong("-9223372036854775808") }
> db.a.update({}, { $set: { a1: -9223372036854776000 } });
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.a.find()
{ "_id" : ObjectId("5669993a49e0557a277d9392"), "a1" : NumberLong("-9223372036854775808") }

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