mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-28 02:21:59 +00:00
add symlinks
This commit is contained in:
parent
58067438cd
commit
03ed9d59b0
@ -29,7 +29,9 @@ public:
|
|||||||
|
|
||||||
DatabaseAtomic::DatabaseAtomic(String name_, String metadata_path_, Context & context_)
|
DatabaseAtomic::DatabaseAtomic(String name_, String metadata_path_, Context & context_)
|
||||||
: DatabaseOrdinary(name_, metadata_path_, "store/", "DatabaseAtomic (" + name_ + ")", context_)
|
: DatabaseOrdinary(name_, metadata_path_, "store/", "DatabaseAtomic (" + name_ + ")", context_)
|
||||||
|
, path_to_table_symlinks(context_.getPath() + "data/" + escapeForFileName(name_) + "/")
|
||||||
{
|
{
|
||||||
|
Poco::File(path_to_table_symlinks).createDirectories();
|
||||||
}
|
}
|
||||||
|
|
||||||
String DatabaseAtomic::getTableDataPath(const String & table_name) const
|
String DatabaseAtomic::getTableDataPath(const String & table_name) const
|
||||||
@ -52,6 +54,7 @@ String DatabaseAtomic::getTableDataPath(const ASTCreateQuery & query) const
|
|||||||
|
|
||||||
void DatabaseAtomic::drop(const Context &)
|
void DatabaseAtomic::drop(const Context &)
|
||||||
{
|
{
|
||||||
|
Poco::File(path_to_table_symlinks).remove(true);
|
||||||
Poco::File(getMetadataPath()).remove(true);
|
Poco::File(getMetadataPath()).remove(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +67,7 @@ void DatabaseAtomic::attachTable(const String & name, const StoragePtr & table,
|
|||||||
assertDetachedTableNotInUse(table->getStorageID().uuid);
|
assertDetachedTableNotInUse(table->getStorageID().uuid);
|
||||||
DatabaseWithDictionaries::attachTableUnlocked(name, table, relative_table_path);
|
DatabaseWithDictionaries::attachTableUnlocked(name, table, relative_table_path);
|
||||||
table_name_to_path.emplace(std::make_pair(name, relative_table_path));
|
table_name_to_path.emplace(std::make_pair(name, relative_table_path));
|
||||||
|
tryCreateSymlink(name, relative_table_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePtr DatabaseAtomic::detachTable(const String & name)
|
StoragePtr DatabaseAtomic::detachTable(const String & name)
|
||||||
@ -74,6 +78,7 @@ StoragePtr DatabaseAtomic::detachTable(const String & name)
|
|||||||
table_name_to_path.erase(name);
|
table_name_to_path.erase(name);
|
||||||
detached_tables.emplace(table->getStorageID().uuid, table);
|
detached_tables.emplace(table->getStorageID().uuid, table);
|
||||||
not_in_use = cleenupDetachedTables();
|
not_in_use = cleenupDetachedTables();
|
||||||
|
tryRemoveSymlink(name);
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +95,7 @@ void DatabaseAtomic::dropTable(const Context &, const String & table_name, bool
|
|||||||
DatabaseWithDictionaries::detachTableUnlocked(table_name); /// Should never throw
|
DatabaseWithDictionaries::detachTableUnlocked(table_name); /// Should never throw
|
||||||
table_name_to_path.erase(table_name);
|
table_name_to_path.erase(table_name);
|
||||||
}
|
}
|
||||||
|
tryRemoveSymlink(table_name);
|
||||||
DatabaseCatalog::instance().enqueueDroppedTableCleanup(table->getStorageID(), table, table_metadata_path_drop, no_delay);
|
DatabaseCatalog::instance().enqueueDroppedTableCleanup(table->getStorageID(), table, table_metadata_path_drop, no_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,31 +112,23 @@ void DatabaseAtomic::renameTable(const Context & context, const String & table_n
|
|||||||
}
|
}
|
||||||
auto & other_db = dynamic_cast<DatabaseAtomic &>(to_database);
|
auto & other_db = dynamic_cast<DatabaseAtomic &>(to_database);
|
||||||
|
|
||||||
StoragePtr table = tryGetTable(context, table_name);
|
|
||||||
StoragePtr other_table;
|
|
||||||
if (exchange)
|
|
||||||
other_table = other_db.tryGetTable(context, to_table_name);
|
|
||||||
|
|
||||||
if (!table)
|
|
||||||
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
|
||||||
if (exchange && !other_table)
|
|
||||||
throw Exception("Table " + backQuote(other_db.getDatabaseName()) + "." + backQuote(to_table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
|
||||||
|
|
||||||
String old_metadata_path = getObjectMetadataPath(table_name);
|
String old_metadata_path = getObjectMetadataPath(table_name);
|
||||||
String new_metadata_path = to_database.getObjectMetadataPath(to_table_name);
|
String new_metadata_path = to_database.getObjectMetadataPath(to_table_name);
|
||||||
|
|
||||||
auto detach = [](DatabaseAtomic & db, const String & table_name_)
|
auto detach = [this](DatabaseAtomic & db, const String & table_name_)
|
||||||
{
|
{
|
||||||
auto table_data_path_saved = db.table_name_to_path.find(table_name_)->second;
|
auto table_data_path_saved = db.table_name_to_path.find(table_name_)->second;
|
||||||
db.tables.erase(table_name_);
|
db.tables.erase(table_name_);
|
||||||
db.table_name_to_path.erase(table_name_);
|
db.table_name_to_path.erase(table_name_);
|
||||||
|
tryRemoveSymlink(table_name_);
|
||||||
return table_data_path_saved;
|
return table_data_path_saved;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto attach = [](DatabaseAtomic & db, const String & table_name_, const String & table_data_path_, const StoragePtr & table_)
|
auto attach = [this](DatabaseAtomic & db, const String & table_name_, const String & table_data_path_, const StoragePtr & table_)
|
||||||
{
|
{
|
||||||
db.tables.emplace(table_name_, table_);
|
db.tables.emplace(table_name_, table_);
|
||||||
db.table_name_to_path.emplace(table_name_, table_data_path_);
|
db.table_name_to_path.emplace(table_name_, table_data_path_);
|
||||||
|
tryCreateSymlink(table_name_, table_data_path_);
|
||||||
};
|
};
|
||||||
|
|
||||||
String table_data_path;
|
String table_data_path;
|
||||||
@ -155,6 +153,11 @@ void DatabaseAtomic::renameTable(const Context & context, const String & table_n
|
|||||||
db_lock = std::unique_lock{mutex};
|
db_lock = std::unique_lock{mutex};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StoragePtr table = getTableUnlocked(table_name);
|
||||||
|
StoragePtr other_table;
|
||||||
|
if (exchange)
|
||||||
|
other_table = other_db.getTableUnlocked(to_table_name);
|
||||||
|
|
||||||
if (exchange)
|
if (exchange)
|
||||||
renameExchange(old_metadata_path, new_metadata_path);
|
renameExchange(old_metadata_path, new_metadata_path);
|
||||||
else
|
else
|
||||||
@ -199,7 +202,7 @@ void DatabaseAtomic::commitCreateTable(const ASTCreateQuery & query, const Stora
|
|||||||
Poco::File(table_metadata_tmp_path).remove();
|
Poco::File(table_metadata_tmp_path).remove();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
tryCreateSymlink(query.table, table_data_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseAtomic::commitAlterTable(const StorageID & table_id, const String & table_metadata_tmp_path, const String & table_metadata_path)
|
void DatabaseAtomic::commitAlterTable(const StorageID & table_id, const String & table_metadata_tmp_path, const String & table_metadata_path)
|
||||||
@ -251,5 +254,52 @@ DatabaseTablesIteratorPtr DatabaseAtomic::getTablesWithDictionaryTablesIterator(
|
|||||||
return std::make_unique<AtomicDatabaseTablesSnapshotIterator>(std::move(typeid_cast<DatabaseTablesSnapshotIterator &>(*base_iter)));
|
return std::make_unique<AtomicDatabaseTablesSnapshotIterator>(std::move(typeid_cast<DatabaseTablesSnapshotIterator &>(*base_iter)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseAtomic::loadStoredObjects(Context & context, bool has_force_restore_data_flag)
|
||||||
|
{
|
||||||
|
/// Recreate symlinks to table data dirs in case of force restore, because some of them may be broken
|
||||||
|
if (has_force_restore_data_flag)
|
||||||
|
Poco::File(path_to_table_symlinks).remove(true);
|
||||||
|
|
||||||
|
DatabaseOrdinary::loadStoredObjects(context, has_force_restore_data_flag);
|
||||||
|
|
||||||
|
if (has_force_restore_data_flag)
|
||||||
|
{
|
||||||
|
NameToPathMap table_names;
|
||||||
|
{
|
||||||
|
std::lock_guard lock{mutex};
|
||||||
|
table_names = table_name_to_path;
|
||||||
|
}
|
||||||
|
for (const auto & table : table_names)
|
||||||
|
tryCreateSymlink(table.first, table.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseAtomic::tryCreateSymlink(const String & table_name, const String & actual_data_path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String link = path_to_table_symlinks + escapeForFileName(table_name);
|
||||||
|
String data = global_context.getPath() + actual_data_path;
|
||||||
|
Poco::File{data}.linkTo(link, Poco::File::LINK_SYMBOLIC);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
tryLogCurrentException(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseAtomic::tryRemoveSymlink(const String & table_name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String path = path_to_table_symlinks + escapeForFileName(table_name);
|
||||||
|
Poco::File{path}.remove();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
tryLogCurrentException(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,19 +36,26 @@ public:
|
|||||||
DatabaseTablesIteratorPtr getTablesIterator(const FilterByNameFunction & filter_by_table_name) override;
|
DatabaseTablesIteratorPtr getTablesIterator(const FilterByNameFunction & filter_by_table_name) override;
|
||||||
DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const FilterByNameFunction & filter_by_dictionary_name) override;
|
DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const FilterByNameFunction & filter_by_dictionary_name) override;
|
||||||
|
|
||||||
|
void loadStoredObjects(Context & context, bool has_force_restore_data_flag) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void commitAlterTable(const StorageID & table_id, const String & table_metadata_tmp_path, const String & table_metadata_path) override;
|
void commitAlterTable(const StorageID & table_id, const String & table_metadata_tmp_path, const String & table_metadata_path) override;
|
||||||
void commitCreateTable(const ASTCreateQuery & query, const StoragePtr & table,
|
void commitCreateTable(const ASTCreateQuery & query, const StoragePtr & table,
|
||||||
const String & table_metadata_tmp_path, const String & table_metadata_path) override;
|
const String & table_metadata_tmp_path, const String & table_metadata_path) override;
|
||||||
|
|
||||||
void assertDetachedTableNotInUse(const UUID & uuid);
|
void assertDetachedTableNotInUse(const UUID & uuid);
|
||||||
typedef std::map<UUID, StoragePtr> DetachedTables;
|
typedef std::unordered_map<UUID, StoragePtr> DetachedTables;
|
||||||
DetachedTables cleenupDetachedTables();
|
DetachedTables cleenupDetachedTables();
|
||||||
|
|
||||||
|
void tryCreateSymlink(const String & table_name, const String & actual_data_path);
|
||||||
|
void tryRemoveSymlink(const String & table_name);
|
||||||
|
|
||||||
//TODO store path in DatabaseWithOwnTables::tables
|
//TODO store path in DatabaseWithOwnTables::tables
|
||||||
std::map<String, String> table_name_to_path;
|
typedef std::unordered_map<String, String> NameToPathMap;
|
||||||
|
NameToPathMap table_name_to_path;
|
||||||
|
|
||||||
DetachedTables detached_tables;
|
DetachedTables detached_tables;
|
||||||
|
const String path_to_table_symlinks;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user