diff --git a/dbms/src/Databases/DatabaseMemory.cpp b/dbms/src/Databases/DatabaseMemory.cpp index b5c39773a3e..7eb5053e9cb 100644 --- a/dbms/src/Databases/DatabaseMemory.cpp +++ b/dbms/src/Databases/DatabaseMemory.cpp @@ -8,75 +8,22 @@ namespace DB namespace ErrorCodes { - extern const int TABLE_ALREADY_EXISTS; - extern const int UNKNOWN_TABLE; - extern const int LOGICAL_ERROR; extern const int CANNOT_GET_CREATE_TABLE_QUERY; } +DatabaseMemory::DatabaseMemory(String name_) + : DatabaseWithOwnTablesBase(std::move(name_)) + , log(&Logger::get("DatabaseMemory(" + name + ")")) +{} + void DatabaseMemory::loadTables( Context & /*context*/, ThreadPool * /*thread_pool*/, bool /*has_force_restore_data_flag*/) { - log = &Logger::get("DatabaseMemory(" + name + ")"); - /// Nothing to load. } -bool DatabaseMemory::isTableExist( - const Context & /*context*/, - const String & table_name) const -{ - std::lock_guard lock(mutex); - return tables.find(table_name) != tables.end(); -} - -StoragePtr DatabaseMemory::tryGetTable( - const Context & /*context*/, - const String & table_name) const -{ - std::lock_guard lock(mutex); - auto it = tables.find(table_name); - if (it == tables.end()) - return {}; - return it->second; -} - -DatabaseIteratorPtr DatabaseMemory::getIterator(const Context & /*context*/) -{ - std::lock_guard lock(mutex); - return std::make_unique(tables); -} - -bool DatabaseMemory::empty(const Context & /*context*/) const -{ - std::lock_guard lock(mutex); - return tables.empty(); -} - -StoragePtr DatabaseMemory::detachTable(const String & table_name) -{ - StoragePtr res; - { - std::lock_guard lock(mutex); - auto it = tables.find(table_name); - if (it == tables.end()) - throw Exception("Table " + name + "." + table_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE); - res = it->second; - tables.erase(it); - } - - return res; -} - -void DatabaseMemory::attachTable(const String & table_name, const StoragePtr & table) -{ - std::lock_guard lock(mutex); - if (!tables.emplace(table_name, table).second) - throw Exception("Table " + name + "." + table_name + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS); -} - void DatabaseMemory::createTable( const Context & /*context*/, const String & table_name, @@ -125,26 +72,6 @@ ASTPtr DatabaseMemory::getCreateQuery( throw Exception("There is no CREATE TABLE query for DatabaseMemory tables", ErrorCodes::CANNOT_GET_CREATE_TABLE_QUERY); } -void DatabaseMemory::shutdown() -{ - /// You can not hold a lock during shutdown. - /// Because inside `shutdown` function tables can work with database, and mutex is not recursive. - - Tables tables_snapshot; - { - std::lock_guard lock(mutex); - tables_snapshot = tables; - } - - for (const auto & kv: tables_snapshot) - { - kv.second->shutdown(); - } - - std::lock_guard lock(mutex); - tables.clear(); -} - void DatabaseMemory::drop() { /// Additional actions to delete database are not required. diff --git a/dbms/src/Databases/DatabaseMemory.h b/dbms/src/Databases/DatabaseMemory.h index 586dcfbe4da..d4599a5c342 100644 --- a/dbms/src/Databases/DatabaseMemory.h +++ b/dbms/src/Databases/DatabaseMemory.h @@ -1,8 +1,6 @@ #pragma once -#include -#include -#include +#include namespace Poco { class Logger; } @@ -16,18 +14,10 @@ namespace DB * All tables are created by calling code. * TODO: Maybe DatabaseRuntime is more suitable class name. */ -class DatabaseMemory : public IDatabase +class DatabaseMemory : public DatabaseWithOwnTablesBase { -protected: - const String name; - mutable std::mutex mutex; - Tables tables; - - Poco::Logger * log; - public: - - DatabaseMemory(const String & name_) : name(name_) {} + DatabaseMemory(String name_); String getEngineName() const override { return "Memory"; } @@ -36,18 +26,6 @@ public: ThreadPool * thread_pool, bool has_force_restore_data_flag) override; - bool empty(const Context & context) const override; - - DatabaseIteratorPtr getIterator(const Context & context) override; - - bool isTableExist( - const Context & context, - const String & table_name) const override; - - StoragePtr tryGetTable( - const Context & context, - const String & table_name) const override; - void createTable( const Context & context, const String & table_name, @@ -58,9 +36,6 @@ public: const Context & context, const String & table_name) override; - void attachTable(const String & table_name, const StoragePtr & table) override; - StoragePtr detachTable(const String & table_name) override; - void renameTable( const Context & context, const String & table_name, @@ -81,8 +56,10 @@ public: const Context & context, const String & table_name) const override; - void shutdown() override; void drop() override; + +private: + Poco::Logger * log; }; } diff --git a/dbms/src/Databases/DatabaseOrdinary.cpp b/dbms/src/Databases/DatabaseOrdinary.cpp index fc82b29a228..aa424e1118c 100644 --- a/dbms/src/Databases/DatabaseOrdinary.cpp +++ b/dbms/src/Databases/DatabaseOrdinary.cpp @@ -93,8 +93,11 @@ static void loadTable( } -DatabaseOrdinary::DatabaseOrdinary(const String & name_, const String & metadata_path_, const Context & context) - : DatabaseMemory(name_), metadata_path(metadata_path_), data_path(context.getPath() + "data/" + escapeForFileName(name_) + "/") +DatabaseOrdinary::DatabaseOrdinary(String name_, const String & metadata_path_, const Context & context) + : DatabaseWithOwnTablesBase(std::move(name_)) + , metadata_path(metadata_path_) + , data_path(context.getPath() + "data/" + escapeForFileName(name) + "/") + , log(&Logger::get("DatabaseOrdinary (" + name + ")")) { Poco::File(data_path).createDirectories(); } @@ -105,8 +108,6 @@ void DatabaseOrdinary::loadTables( ThreadPool * thread_pool, bool has_force_restore_data_flag) { - log = &Logger::get("DatabaseOrdinary (" + name + ")"); - using FileNames = std::vector; FileNames file_names; @@ -457,7 +458,6 @@ void DatabaseOrdinary::drop() /// No additional removal actions are required. } - void DatabaseOrdinary::alterTable( const Context & context, const String & name, diff --git a/dbms/src/Databases/DatabaseOrdinary.h b/dbms/src/Databases/DatabaseOrdinary.h index 25e99114430..5902ee73a76 100644 --- a/dbms/src/Databases/DatabaseOrdinary.h +++ b/dbms/src/Databases/DatabaseOrdinary.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace DB @@ -10,14 +10,10 @@ namespace DB * It stores tables list in filesystem using list of .sql files, * that contain declaration of table represented by SQL ATTACH TABLE query. */ -class DatabaseOrdinary : public DatabaseMemory +class DatabaseOrdinary : public DatabaseWithOwnTablesBase { -protected: - const String metadata_path; - const String data_path; - public: - DatabaseOrdinary(const String & name_, const String & metadata_path_, const Context & context); + DatabaseOrdinary(String name_, const String & metadata_path_, const Context & context); String getEngineName() const override { return "Ordinary"; } @@ -64,6 +60,10 @@ public: void drop() override; private: + const String metadata_path; + const String data_path; + Poco::Logger * log; + void startupTables(ThreadPool * thread_pool); }; diff --git a/dbms/src/Databases/DatabasesCommon.cpp b/dbms/src/Databases/DatabasesCommon.cpp index 66d05d11184..04511f7b9ce 100644 --- a/dbms/src/Databases/DatabasesCommon.cpp +++ b/dbms/src/Databases/DatabasesCommon.cpp @@ -16,6 +16,9 @@ namespace DB namespace ErrorCodes { extern const int EMPTY_LIST_OF_COLUMNS_PASSED; + extern const int TABLE_ALREADY_EXISTS; + extern const int UNKNOWN_TABLE; + extern const int LOGICAL_ERROR; } @@ -80,4 +83,78 @@ std::pair createTableFromDefinition( }; } + +bool DatabaseWithOwnTablesBase::isTableExist( + const Context & /*context*/, + const String & table_name) const +{ + std::lock_guard lock(mutex); + return tables.find(table_name) != tables.end(); +} + +StoragePtr DatabaseWithOwnTablesBase::tryGetTable( + const Context & /*context*/, + const String & table_name) const +{ + std::lock_guard lock(mutex); + auto it = tables.find(table_name); + if (it == tables.end()) + return {}; + return it->second; +} + +DatabaseIteratorPtr DatabaseWithOwnTablesBase::getIterator(const Context & /*context*/) +{ + std::lock_guard lock(mutex); + return std::make_unique(tables); +} + +bool DatabaseWithOwnTablesBase::empty(const Context & /*context*/) const +{ + std::lock_guard lock(mutex); + return tables.empty(); +} + +StoragePtr DatabaseWithOwnTablesBase::detachTable(const String & table_name) +{ + StoragePtr res; + { + std::lock_guard lock(mutex); + auto it = tables.find(table_name); + if (it == tables.end()) + throw Exception("Table " + name + "." + table_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE); + res = it->second; + tables.erase(it); + } + + return res; +} + +void DatabaseWithOwnTablesBase::attachTable(const String & table_name, const StoragePtr & table) +{ + std::lock_guard lock(mutex); + if (!tables.emplace(table_name, table).second) + throw Exception("Table " + name + "." + table_name + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS); +} + +void DatabaseWithOwnTablesBase::shutdown() +{ + /// You can not hold a lock during shutdown. + /// Because inside `shutdown` function tables can work with database, and mutex is not recursive. + + Tables tables_snapshot; + { + std::lock_guard lock(mutex); + tables_snapshot = tables; + } + + for (const auto & kv: tables_snapshot) + { + kv.second->shutdown(); + } + + std::lock_guard lock(mutex); + tables.clear(); +} + } diff --git a/dbms/src/Databases/DatabasesCommon.h b/dbms/src/Databases/DatabasesCommon.h index 2a2ccbb26ec..3f1d8f9d800 100644 --- a/dbms/src/Databases/DatabasesCommon.h +++ b/dbms/src/Databases/DatabasesCommon.h @@ -70,4 +70,36 @@ public: } }; +/// A base class for databases that manage their own list of tables. +class DatabaseWithOwnTablesBase : public IDatabase +{ +public: + bool isTableExist( + const Context & context, + const String & table_name) const override; + + StoragePtr tryGetTable( + const Context & context, + const String & table_name) const override; + + bool empty(const Context & context) const override; + + + void attachTable(const String & table_name, const StoragePtr & table) override; + + StoragePtr detachTable(const String & table_name) override; + + DatabaseIteratorPtr getIterator(const Context & context) override; + + void shutdown() override; + +protected: + String name; + + mutable std::mutex mutex; + Tables tables; + + DatabaseWithOwnTablesBase(String name_) : name(std::move(name_)) { } +}; + } diff --git a/dbms/src/Server/LocalServer.cpp b/dbms/src/Server/LocalServer.cpp index 1196c62f06f..035e08c4d3f 100644 --- a/dbms/src/Server/LocalServer.cpp +++ b/dbms/src/Server/LocalServer.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include