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

Capped collections can contain too many documents after replication recovery

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major - P3
    • Resolution: Fixed
    • None
    • 4.9.0, 4.4.5, 4.2.14, 4.0.25
    • None
    • None
    • Fully Compatible
    • ALL
    • v4.4, v4.2, v4.0
    • Execution Team 2021-02-08, Execution Team 2021-02-22, Execution Team 2021-03-08
    • 15

    Description

      Starting in SERVER-25025, we mark a collection as always needing size adjustment only if we are in rollback or replication recovery. However, we only set the inReplicationRecovery flag once we are in ReplicationRecoveryImpl::recoverFromOplog, which occurs after the aforementioned check for replication recovery.

      This causes an issue for capped collections when the number of inserts applied during replication recovery is greater than collection's max number of documents. Since we're erroneously not adjusting the count, these documents will not delete other documents already inserted during replication recovery, causing the capped collection to contain more documents than it should until collection validation is run to correct the fast count.

      The following jstest reproduces the issue:

      /**
       * Reproduces the issue described in SERVER-52833.
       */
      (function() {
      "use strict";
       
      load("jstests/libs/fail_point_util.js");
       
      const rst = new ReplSetTest({nodes: 1});
      rst.startSet();
      rst.initiate();
       
      const primary = rst.getPrimary();
      const testDB = primary.getDB("test");
      const coll = testDB.getCollection(jsTestName());
       
      assert.commandWorked(testDB.createCollection(coll.getName(), {capped: true, size: 100, max: 1}));
       
      const ts = assert.commandWorked(testDB.runCommand({insert: coll.getName(), documents: [{a: 1}]}))
                     .operationTime;
      configureFailPoint(primary, "holdStableTimestampAtSpecificTimestamp", {timestamp: ts});
       
      assert.commandWorked(coll.insert([{b: 1}, {b: 2}]));
      rst.restart(primary);
       
      rst.stopSet();
      })();
      

      Attachments

        Issue Links

          Activity

            People

              gregory.noma@mongodb.com Gregory Noma
              gregory.noma@mongodb.com Gregory Noma
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: