`DataTypeFactory::get` locks a mutex inside shared a context, there was a case when many threads were locked inside it

https://pastila.nl/?0043b3e6/c557368f4cf0eb87a3c6f2cc162bc693

It is not clear which thread locked the mutex for a long time. However, it may be possible to lock less inside `DataTypeFactory::get`.
void setAsynchronousInsertQueue(const std::shared_ptr<AsynchronousInsertQueue> & ptr);
    ReadTaskCallback getReadTaskCallback() const;
    void setReadTaskCallback(ReadTaskCallback && callback);
    MergeTreeReadTaskCallback getMergeTreeReadTaskCallback() const;
    void setMergeTreeReadTaskCallback(MergeTreeReadTaskCallback && callback);
    
    void initializeBackgroundExecutorsIfNeeded();
    bool areBackgroundExecutorsInitialized();
    MergeMutateBackgroundExecutorPtr getMergeMutateExecutor() const;
    OrdinaryBackgroundExecutorPtr getMovesExecutor() const;
    OrdinaryBackgroundExecutorPtr getFetchesExecutor() const;
    OrdinaryBackgroundExecutorPtr getCommonExecutor() const;
    
    ReadSettings getReadSettings() const;
    
    WriteSettings getWriteSettings() const;
private:
    std::unique_lock<std::recursive_mutex> getLock() const;
    void initGlobal();
    
    void calculateAccessRights();
    template <typename... Args>
    void checkAccessImpl(const Args &... args) const;
    EmbeddedDictionaries & getEmbeddedDictionariesImpl(bool throw_on_error) const;
    void checkCanBeDropped(const String & database, const String & table, const size_t & size, const size_t & max_size_to_drop) const;
    StoragePolicySelectorPtr getStoragePolicySelector(std::lock_guard<std::mutex> & lock) const;
    DiskSelectorPtr getDiskSelector(std::lock_guard<std::mutex> & ) const;
};
}