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

findAndModify returns operationTime before the modification took place

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 3.5.11
    • Affects Version/s: 3.5.9
    • Component/s: Sharding
    • Labels:
    • Fully Compatible
    • Sharding 2017-07-10, Sharding 2017-07-31

      Filed to investigate why, and if its expected update the docs to warn users that follow up reads will not be causally consistent with the findAndModify unless it uses w:majority.
      the issue logs:
      https://evergreen.mongodb.com/task/mongodb_mongo_master_enterprise_rhel_62_64_bit_causally_consistent_jscore_passthrough_auth_WT_c7aa40633696a49fea2e75750b30a8339117d072_17_06_16_16_23_00

      After the root cause is determined here is the proposal to address the issue:

      1. Add OperationContext argument to interface EgressMetadataHook::readReplyMetadata

      virtual Status readReplyMetadata(OperationContext* opCtx, StringData replySource, const BSONObj& metadataObj) = 0;
      

      2. In ShardingConnectionHook::onCreate add the opCtx for replyMetadataReader:

          if (_shardedConnections) {
              conn->setReplyMetadataReader([this](OperationContext* opCtx, const BSONObj& metadataObj, StringData target) {
                  return _egressHook->readReplyMetadata(opCtx, target, metadataObj);
              });
          }
      

      3. in DBClientWithCommands::runCommandWithTarget pass the operationContext to the _metadataReader call

      Reading OperationTime
      4. add OperationTimeHook class

      Status OperationTimeHook::readReplyMetadata(OperationContext* opCtx, StringData replySource,
                                                        const BSONObj& metadataObj) {
              std::shared_ptr<OperationTimeTracker> timeTracker = OperationTimeTracker::get(opCtx);
      
             auto operationTime =metadataObj[kOperationTimeField];
              if (!operationTime.eoo()) {
                  invariant(operationTime.type() == BSONType::bsonTimestamp);
                  timeTracker->updateOperationTime(LogicalTime(operationTime.timestamp()));
              }
      
      }
      

      5. install OperationTimeHook to the hook list in runMongosServer

       unshardedHookList->addHook(stdx::make_unique<rpc::OperationTimeHook>());
       shardedHookList->addHook(stdx::make_unique<rpc::OperationTimeHook>());
      

            Assignee:
            misha.tyulenev@mongodb.com Misha Tyulenev (Inactive)
            Reporter:
            misha.tyulenev@mongodb.com Misha Tyulenev (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: