diff --git a/dbms/src/Dictionaries/ODBCDictionarySource.cpp b/dbms/src/Dictionaries/ODBCDictionarySource.cpp index d5002bc94af..c2bad4eacca 100644 --- a/dbms/src/Dictionaries/ODBCDictionarySource.cpp +++ b/dbms/src/Dictionaries/ODBCDictionarySource.cpp @@ -21,12 +21,13 @@ ODBCDictionarySource::ODBCDictionarySource(const DictionaryStructure & dict_stru table{config.getString(config_prefix + ".table")}, where{config.getString(config_prefix + ".where", "")}, sample_block{sample_block}, - pool{std::make_shared( - config.getString(config_prefix + ".connector", "ODBC"), - config.getString(config_prefix + ".connection_string"))}, query_builder{dict_struct, db, table, where, ExternalQueryBuilder::None}, /// NOTE Better to obtain quoting style via ODBC interface. load_all_query{query_builder.composeLoadAllQuery()} { + pool = createAndCheckResizePocoSessionPool([&] () { return std::make_shared( + config.getString(config_prefix + ".connector", "ODBC"), + config.getString(config_prefix + ".connection_string")); + }); } /// copy-constructor is provided in order to support cloneability @@ -43,6 +44,21 @@ ODBCDictionarySource::ODBCDictionarySource(const ODBCDictionarySource & other) { } +std::shared_ptr ODBCDictionarySource::createAndCheckResizePocoSessionPool(PocoSessionPoolConstructor pool_constr) +{ + static std::mutex mutex; + + Poco::ThreadPool & pool = Poco::ThreadPool::defaultPool(); + + /// NOTE: The lock don't guarantee that external users of the pool don't change its capacity + std::unique_lock lock(mutex); + + if (pool.available() == 0) + pool.addCapacity(2 * std::max(pool.capacity(), 1)); + + return pool_constr(); +} + BlockInputStreamPtr ODBCDictionarySource::loadAll() { LOG_TRACE(log, load_all_query); diff --git a/dbms/src/Dictionaries/ODBCDictionarySource.h b/dbms/src/Dictionaries/ODBCDictionarySource.h index 7dbf95e720f..8e1ea57cc87 100644 --- a/dbms/src/Dictionaries/ODBCDictionarySource.h +++ b/dbms/src/Dictionaries/ODBCDictionarySource.h @@ -59,9 +59,15 @@ private: const std::string table; const std::string where; Block sample_block; - std::shared_ptr pool; + std::shared_ptr pool = nullptr; ExternalQueryBuilder query_builder; const std::string load_all_query; + + using PocoSessionPoolConstructor = std::function()>; + + /// Is used to adjust max size of default Poco thread pool. See issue #750 + /// Acquire the lock, resize pool and construct new Session + static std::shared_ptr createAndCheckResizePocoSessionPool(PocoSessionPoolConstructor pool_constr); };