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

Using the OplogReplay flag with extra predicates can yield incorrect results

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Critical - P2 Critical - P2
    • 2.6.1, 2.7.0
    • Affects Version/s: 2.6.0
    • Component/s: Querying
    • None
    • ALL
    • 35

      Issue Status as of April 17, 2014

      ISSUE SUMMARY
      The OplogReplay query flag is an internal optimization for queries on the oplog (and other capped collections) using the ts (timestamp) field. Version 2.6.0 introduced a bug whereby a query using the OplogReplay flag with additional predicates not on the ts field could return incorrect results.

      USER IMPACT
      Internally, replication issues queries with predicates only on the ts field, and thus is unaffected by the bug. Third-party tools or other user implementations to query or tail the oplog can break, if they use the query flag and have additional query predicates.

      WORKAROUNDS
      A query without the OplogReplay query flag would return correct results but may be less efficient as it would not employ the OplogReplay optimization.

      RESOLUTION
      The fix restores the behavior to ignore predicates on other fields when walking the collection backwards to find the earliest oplog entry that matches the query. This brings the behavior back in line with that of version 2.4.x. Additionally, validation was added to ensure that the predicate on ts is either $gt or $gte, as the OplogReplay optimization does not work with other operators.

      AFFECTED VERSIONS
      Version 2.6.0 was affected by this bug.

      PATCHES
      The patch is included in the 2.6.1 production release.

      Original description

      Querying the oplog on a 2.6.0 secondary with the oplog replay flag and another predicate in addition to "ts" gives incorrect results vs. a 2.4.8 primary.

      The query returns correct results if "ts" is the only predicate in the find.

      query: db.oplog.rs.find({ts : {$gte : Timestamp(1397347250,1)}, "o2._id" : ObjectId("52a41544e4b04cb2bcc59814")}).addOption(8).limit(1)

      I do not have a 2.4 secondary to test this on now, but I've issued similar queries on 2.4 secondaries in the past and they returned correct results.

            Assignee:
            david.storch@mongodb.com David Storch
            Reporter:
            steve.briskin Steve Briskin (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated:
              Resolved: