diff --git a/programs/local/LocalServer.cpp b/programs/local/LocalServer.cpp index 571e3a3a4df..7d7fd8ff32d 100644 --- a/programs/local/LocalServer.cpp +++ b/programs/local/LocalServer.cpp @@ -654,8 +654,9 @@ void LocalServer::processConfig() if (!config().has("only-system-tables")) { - DatabaseCatalog::instance().startupBackgroundCleanup(); + DatabaseCatalog::instance().createBackgroundTasks(); loadMetadata(global_context); + DatabaseCatalog::instance().startupBackgroundCleanup(); } /// For ClickHouse local if path is not set the loader will be disabled. diff --git a/programs/server/Server.cpp b/programs/server/Server.cpp index df223317fcc..34d266b6519 100644 --- a/programs/server/Server.cpp +++ b/programs/server/Server.cpp @@ -1656,11 +1656,12 @@ try /// that may execute DROP before loadMarkedAsDroppedTables() in background, /// and so loadMarkedAsDroppedTables() will find it and try to add, and UUID will overlap. database_catalog.loadMarkedAsDroppedTables(); - database_catalog.startupBackgroundCleanup(); + database_catalog.createBackgroundTasks(); /// Then, load remaining databases loadMetadata(global_context, default_database); convertDatabasesEnginesIfNeed(global_context); startupSystemTables(); + database_catalog.startupBackgroundCleanup(); /// After loading validate that default database exists database_catalog.assertDatabaseExists(default_database); /// Load user-defined SQL functions. diff --git a/src/Interpreters/DatabaseCatalog.cpp b/src/Interpreters/DatabaseCatalog.cpp index 24d5f3491fd..6142608306f 100644 --- a/src/Interpreters/DatabaseCatalog.cpp +++ b/src/Interpreters/DatabaseCatalog.cpp @@ -152,20 +152,30 @@ void DatabaseCatalog::initializeAndLoadTemporaryDatabase() attachDatabase(TEMPORARY_DATABASE, db_for_temporary_and_external_tables); } -void DatabaseCatalog::startupBackgroundCleanup() +void DatabaseCatalog::createBackgroundTasks() { + /// It has to be done before databases are loaded (to avoid a race condition on initalization) if (Context::getGlobalContextInstance()->getApplicationType() == Context::ApplicationType::SERVER && unused_dir_cleanup_period_sec) { auto cleanup_task_holder = getContext()->getSchedulePool().createTask("DatabaseCatalog", [this]() { this->cleanupStoreDirectoryTask(); }); cleanup_task = std::make_unique(std::move(cleanup_task_holder)); + } + + auto task_holder = getContext()->getSchedulePool().createTask("DatabaseCatalog", [this](){ this->dropTableDataTask(); }); + drop_task = std::make_unique(std::move(task_holder)); +} + +void DatabaseCatalog::startupBackgroundCleanup() +{ + /// And it has to be done after all databases are loaded, otherwise cleanup_task may remove something that should not be removed + if (cleanup_task) + { (*cleanup_task)->activate(); /// Do not start task immediately on server startup, it's not urgent. (*cleanup_task)->scheduleAfter(unused_dir_hide_timeout_sec * 1000); } - auto task_holder = getContext()->getSchedulePool().createTask("DatabaseCatalog", [this](){ this->dropTableDataTask(); }); - drop_task = std::make_unique(std::move(task_holder)); (*drop_task)->activate(); std::lock_guard lock{tables_marked_dropped_mutex}; if (!tables_marked_dropped.empty()) diff --git a/src/Interpreters/DatabaseCatalog.h b/src/Interpreters/DatabaseCatalog.h index 5526e1496a3..11a855ebd79 100644 --- a/src/Interpreters/DatabaseCatalog.h +++ b/src/Interpreters/DatabaseCatalog.h @@ -135,6 +135,7 @@ public: static DatabaseCatalog & instance(); static void shutdown(); + void createBackgroundTasks(); void initializeAndLoadTemporaryDatabase(); void startupBackgroundCleanup(); void loadMarkedAsDroppedTables();