Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-44638

j:false is ignored in startTransaction write concern

    • Storage Execution
    • ALL
    • v4.2, v4.0
    • Hide

      To observe fdatasync per commit, run "strace -c -f -p $( pidof mongod )" in background and then run...

       

      session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
      col = session.getDatabase("test").foo;
      // Confirm collection exists to avoid error from transactional DDL below
      col.insertOne( { abc: 1 } );
      var i;
      var ninsert=10000;
      var jvals = [false];
      function time_it(jval) {
       var start_msecs = Date.now()
       for (i = 0; i < ninsert; i++) {
       session.startTransaction( { writeConcern: { w: 1, j: jval} } );
       col.insertOne( { abc: 1 } );
       session.commitTransaction();
       }
       var end_msecs = Date.now()
       var tot_secs = (end_msecs - start_msecs) / 1000.0;
       print("With trx:", jval, tot_secs, ninsert, ninsert/tot_secs);
      }
      jvals.forEach(time_it);
      session.endSession();
      

       

      To compare insert performance with/without transactions for both values of j run...

       

      session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
      col = session.getDatabase("test").foo;
      // Confirm collection exists to avoid error from transactional DDL below
      col.insertOne( { abc: 1 } );
      var i;
      var ninsert=5000;
      var jvals = [true, false];
      function time_it(jval) {
       var start_msecs = Date.now()
       for (i = 0; i < ninsert; i++) {
       session.startTransaction( { writeConcern: { w: 1, j: jval} } );
       col.insertOne( { abc: 1 } );
       session.commitTransaction();
       }
       var end_msecs = Date.now()
       var tot_secs = (end_msecs - start_msecs) / 1000.0;
       print("With trx:", jval, tot_secs, ninsert, ninsert/tot_secs);
      start_msecs = Date.now()
       for (i = 0; i < ninsert; i++) {
       col.insertOne( { abc: 1 }, { w: 1, j: jval} );
       }
       end_msecs = Date.now()
       tot_secs = (end_msecs - start_msecs) / 1000.0;
       print("Without trx:", jval, tot_secs, ninsert, ninsert/tot_secs);
      }
      jvals.forEach(time_it);
      session.endSession();
      

       

      Show
      To observe fdatasync per commit, run "strace -c -f -p $( pidof mongod )" in background and then run...   session = db.getMongo().startSession( { readPreference: { mode: "primary" } } ); col = session.getDatabase( "test" ).foo; // Confirm collection exists to avoid error from transactional DDL below col.insertOne( { abc: 1 } ); var i; var ninsert=10000; var jvals = [ false ]; function time_it(jval) { var start_msecs = Date.now() for (i = 0; i < ninsert; i++) { session.startTransaction( { writeConcern: { w: 1, j: jval} } ); col.insertOne( { abc: 1 } ); session.commitTransaction(); } var end_msecs = Date.now() var tot_secs = (end_msecs - start_msecs) / 1000.0; print( "With trx:" , jval, tot_secs, ninsert, ninsert/tot_secs); } jvals.forEach(time_it); session.endSession();   To compare insert performance with/without transactions for both values of j run...   session = db.getMongo().startSession( { readPreference: { mode: "primary" } } ); col = session.getDatabase( "test" ).foo; // Confirm collection exists to avoid error from transactional DDL below col.insertOne( { abc: 1 } ); var i; var ninsert=5000; var jvals = [ true , false ]; function time_it(jval) { var start_msecs = Date.now() for (i = 0; i < ninsert; i++) { session.startTransaction( { writeConcern: { w: 1, j: jval} } ); col.insertOne( { abc: 1 } ); session.commitTransaction(); } var end_msecs = Date.now() var tot_secs = (end_msecs - start_msecs) / 1000.0; print( "With trx:" , jval, tot_secs, ninsert, ninsert/tot_secs); start_msecs = Date.now() for (i = 0; i < ninsert; i++) { col.insertOne( { abc: 1 }, { w: 1, j: jval} ); } end_msecs = Date.now() tot_secs = (end_msecs - start_msecs) / 1000.0; print( "Without trx:" , jval, tot_secs, ninsert, ninsert/tot_secs); } jvals.forEach(time_it); session.endSession();  
    • Repl 2019-12-02

      Single replica set transactions should respect the writeConcern option j:false

      Sharded transactions will be handled in SERVER-37364, where we specify that commitTransaction can return as soon as the decision is written with the client's requested writeConcern. Some component writes must still be performed with {w:"majority", j: true}.

      Original description:

      There is a call to fdatasync per transaction with j:false in the startTransaction write concern. I prefer to have an option to do transactions without fsync/fdatasync per commit. The current behavior isn't documented, and it doesn't seem right to accept j:false in the write concern but then ignore it.

      I have been testing this with a single-node replica set and w:1 and what I see is:

      • insert rate without transactions is better with j:false than j:true as expected
      • insert rate with transactions is same for j:false vs j:true, this isn't expected
      • fdatasync/commit is done with transactions regardless of value for j

      Docs for startTransaction don't explain why fsync on commit would always be done – https://docs.mongodb.com/manual/reference/method/Session.startTransaction/

      Docs for writeConcern also don't explain this - https://docs.mongodb.com/manual/reference/write-concern/

            Assignee:
            backlog-server-execution [DO NOT USE] Backlog - Storage Execution Team
            Reporter:
            mdcallag@gmail.com Mark Callaghan
            Votes:
            0 Vote for this issue
            Watchers:
            22 Start watching this issue

              Created:
              Updated:
              Resolved: