diff --git a/src/Databases/DatabaseOrdinary.cpp b/src/Databases/DatabaseOrdinary.cpp index 644bed23350..ef8b0eaae4f 100644 --- a/src/Databases/DatabaseOrdinary.cpp +++ b/src/Databases/DatabaseOrdinary.cpp @@ -46,12 +46,14 @@ static constexpr size_t METADATA_FILE_BUFFER_SIZE = 32768; DatabaseOrdinary::DatabaseOrdinary(const String & name_, const String & metadata_path_, ContextPtr context_) : DatabaseOrdinary(name_, metadata_path_, "data/" + escapeForFileName(name_) + "/", "DatabaseOrdinary (" + name_ + ")", context_) { + getContext()->addWarningMessageAboutDatabaseOrdinary(name_); } DatabaseOrdinary::DatabaseOrdinary( const String & name_, const String & metadata_path_, const String & data_path_, const String & logger, ContextPtr context_) : DatabaseOnDisk(name_, metadata_path_, data_path_, logger, context_) { + getContext()->addWarningMessageAboutDatabaseOrdinary(name_); } void DatabaseOrdinary::loadStoredObjects(ContextMutablePtr, LoadingStrictnessLevel) diff --git a/src/Interpreters/Context.cpp b/src/Interpreters/Context.cpp index 0e5897e7306..3c0cddf4a15 100644 --- a/src/Interpreters/Context.cpp +++ b/src/Interpreters/Context.cpp @@ -1171,6 +1171,30 @@ void Context::addWarningMessage(const String & msg) const shared->addWarningMessage(msg); } +void Context::addWarningMessageAboutDatabaseOrdinary(const String & database_name) const +{ + std::lock_guard lock(shared->mutex); + + /// We would like to report only about the first database with engine Ordinary + static std::atomic_bool is_called = false; + if (is_called.exchange(true)) + return; + + auto suppress_re = shared->getConfigRefWithLock(lock).getString("warning_supress_regexp", ""); + /// We don't use getFlagsPath method, because it takes a shared lock. + auto convert_databases_flag = fs::path(shared->flags_path) / "convert_ordinary_to_atomic"; + auto message = fmt::format("Server has databases (for example `{}`) with Ordinary engine, which was deprecated.\n" + "To convert this database to a new Atomic engine, please create a forcing flag {} and make sure that ClickHouse has write permission for it.\n" + "Example:\n" + "sudo touch '{}' && sudo chmod 666 '{}'", + database_name, + convert_databases_flag.string(), convert_databases_flag.string(), convert_databases_flag.string()); + + bool is_supressed = !suppress_re.empty() && re2::RE2::PartialMatch(message, suppress_re); + if (!is_supressed) + shared->addWarningMessage(message); +} + void Context::setConfig(const ConfigurationPtr & config) { shared->setConfig(config); diff --git a/src/Interpreters/Context.h b/src/Interpreters/Context.h index 8d40ccb301b..cac8c4c6ad3 100644 --- a/src/Interpreters/Context.h +++ b/src/Interpreters/Context.h @@ -532,6 +532,7 @@ public: void setUserScriptsPath(const String & path); void addWarningMessage(const String & msg) const; + void addWarningMessageAboutDatabaseOrdinary(const String & database_name) const; void setTemporaryStorageInCache(const String & cache_disk_name, size_t max_size); void setTemporaryStoragePolicy(const String & policy_name, size_t max_size); diff --git a/src/Interpreters/loadMetadata.cpp b/src/Interpreters/loadMetadata.cpp index 9543c70f49d..0b7a6dc92b0 100644 --- a/src/Interpreters/loadMetadata.cpp +++ b/src/Interpreters/loadMetadata.cpp @@ -227,26 +227,13 @@ LoadTaskPtrs loadMetadata(ContextMutablePtr context, const String & default_data databases.emplace(default_database_name, std::filesystem::path(path) / escapeForFileName(default_database_name)); } - bool has_ordinary_databases = false; TablesLoader::Databases loaded_databases; for (const auto & [name, db_path] : databases) { loadDatabase(context, name, db_path, has_force_restore_data_flag); - - auto database = DatabaseCatalog::instance().getDatabase(name); - loaded_databases.insert({name, database}); - - - if (database->getEngineName() == "Ordinary") - has_ordinary_databases = true; - - loaded_databases.insert({name,database}); + loaded_databases.insert({name, DatabaseCatalog::instance().getDatabase(name)}); } - if (has_ordinary_databases) - context->addWarningMessage("Server has databases with Ordinary engine, which is not optimal. \n " - "To convert this database to a new Atomic engine, please create a flag named `convert_ordinary_to_atomic` in flags directory"); - auto mode = getLoadingStrictnessLevel(/* attach */ true, /* force_attach */ true, has_force_restore_data_flag); TablesLoader loader{context, std::move(loaded_databases), mode}; auto load_tasks = loader.loadTablesAsync(); diff --git a/tests/queries/0_stateless/02988_ordinary_database_warning.reference b/tests/queries/0_stateless/02988_ordinary_database_warning.reference new file mode 100644 index 00000000000..587579af915 --- /dev/null +++ b/tests/queries/0_stateless/02988_ordinary_database_warning.reference @@ -0,0 +1 @@ +Ok. diff --git a/tests/queries/0_stateless/02988_ordinary_database_warning.sql b/tests/queries/0_stateless/02988_ordinary_database_warning.sql new file mode 100644 index 00000000000..cfa3eb42f53 --- /dev/null +++ b/tests/queries/0_stateless/02988_ordinary_database_warning.sql @@ -0,0 +1,8 @@ +DROP DATABASE IF EXISTS 02988_ordinary; + +SET allow_deprecated_database_ordinary = 1; +CREATE DATABASE 02988_ordinary ENGINE=Ordinary; + +SELECT 'Ok.' FROM system.warnings WHERE message ILIKE '%Ordinary%' and message ILIKE '%deprecated%'; + +DROP DATABASE IF EXISTS 02988_ordinary;