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

Convert getDestinedRecipient() in resharding_util to be a class method



    • Task
    • Status: Closed
    • Major - P3
    • Resolution: Duplicate
    • None
    • None
    • Sharding
    • None
    • Sharding 2021-07-26
    • 2


      getDestinedRecipient() is called on the write path for insert, updates, and deletes. Special care has needed to be taken to avoid introducing a performance regression on non-shardsvrs and on collections in sharded clusters not undergoing a resharding operation (SERVER-52974, SERVER-53678, SERVER-53679). More care is still needed.

      Converting getDestinedRecipient() into a class will make it more straightforward to make explicit what components must be lazily initialized and what components must be cached so introducing the resharding feature is performance neutral when not in active use.

      class ReshardingDonorWriteRouter {
          ReshardingDonorWriteRouter(OperationContext* opCtx,
                                     const NamespaceString& sourceNss,
                                     CatalogCache* catalogCache);
          ReshardingDonorWriteRouter(OperationContext* opCtx,
                                     const NamespaceString& sourceNss,
                                     CatalogCache* catalogCache,
                                     CollectionShardingState* css,
                                     const ScopedCollectionDescription* collDesc);
          CollectionShardingState* getCollectionShardingState() const;
          boost::optional<ShardId> getDestinedRecipient(const BSONObj& fullDocument) const;
          CollectionShardingState* const _css;
          const ScopedCollectionDescription* const _collDesc;
          boost::optional<ScopedCollectionFilter> _ownershipFilter;
          boost::optional<ShardKeyPattern> _reshardingKeyPattern;
          boost::optional<ChunkManager> _tempReshardingChunkMgr;

      Something along the above lines would be my proposal. It has the following properties:

      • OpObserverImpl doesn't get the CollectionShardingState or ScopedCollectionDescription when the mongod isn't a shardsvr. The 3-argument constructor would use nullptr for both when ShardingState::enabled() returns false.
      • UpdateStage already gets the CollectionShardingState and ScopedCollectionDescription. The 5-argument argument constructor would use the values to avoid getting them a second time.
      • OpObserverImpl::onInserts() would construct the ReshardingDonorWriteRouter once outside of the for loop. ReshardingDonorWriteRouter would have cached the ScopedCollectionFilter, ShardKeyPattern, and ChunkManager upon construction so calling ReshardingDonorWriteRouter::getDestinedRecipient() in a loop won't do extra work.
        • repl::logInsertOps() would be changed to take a const ReshardingDonorWriteRouter& as an argument.
      • All OpObserverImpl methods would use ReshardingDonorWriteRouter::getCollectionShardingState() to avoid getting the CollectionShardingState from the map a second time. Note that when the mongod isn't a shardsvr ReshardingDonorWriteRouter::getCollectionShardingState() will return nullptr. This is acceptable because OpObserverShardingImpl won't have been registered for non-shardsvrs either and so the CollectionShardingState* pointer won't ever be dereferenced.
      • ReshardingDonorWriteRouter would use TypeCollectionDonorFields::getTempReshardingNss() rather than calling constructTemporaryReshardingNss().
      • ReshardingDonorWriteRouter would be moved into libsharding_api_d (from libresharding_util).


        Issue Links



              junhson.jean-baptiste@mongodb.com Junhson Jean-Baptiste (Inactive)
              max.hirschhorn@mongodb.com Max Hirschhorn
              0 Vote for this issue
              2 Start watching this issue