mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Better load of dictionaries
This commit is contained in:
parent
b4e0ded048
commit
01e23f0a22
@ -98,13 +98,13 @@ void DatabaseDictionary::removeDictionary(
|
||||
}
|
||||
|
||||
void DatabaseDictionary::attachDictionary(
|
||||
const String & /*dictionary_name*/)
|
||||
const String & /*dictionary_name*/, const Context & /*context*/, bool /*load*/)
|
||||
{
|
||||
throw Exception("Dictionary engine doesn't support dictionaries.", ErrorCodes::UNSUPPORTED_METHOD);
|
||||
}
|
||||
|
||||
void DatabaseDictionary::detachDictionary(
|
||||
const String & /*dictionary_name*/)
|
||||
const String & /*dictionary_name*/, const Context & /*context*/)
|
||||
{
|
||||
throw Exception("Dictionary engine doesn't support dictionaries.", ErrorCodes::UNSUPPORTED_METHOD);
|
||||
}
|
||||
|
@ -89,9 +89,9 @@ public:
|
||||
ASTPtr tryGetCreateDictionaryQuery(const Context & context, const String & table_name) const override;
|
||||
|
||||
|
||||
void attachDictionary(const String & dictionary_name) override;
|
||||
void attachDictionary(const String & dictionary_name, const Context & context, bool load) override;
|
||||
|
||||
void detachDictionary(const String & dictionary_name) override;
|
||||
void detachDictionary(const String & dictionary_name, const Context & context) override;
|
||||
|
||||
void shutdown() override;
|
||||
|
||||
|
@ -122,12 +122,14 @@ DatabaseDictionariesIteratorPtr DatabaseLazy::getDictionariesIterator(
|
||||
}
|
||||
|
||||
void DatabaseLazy::attachDictionary(
|
||||
const String & /*dictionary_name*/)
|
||||
const String & /*dictionary_name*/,
|
||||
const Context & /*context*/,
|
||||
bool /*load*/)
|
||||
{
|
||||
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
||||
}
|
||||
|
||||
void DatabaseLazy::detachDictionary(const String & /*dictionary_name*/)
|
||||
void DatabaseLazy::detachDictionary(const String & /*dictionary_name*/, const Context & /*context*/)
|
||||
{
|
||||
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
||||
}
|
||||
|
@ -111,9 +111,9 @@ public:
|
||||
|
||||
StoragePtr detachTable(const String & table_name) override;
|
||||
|
||||
void attachDictionary(const String & dictionary_name) override;
|
||||
void attachDictionary(const String & dictionary_name, const Context & context, bool load) override;
|
||||
|
||||
void detachDictionary(const String & dictionary_name) override;
|
||||
void detachDictionary(const String & dictionary_name, const Context & context) override;
|
||||
|
||||
void shutdown() override;
|
||||
|
||||
|
@ -35,11 +35,11 @@ void DatabaseMemory::createTable(
|
||||
|
||||
|
||||
void DatabaseMemory::createDictionary(
|
||||
const Context & /*context*/,
|
||||
const Context & context,
|
||||
const String & dictionary_name,
|
||||
const ASTPtr & /*query*/)
|
||||
{
|
||||
attachDictionary(dictionary_name);
|
||||
attachDictionary(dictionary_name, context, true);
|
||||
}
|
||||
|
||||
|
||||
@ -52,10 +52,10 @@ void DatabaseMemory::removeTable(
|
||||
|
||||
|
||||
void DatabaseMemory::removeDictionary(
|
||||
const Context &,
|
||||
const Context & context,
|
||||
const String & dictionary_name)
|
||||
{
|
||||
detachDictionary(dictionary_name);
|
||||
detachDictionary(dictionary_name, context);
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
throw Exception("MySQL database engine does not support detach table.", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
void detachDictionary(const String &) override
|
||||
void detachDictionary(const String &, const Context &) override
|
||||
{
|
||||
throw Exception("MySQL database engine does not support detach dictionary.", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
@ -89,7 +89,7 @@ public:
|
||||
throw Exception("MySQL database engine does not support attach table.", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
void attachDictionary(const String &) override
|
||||
void attachDictionary(const String &, const Context &, bool) override
|
||||
{
|
||||
throw Exception("MySQL database engine does not support attach dictionary.", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
@ -296,21 +296,22 @@ void DatabaseOnDisk::createDictionary(
|
||||
|
||||
try
|
||||
{
|
||||
database.attachDictionary(dictionary_name);
|
||||
/// Do not load it now
|
||||
database.attachDictionary(dictionary_name, context, false);
|
||||
|
||||
/// If it was ATTACH query and file with table metadata already exist
|
||||
/// (so, ATTACH is done after DETACH), then rename atomically replaces old file with new one.
|
||||
Poco::File(dictionary_metadata_tmp_path).renameTo(dictionary_metadata_path);
|
||||
|
||||
/// Load dictionary
|
||||
bool lazy_load = context.getConfigRef().getBool("dictionaries_lazy_load", true);
|
||||
context.getExternalDictionariesLoader().reload(database.getDatabaseName() + "." + dictionary_name, !lazy_load);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Poco::File(dictionary_metadata_tmp_path).remove();
|
||||
throw;
|
||||
}
|
||||
|
||||
const auto & config = context.getConfigRef();
|
||||
context.getExternalDictionariesLoader().reload(
|
||||
database.getDatabaseName() + "." + dictionary_name, config.getBool("dictionaries_lazy_load", true));
|
||||
}
|
||||
|
||||
|
||||
@ -347,11 +348,11 @@ void DatabaseOnDisk::removeTable(
|
||||
|
||||
void DatabaseOnDisk::removeDictionary(
|
||||
IDatabase & database,
|
||||
const Context & /*context*/,
|
||||
const Context & context,
|
||||
const String & dictionary_name,
|
||||
Poco::Logger * log)
|
||||
{
|
||||
database.detachDictionary(dictionary_name);
|
||||
database.detachDictionary(dictionary_name, context);
|
||||
|
||||
String dictionary_metadata_path = database.getObjectMetadataPath(dictionary_name);
|
||||
|
||||
@ -370,7 +371,7 @@ void DatabaseOnDisk::removeDictionary(
|
||||
{
|
||||
LOG_WARNING(log, getCurrentExceptionMessage(__PRETTY_FUNCTION__));
|
||||
}
|
||||
database.attachDictionary(dictionary_name);
|
||||
database.attachDictionary(dictionary_name, context);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@ -482,14 +483,10 @@ time_t DatabaseOnDisk::getObjectMetadataModificationTime(
|
||||
Poco::File meta_file(table_metadata_path);
|
||||
|
||||
if (meta_file.exists())
|
||||
{
|
||||
return meta_file.getLastModified().epochTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<time_t>(0);
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseOnDisk::iterateMetadataFiles(const IDatabase & database, Poco::Logger * log, const IteratingFunction & iterating_function)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ try
|
||||
if (query.is_dictionary)
|
||||
{
|
||||
String dictionary_name = createDictionaryFromAST(query, database_name);
|
||||
database.attachDictionary(dictionary_name);
|
||||
database.attachDictionary(dictionary_name, context, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -125,6 +125,7 @@ void DatabaseOrdinary::loadStoredObjects(
|
||||
Context & context,
|
||||
bool has_force_restore_data_flag)
|
||||
{
|
||||
|
||||
/** Tables load faster if they are loaded in sorted (by name) order.
|
||||
* Otherwise (for the ext4 filesystem), `DirectoryIterator` iterates through them in some order,
|
||||
* which does not correspond to order tables creation and does not correspond to order of their location on disk.
|
||||
@ -183,7 +184,10 @@ void DatabaseOrdinary::loadStoredObjects(
|
||||
|
||||
/// After all tables was basically initialized, startup them.
|
||||
startupTables(pool);
|
||||
loadDictionaries(context);
|
||||
/// Add database as repository
|
||||
auto dictionaries_repository = std::make_unique<ExternalLoaderDatabaseConfigRepository>(shared_from_this(), context);
|
||||
context.getExternalDictionariesLoader().addConfigRepository(
|
||||
getDatabaseName(), std::move(dictionaries_repository), {"dictionary", "name"});
|
||||
}
|
||||
|
||||
|
||||
@ -210,16 +214,6 @@ void DatabaseOrdinary::startupTables(ThreadPool & thread_pool)
|
||||
thread_pool.wait();
|
||||
}
|
||||
|
||||
void DatabaseOrdinary::loadDictionaries(Context & context)
|
||||
{
|
||||
LOG_INFO(log, "Loading dictionaries.");
|
||||
|
||||
auto dictionaries_repository = std::make_unique<ExternalLoaderDatabaseConfigRepository>(shared_from_this(), context);
|
||||
context.getExternalDictionariesLoader().addConfigRepository(
|
||||
getDatabaseName(), std::move(dictionaries_repository), {"dictionary", "name"});
|
||||
}
|
||||
|
||||
|
||||
void DatabaseOrdinary::createTable(
|
||||
const Context & context,
|
||||
const String & table_name,
|
||||
|
@ -91,7 +91,6 @@ private:
|
||||
Poco::Logger * log;
|
||||
|
||||
void startupTables(ThreadPool & thread_pool);
|
||||
void loadDictionaries(Context & context);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <Databases/DatabasesCommon.h>
|
||||
|
||||
#include <Interpreters/ExternalDictionariesLoader.h>
|
||||
#include <Interpreters/ExternalLoaderDatabaseConfigRepository.h>
|
||||
#include <Interpreters/Context.h>
|
||||
#include <Interpreters/InterpreterCreateQuery.h>
|
||||
#include <Parsers/ASTCreateQuery.h>
|
||||
@ -102,13 +104,17 @@ StoragePtr DatabaseWithOwnTablesBase::detachTable(const String & table_name)
|
||||
return res;
|
||||
}
|
||||
|
||||
void DatabaseWithOwnTablesBase::detachDictionary(const String & dictionary_name)
|
||||
void DatabaseWithOwnTablesBase::detachDictionary(const String & dictionary_name, const Context & context)
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = dictionaries.find(dictionary_name);
|
||||
if (it == dictionaries.end())
|
||||
throw Exception("Dictionary " + name + "." + dictionary_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
||||
dictionaries.erase(it);
|
||||
}
|
||||
|
||||
context.getExternalDictionariesLoader().reload(getDatabaseName() + "." + dictionary_name, true);
|
||||
|
||||
}
|
||||
|
||||
@ -120,13 +126,21 @@ void DatabaseWithOwnTablesBase::attachTable(const String & table_name, const Sto
|
||||
}
|
||||
|
||||
|
||||
void DatabaseWithOwnTablesBase::attachDictionary(const String & dictionary_name)
|
||||
void DatabaseWithOwnTablesBase::attachDictionary(const String & dictionary_name, const Context & context, bool load)
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
if (!dictionaries.emplace(dictionary_name).second)
|
||||
throw Exception("Dictionary " + name + "." + dictionary_name + " already exists.", ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
if (load)
|
||||
{
|
||||
bool lazy_load = context.getConfigRef().getBool("dictionaries_lazy_load", true);
|
||||
context.getExternalDictionariesLoader().reload(getDatabaseName() + "." + dictionary_name, !lazy_load);
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWithOwnTablesBase::shutdown()
|
||||
{
|
||||
/// You can not hold a lock during shutdown.
|
||||
|
@ -33,11 +33,11 @@ public:
|
||||
|
||||
void attachTable(const String & table_name, const StoragePtr & table) override;
|
||||
|
||||
void attachDictionary(const String & name) override;
|
||||
void attachDictionary(const String & name, const Context & context, bool load) override;
|
||||
|
||||
StoragePtr detachTable(const String & table_name) override;
|
||||
|
||||
void detachDictionary(const String & name) override;
|
||||
void detachDictionary(const String & name, const Context & context) override;
|
||||
|
||||
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
||||
|
||||
|
@ -159,13 +159,13 @@ public:
|
||||
virtual void attachTable(const String & name, const StoragePtr & table) = 0;
|
||||
|
||||
/// Add dictionary to the database, but do not add it to the metadata. The database may not support this method.
|
||||
virtual void attachDictionary(const String & name) = 0;
|
||||
virtual void attachDictionary(const String & name, const Context & context, bool load=true) = 0;
|
||||
|
||||
/// Forget about the table without deleting it, and return it. The database may not support this method.
|
||||
virtual StoragePtr detachTable(const String & name) = 0;
|
||||
|
||||
/// Forget about the dictionary without deleting it, and return it. The database may not support this method.
|
||||
virtual void detachDictionary(const String & name) = 0;
|
||||
virtual void detachDictionary(const String & name, const Context & context) = 0;
|
||||
|
||||
/// Rename the table and possibly move the table to another database.
|
||||
virtual void renameTable(
|
||||
|
@ -131,14 +131,14 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<String> deleted_files;
|
||||
std::vector<String> deleted_names;
|
||||
for (auto & [path, loadable_info] : loadables_infos)
|
||||
if (!loadable_info.in_use)
|
||||
deleted_files.emplace_back(path);
|
||||
if (!deleted_files.empty())
|
||||
deleted_names.emplace_back(path);
|
||||
if (!deleted_names.empty())
|
||||
{
|
||||
for (const String & deleted_file : deleted_files)
|
||||
loadables_infos.erase(deleted_file);
|
||||
for (const String & deleted_name : deleted_names)
|
||||
loadables_infos.erase(deleted_name);
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
|
@ -729,7 +729,7 @@ BlockIO InterpreterCreateQuery::createDictionary(ASTCreateQuery & create)
|
||||
}
|
||||
|
||||
if (create.attach)
|
||||
database->attachDictionary(dictionary_name);
|
||||
database->attachDictionary(dictionary_name, context);
|
||||
else
|
||||
database->createDictionary(context, dictionary_name, query_ptr);
|
||||
|
||||
|
@ -179,7 +179,7 @@ BlockIO InterpreterDropQuery::executeToDictionary(
|
||||
if (kind == ASTDropQuery::Kind::Detach)
|
||||
{
|
||||
/// Drop dictionary from memory, don't touch data and metadata
|
||||
database->detachDictionary(dictionary_name);
|
||||
database->detachDictionary(dictionary_name, context);
|
||||
}
|
||||
else if (kind == ASTDropQuery::Kind::Truncate)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user