Search code examples
mongodbmongo-cxx-driver

Different behaviour on mongo 4.0 and 4.2 using mongocxx 3.5


The following simple code exhibits different behaviour on mongo 4.2.6 and 4.0

#include <iostream>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/instance.hpp>


using bsoncxx::builder::basic::make_document;
using bsoncxx::builder::basic::kvp;

int main(int, char**) {

  std::cout << "Creating instance" << std::endl;
  mongocxx::instance instance{};
  auto uri = mongocxx::uri{mongocxx::uri::k_default_uri};

  std::cout << "Creating client" << std::endl;
  auto client = mongocxx::client{uri};

  std::cout << "Accessing DB " << std::endl;
  auto db = client["mydb"];

  auto coll = db["my_collection"];

  auto criteria = make_document(kvp("x", "foo"));
  auto update = make_document(kvp("$set", make_document(kvp("x", "bar"))));

  auto write_concern = mongocxx::write_concern{};
  write_concern.journal(true);
  write_concern.acknowledge_level(
    mongocxx::write_concern::level::k_majority);

  std::cout << "Setting options" << std::endl;
  auto options = mongocxx::options::find_one_and_update()
    .write_concern(std::move(write_concern))
    .return_document(mongocxx::options::return_document::k_before);

  std::cout << "Invoking find_one_and_update" << std::endl;
  coll.find_one_and_update(
    criteria.view(),
    update.view(),
    options);

  std::cout << "Done" << std::endl;
}

On mongo 4.0, things work as expected and give this output,

Creating client
Accessing DB
Setting options
Invoking find_one_and_update
Done

However, when I run this against a mongo 4.2.6 server, I see this,

Creating client
Accessing DB
Setting options
Invoking find_one_and_update
terminate called after throwing an instance of 'mongocxx::v_noabi::write_exception'
  what():  BSON field 'j' is an unknown field.: generic server error
Aborted

This j seem to come from the write_concern.journal(true); line. Here is what the mongo 4.2.6 logs say about this,

1405 2020-05-24T21:57:55.798+0000 D2 COMMAND  [conn2] run command mydb.$cmd { findAndModify: "my_collection", query: { x: "foo" }, update: { $set: { x: "bar" } }, w: "majority", j: true, $db: "mydb", lsid     : { id: UUID("a2067505-a443-4427-84a6-500f83ce310c") } }
1406 2020-05-24T21:57:55.799+0000 D1 -        [conn2] User Assertion: Location51177: BSON field 'j' is an unknown field. src/mongo/db/commands/find_and_modify.cpp 315
1407 2020-05-24T21:57:55.799+0000 D1 COMMAND  [conn2] assertion while executing command 'findAndModify' on database 'mydb' with arguments '{ findAndModify: "my_collection", query: { x: "foo" }, update: {      $set: { x: "bar" } }, w: "majority", j: true, $db: "mydb", lsid: { id: UUID("a2067505-a443-4427-84a6-500f83ce310c") } }': Location51177: BSON field 'j' is an unknown field.
1408 2020-05-24T21:57:55.799+0000 I  COMMAND  [conn2] command mydb.$cmd command: findAndModify { findAndModify: "my_collection", query: { x: "foo" }, update: { $set: { x: "bar" } }, w: "majority", j: true     , $db: "mydb", lsid: { id: UUID("a2067505-a443-4427-84a6-500f83ce310c") } } numYields:0 ok:0 errMsg:"BSON field 'j' is an unknown field." errName:Location51177 errCode:51177 reslen:124 locks:{} proto     col:op_msg 0ms

I was going to create a bug for this in the mongocxx JIRA project. Posting this here so that I get a few more people to look at this - in case I am overlooking something.

Details,

In both cases, mongo was started with a command like this,

mongod --port=27017 --bind_ip_all -vvvvv --fork \
  --dbpath=/my/db/path/ --logpath=/my/db/path/logs/mongod.log

Solution

  • We've been able to verify that this is a bug in the mongocxx driver. It has been documented here: https://jira.mongodb.org/browse/CXX-2028