MongoDB attempts insert instead of update/upsert if reconnect happens

61 views
Skip to first unread message

Mikhail Novikov

unread,
May 25, 2016, 7:32:32 AM5/25/16
to node-mongodb-native
Hello!

I have an occasional error with MongoDB nodejs driver (v 2.0.48).

It seems to be that in some cases, when doing MongoDB "findOneAndUpdate" with "upsert: true", update object is not converted correctly and is sent as is, causing incorrect documents being inserted or errors. For instance dotted keys are not converted to a nested object. It seems that it happens when a reconnect happened and MongoDB is trying to send the update again, but in a wrong way this time (you can see .emit("reconnect") in stack trace). I can't reproduce it myself in dev, it happens very rarely, but it does happen in production. In all the other time the code works fine.

Here is code and stacktrace:

db.collection(type).findOneAndUpdate({
  _id
: id,
}, {
  $set
: { 'very.dotted.key': 'someId', },
}, {
  upsert
: true,
  returnOriginal
: false,
});



MongoError: key very.dotted.key must not contain '.'
 
?, in Error
 
File "/app/node_modules/bson/lib/bson/parser/serializer.js", line 682, in serializeInto
 
throw Error("key " + key + " must not contain '.'");
 
File "/app/node_modules/bson/lib/bson/parser/serializer.js", line 280, in serializeObject
 
var endIndex = serializeInto(buffer, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined);
 
File "/app/node_modules/bson/lib/bson/parser/serializer.js", line 705, in serializeInto
 index
= serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined);
 
File "/app/node_modules/bson/lib/bson/parser/serializer.js", line 280, in serializeObject
 
var endIndex = serializeInto(buffer, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined);
 
File "/app/node_modules/bson/lib/bson/parser/serializer.js", line 551, in serializeInto
 index
= serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined);
 
File "/app/node_modules/bson/lib/bson/parser/serializer.js", line 280, in serializeObject
 
var endIndex = serializeInto(buffer, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined);
 
File "/app/node_modules/bson/lib/bson/parser/serializer.js", line 705, in serializeInto
 index
= serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined);
 
File "/app/node_modules/bson/lib/bson/bson.js", line 47, in serialize
 
var serializationIndex = serializer(buffer, object, checkKeys, index || 0, 0, serializeFunctions, ignoreUndefined);
 
File "/app/node_modules/mongodb-core/lib/connection/commands.js", line 143, in Query.toBin
 
var query = self.bson.serialize(this.query
 
File "/app/node_modules/mongodb-core/lib/topologies/server.js", line 763, in executeSingleOperation
 connection
.write(query.toBin());
 
File "/app/node_modules/mongodb-core/lib/topologies/server.js", line 843, in Server.command
 
return executeSingleOperation(self, ns, cmd, queryOptions, options, onAll, callback);
 
File "/app/node_modules/mongodb-core/lib/wireprotocol/2_6_support.js", line 52, in executeWrite
 topology
.command(f("%s.$cmd", d), writeCommand, opts, callback);
 
File "/app/node_modules/mongodb-core/lib/wireprotocol/2_6_support.js", line 60, in WireProtocol.insert
 executeWrite
(topology, 'insert', 'documents', ns, ops, options, callback);
 
File "/app/node_modules/mongodb-core/lib/topologies/server.js", line 962, in Server.insert
 
return self.s.wireProtocolHandler.insert(self, self.s.ismaster, ns, self.s.bson, self.s.pool, self.s.callbacks, ops, options, callback);
 
File "/app/node_modules/mongodb-core/lib/topologies/replset.js", line 381, in executeWriteOperation
 server
[op](ns, ops, options, handler);
 
File "/app/node_modules/mongodb-core/lib/topologies/replset.js", line 503, in ReplSet.insert
 executeWriteOperation
(this, 'insert', ns, ops, options, callback);
 
File "/app/node_modules/mongodb/lib/replset.js", line 399, in ReplSet.insert
 
this.s.replset.insert(ns, ops, options, callback);
 
File "/app/node_modules/mongodb/lib/topology_base.js", line 85, in Store.execute
 
this.s.topology[op.t](op.n, op.o, op.op, op.c);
 
File "/app/node_modules/mongodb/lib/replset.js", line 195, in .<anonymous>
 store
.execute();
 
File "events.js", line 96, in emitOne
 
File "events.js", line 188, in emit
 
File "/app/node_modules/mongodb-core/lib/topologies/replset_state.js", line 437, in State.update
 
self.replSet.emit('reconnect', server);
 
File "/app/node_modules/mongodb-core/lib/topologies/replset.js", line 1207, in processNewServer
 
if(!state.replState.update(ismaster, server)) {
 
File "/app/node_modules/mongodb-core/lib/topologies/replset.js", line 1260, in null.<anonymous>
 
if(count == 0) processNewServer();
 
File "/app/node_modules/mongodb-core/lib/topologies/server.js", line 1052, in null.<anonymous>
 callback
(null, new Session({}, self));
 
File "/app/node_modules/mongodb-core/lib/auth/scram.js", line 158, in finish
 
return callback(null, true);
 
File "/app/node_modules/mongodb-core/lib/auth/scram.js", line 171, in handleEnd
 finish
(count, numberOfValidConnections);
 
File "/app/node_modules/mongodb-core/lib/auth/scram.js", line 265, in null.<anonymous>
 handleEnd
(err, r);
 
File "/app/node_modules/mongodb-core/lib/topologies/server.js", line 778, in null.<anonymous>
 
try { callback(null, new CommandResult(result.documents[0], connection)); }
 
File "domain.js", line 280, in bound
 
File "domain.js", line 293, in runBound
 
File "/app/node_modules/mongodb-core/lib/topologies/server.js", line 95, in Callbacks.emit
 callback
(err, value);
 
File "/app/node_modules/mongodb-core/lib/topologies/server.js", line 249, in .messageHandler
 state
.callbacks.emit(response.responseTo, null, response);
 
File "/app/node_modules/mongodb-core/lib/connection/connection.js", line 262, in TLSSocket.<anonymous>
 
self.messageHandler(new Response(self.bson, emitBuffer, self.responseOptions), self);
 
File "events.js", line 96, in emitOne
 
File "events.js", line 188, in TLSSocket.emit
 
File "_stream_readable.js", line 172, in readableAddChunk
 
File "_stream_readable.js", line 130, in TLSSocket.Readable.push
 
File "net.js", line 542, in TLSWrap.onread



Thank you,
Mikhail

Christian Kvalheim

unread,
Aug 17, 2016, 5:35:48 AM8/17/16
to node-mongodb-native
I recommend upgrading to the 2.2.6 driver (Should be straight drop in replacement) as it has much better pool handling and better throughput.
Reply all
Reply to author
Forward
0 new messages