fix, add test

This commit is contained in:
Alexander Tokmakov 2020-07-08 17:28:07 +03:00
parent 7a5d532c7b
commit 9c4efa1f36
12 changed files with 129 additions and 48 deletions

View File

@ -114,7 +114,7 @@ void ClusterCopierApp::mainImpl()
registerDisks();
static const std::string default_database = "_local";
DatabaseCatalog::instance().attachDatabase(default_database, UUIDHelpers::Nil, std::make_shared<DatabaseMemory>(default_database, *context));
DatabaseCatalog::instance().attachDatabase(default_database, std::make_shared<DatabaseMemory>(default_database, *context));
context->setCurrentDatabase(default_database);
/// Initialize query scope just in case.

View File

@ -164,7 +164,7 @@ static void attachSystemTables(const Context & context)
{
/// TODO: add attachTableDelayed into DatabaseMemory to speedup loading
system_database = std::make_shared<DatabaseMemory>(DatabaseCatalog::SYSTEM_DATABASE, context);
DatabaseCatalog::instance().attachDatabase(DatabaseCatalog::SYSTEM_DATABASE, UUIDHelpers::Nil, system_database);
DatabaseCatalog::instance().attachDatabase(DatabaseCatalog::SYSTEM_DATABASE, system_database);
}
attachSystemTablesLocal(*system_database);
@ -241,7 +241,7 @@ try
* if such tables will not be dropped, clickhouse-server will not be able to load them due to security reasons.
*/
std::string default_database = config().getString("default_database", "_local");
DatabaseCatalog::instance().attachDatabase(default_database, UUIDHelpers::Nil, std::make_shared<DatabaseMemory>(default_database, *context));
DatabaseCatalog::instance().attachDatabase(default_database, std::make_shared<DatabaseMemory>(default_database, *context));
context->setCurrentDatabase(default_database);
applyCmdOptions();

View File

@ -389,6 +389,7 @@ void DatabaseAtomic::tryCreateMetadataSymlink()
void DatabaseAtomic::renameDatabase(const String & new_name)
{
/// CREATE, ATTACH, DROP, DETACH and RENAME DATABASE must hold DDLGuard
try
{
Poco::File(path_to_metadata_symlink).remove();
@ -398,8 +399,16 @@ void DatabaseAtomic::renameDatabase(const String & new_name)
LOG_WARNING(log, getCurrentExceptionMessage(true));
}
auto new_name_escaped = escapeForFileName(new_name);
auto old_database_metadata_path = global_context.getPath() + "metadata/" + escapeForFileName(getDatabaseName()) + ".sql";
auto new_database_metadata_path = global_context.getPath() + "metadata/" + new_name_escaped + ".sql";
renameNoReplace(old_database_metadata_path, new_database_metadata_path);
String old_path_to_table_symlinks;
{
std::lock_guard lock(mutex);
DatabaseCatalog::instance().updateDatabaseName(database_name, new_name);
database_name = new_name;
for (auto & table : tables)
@ -409,12 +418,12 @@ void DatabaseAtomic::renameDatabase(const String & new_name)
table.second->renameInMemory(table_id);
}
path_to_metadata_symlink = global_context.getPath() + "metadata/" + escapeForFileName(database_name);
String old_path_to_table_symlinks = path_to_table_symlinks;
path_to_table_symlinks = global_context.getPath() + "data/" + escapeForFileName(database_name) + "/";
Poco::File(old_path_to_table_symlinks).renameTo(path_to_table_symlinks);
path_to_metadata_symlink = global_context.getPath() + "metadata/" + new_name_escaped;
old_path_to_table_symlinks = path_to_table_symlinks;
path_to_table_symlinks = global_context.getPath() + "data/" + new_name_escaped + "/";
}
Poco::File(old_path_to_table_symlinks).renameTo(path_to_table_symlinks);
tryCreateMetadataSymlink();
}

View File

@ -115,7 +115,7 @@ void DatabaseCatalog::loadDatabases()
drop_delay_sec = global_context->getConfigRef().getInt("database_atomic_delay_before_drop_table_sec", default_drop_delay_sec);
auto db_for_temporary_and_external_tables = std::make_shared<DatabaseMemory>(TEMPORARY_DATABASE, *global_context);
attachDatabase(TEMPORARY_DATABASE, UUIDHelpers::Nil, db_for_temporary_and_external_tables);
attachDatabase(TEMPORARY_DATABASE, db_for_temporary_and_external_tables);
loadMarkedAsDroppedTables();
auto task_holder = global_context->getSchedulePool().createTask("DatabaseCatalog", [this](){ this->dropTableDataTask(); });
@ -248,13 +248,15 @@ void DatabaseCatalog::assertDatabaseDoesntExistUnlocked(const String & database_
throw Exception("Database " + backQuoteIfNeed(database_name) + " already exists.", ErrorCodes::DATABASE_ALREADY_EXISTS);
}
void DatabaseCatalog::attachDatabase(const String & database_name, const UUID & uuid, const DatabasePtr & database)
void DatabaseCatalog::attachDatabase(const String & database_name, const DatabasePtr & database)
{
std::lock_guard lock{databases_mutex};
assertDatabaseDoesntExistUnlocked(database_name);
databases.emplace(database_name, database);
if (uuid != UUIDHelpers::Nil)
db_uuid_map.emplace(uuid, database);
UUID db_uuid = database->getUUID();
assert((db_uuid != UUIDHelpers::Nil) ^ (dynamic_cast<DatabaseAtomic *>(database.get()) == nullptr));
if (db_uuid != UUIDHelpers::Nil)
db_uuid_map.emplace(db_uuid, database);
}
@ -263,13 +265,18 @@ DatabasePtr DatabaseCatalog::detachDatabase(const String & database_name, bool d
if (database_name == TEMPORARY_DATABASE)
throw Exception("Cannot detach database with temporary tables.", ErrorCodes::DATABASE_ACCESS_DENIED);
std::shared_ptr<IDatabase> db;
DatabasePtr db;
{
std::lock_guard lock{databases_mutex};
assertDatabaseExistsUnlocked(database_name);
db = databases.find(database_name)->second;
db_uuid_map.erase(db->getUUID());
databases.erase(database_name);
}
if (check_empty)
if (check_empty)
{
try
{
if (!db->empty())
throw Exception("New table appeared in database being dropped or detached. Try again.",
@ -278,9 +285,11 @@ DatabasePtr DatabaseCatalog::detachDatabase(const String & database_name, bool d
if (!drop && database_atomic)
database_atomic->assertCanBeDetached(false);
}
db_uuid_map.erase(db->getUUID());
databases.erase(database_name);
catch (...)
{
attachDatabase(database_name, db);
throw;
}
}
db->shutdown();
@ -300,36 +309,15 @@ DatabasePtr DatabaseCatalog::detachDatabase(const String & database_name, bool d
return db;
}
void DatabaseCatalog::renameDatabase(const String & old_name, const String & new_name)
void DatabaseCatalog::updateDatabaseName(const String & old_name, const String & new_name)
{
std::lock_guard lock{databases_mutex};
assertDatabaseExistsUnlocked(old_name);
assertDatabaseDoesntExistUnlocked(new_name);
assert(databases.find(new_name) == databases.end());
auto it = databases.find(old_name);
assert(it != databases.end());
auto db = it->second;
db->renameDatabase(new_name);
databases.erase(it);
databases.emplace(new_name, db);
auto depend_it = view_dependencies.begin();
while (depend_it != view_dependencies.end())
{
if (depend_it->first.database_name == old_name)
{
auto table_id = depend_it->first;
auto dependencies = std::move(depend_it->second);
depend_it = view_dependencies.erase(depend_it);
table_id.database_name = new_name;
view_dependencies.emplace(std::move(table_id), std::move(dependencies));
}
else
++depend_it;
}
auto old_database_metadata_path = global_context->getPath() + "metadata/" + escapeForFileName(old_name) + ".sql";
auto new_database_metadata_path = global_context->getPath() + "metadata/" + escapeForFileName(new_name) + ".sql";
renameNoReplace(old_database_metadata_path, new_database_metadata_path);
}
DatabasePtr DatabaseCatalog::getDatabase(const String & database_name) const

View File

@ -121,9 +121,9 @@ public:
DatabasePtr getDatabaseForTemporaryTables() const;
DatabasePtr getSystemDatabase() const;
void attachDatabase(const String & database_name, const UUID & uuid, const DatabasePtr & database);
void attachDatabase(const String & database_name, const DatabasePtr & database);
DatabasePtr detachDatabase(const String & database_name, bool drop = false, bool check_empty = true);
void renameDatabase(const String & old_name, const String & new_name);
void updateDatabaseName(const String & old_name, const String & new_name);
/// database_name must be not empty
DatabasePtr getDatabase(const String & database_name) const;

View File

@ -197,7 +197,7 @@ BlockIO InterpreterCreateQuery::createDatabase(ASTCreateQuery & create)
try
{
/// TODO Attach db only after it was loaded. Now it's not possible because of view dependencies
DatabaseCatalog::instance().attachDatabase(database_name, create.uuid, database);
DatabaseCatalog::instance().attachDatabase(database_name, database);
added = true;
if (need_write_metadata)

View File

@ -5,7 +5,6 @@
#include <Storages/IStorage.h>
#include <Interpreters/DDLWorker.h>
#include <Access/AccessRightsElement.h>
#include <Common/typeid_cast.h>
namespace DB
@ -89,9 +88,14 @@ BlockIO InterpreterRenameQuery::executeToDatabase(const ASTRenameQuery &, const
assert(descriptions.size() == 1);
assert(descriptions.front().from_table_name.empty());
assert(descriptions.front().to_table_name.empty());
const auto & old_name = descriptions.front().from_database_name;
const auto & new_name = descriptions.back().to_database_name;
DatabaseCatalog::instance().renameDatabase(old_name, new_name);
auto & catalog = DatabaseCatalog::instance();
auto db = catalog.getDatabase(old_name);
catalog.assertDatabaseDoesntExist(new_name);
db->renameDatabase(new_name);
return {};
}

View File

@ -156,7 +156,7 @@ void loadMetadataSystem(Context & context)
Poco::File(global_path + "metadata/" SYSTEM_DATABASE).createDirectories();
auto system_database = std::make_shared<DatabaseOrdinary>(SYSTEM_DATABASE, global_path + "metadata/" SYSTEM_DATABASE "/", context);
DatabaseCatalog::instance().attachDatabase(SYSTEM_DATABASE, UUIDHelpers::Nil, system_database);
DatabaseCatalog::instance().attachDatabase(SYSTEM_DATABASE, system_database);
}
}

View File

@ -1167,7 +1167,7 @@ TestResult check(const TestEntry & entry)
auto storage_distributed_hits = StorageDistributedFake::create("distant_db", "distant_hits", entry.shard_count);
DB::DatabasePtr database = std::make_shared<DB::DatabaseOrdinary>("test", "./metadata/test/", context);
DB::DatabaseCatalog::instance().attachDatabase("test", UUIDHelpers::Nil, database);
DB::DatabaseCatalog::instance().attachDatabase("test", database);
database->attachTable("visits_all", storage_distributed_visits);
database->attachTable("hits_all", storage_distributed_hits);
context.setCurrentDatabase("test");

View File

@ -42,7 +42,7 @@ private:
registerFunctions();
DatabasePtr database = std::make_shared<DatabaseMemory>("test", context);
database->attachTable("table", StorageMemory::create(StorageID("test", "table"), ColumnsDescription{columns}, ConstraintsDescription{}));
DatabaseCatalog::instance().attachDatabase("test", UUIDHelpers::Nil, database);
DatabaseCatalog::instance().attachDatabase("test", database);
context.setCurrentDatabase("test");
}
};

View File

@ -0,0 +1,22 @@
ok
CREATE DATABASE test_01192 UUID \'00001192-0000-4000-8000-000000000001\'\nENGINE = Atomic
Atomic store 00001192-0000-4000-8000-000000000001 00001192-0000-4000-8000-000000000001
ok
ok
renamed
inserted
CREATE DATABASE test_01192_renamed UUID \'00001192-0000-4000-8000-000000000001\'\nENGINE = Atomic
Atomic store 00001192-0000-4000-8000-000000000001 00001192-0000-4000-8000-000000000001
CREATE DATABASE test_01192_renamed\nENGINE = Atomic
10 45
inserted
renamed
10 45
10 45
ok
ok
renamed
inserted
20 190
10 45
10 45

View File

@ -0,0 +1,58 @@
#!/usr/bin/env bash
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
. $CURDIR/../shell_config.sh
$CLICKHOUSE_CLIENT -q "DROP DATABASE IF EXISTS test_01192"
$CLICKHOUSE_CLIENT -q "DROP DATABASE IF EXISTS test_01192_renamed"
$CLICKHOUSE_CLIENT -q "DROP DATABASE IF EXISTS test_01192_atomic"
$CLICKHOUSE_CLIENT --default_database_engine=Ordinary -q "CREATE DATABASE test_01192 UUID '00001192-0000-4000-8000-000000000001'" 2>&1| grep -F "does not support" > /dev/null && echo "ok"
$CLICKHOUSE_CLIENT --allow_experimental_database_atomic=1 --default_database_engine=Atomic -q "CREATE DATABASE test_01192 UUID '00001192-0000-4000-8000-000000000001'"
$CLICKHOUSE_CLIENT --show_table_uuid_in_table_create_query_if_not_nil=1 -q "SHOW CREATE DATABASE test_01192"
$CLICKHOUSE_CLIENT -q "SELECT engine, splitByChar('/', data_path)[-2], uuid, splitByChar('/', metadata_path)[-2] FROM system.databases WHERE name='test_01192'"
$CLICKHOUSE_CLIENT -q "CREATE TABLE test_01192.mt (n UInt64) ENGINE=MergeTree ORDER BY n"
$CLICKHOUSE_CLIENT -q "INSERT INTO test_01192.mt SELECT number + sleepEachRow(1) FROM numbers(10)" && echo "inserted" &
sleep 1
$CLICKHOUSE_CLIENT -q "RENAME DATABASE test_01192 TO default" 2>&1| grep -F "already exists" > /dev/null && echo "ok"
$CLICKHOUSE_CLIENT -q "RENAME DATABASE test_01192_notexisting TO test_01192_renamed" 2>&1| grep -F "doesn't exist" > /dev/null && echo "ok"
$CLICKHOUSE_CLIENT -q "RENAME DATABASE test_01192 TO test_01192_renamed" && echo "renamed"
wait
$CLICKHOUSE_CLIENT --show_table_uuid_in_table_create_query_if_not_nil=1 -q "SHOW CREATE DATABASE test_01192_renamed"
$CLICKHOUSE_CLIENT -q "SELECT engine, splitByChar('/', data_path)[-2], uuid, splitByChar('/', metadata_path)[-2] FROM system.databases WHERE name='test_01192_renamed'"
$CLICKHOUSE_CLIENT -q "SHOW CREATE DATABASE test_01192_renamed"
$CLICKHOUSE_CLIENT -q "SELECT count(n), sum(n) FROM test_01192_renamed.mt"
$CLICKHOUSE_CLIENT --default_database_engine=Ordinary -q "CREATE DATABASE test_01192"
$CLICKHOUSE_CLIENT -q "CREATE TABLE test_01192.mt AS test_01192_renamed.mt ENGINE=MergeTree ORDER BY n"
$CLICKHOUSE_CLIENT -q "CREATE TABLE test_01192.rmt AS test_01192_renamed.mt ENGINE=ReplicatedMergeTree('/test/01192/', '1') ORDER BY n"
$CLICKHOUSE_CLIENT -q "CREATE MATERIALIZED VIEW test_01192.mv TO test_01192.rmt AS SELECT * FROM test_01192.mt"
$CLICKHOUSE_CLIENT -q "INSERT INTO test_01192.mt SELECT number FROM numbers(10)" && echo "inserted"
$CLICKHOUSE_CLIENT --allow_experimental_database_atomic=1 --default_database_engine=Atomic -q "CREATE DATABASE test_01192_atomic"
$CLICKHOUSE_CLIENT -q "DROP DATABASE test_01192_renamed"
$CLICKHOUSE_CLIENT -q "RENAME TABLE test_01192.mt TO test_01192_atomic.mt, test_01192.rmt TO test_01192_atomic.rmt, test_01192.mv TO test_01192_atomic.mv" && echo "renamed"
$CLICKHOUSE_CLIENT -q "SELECT count(n), sum(n) FROM test_01192_atomic.mt"
$CLICKHOUSE_CLIENT -q "SELECT count(n), sum(n) FROM test_01192_atomic.rmt"
$CLICKHOUSE_CLIENT -q "SELECT count(n), sum(n) FROM test_01192_atomic.mv" 2>&1| grep -F "doesn't exist" > /dev/null && echo "ok"
$CLICKHOUSE_CLIENT -q "INSERT INTO test_01192_atomic.mt SELECT number + sleepEachRow(1) + 10 FROM numbers(10)" && echo "inserted" &
sleep 1
$CLICKHOUSE_CLIENT -q "RENAME DATABASE test_01192 TO test_01192_renamed" 2>&1| grep -F "not supported" > /dev/null && echo "ok"
$CLICKHOUSE_CLIENT -q "DROP DATABASE test_01192"
$CLICKHOUSE_CLIENT -q "RENAME DATABASE test_01192_atomic TO test_01192" && echo "renamed"
wait
$CLICKHOUSE_CLIENT -q "SELECT count(n), sum(n) FROM test_01192.mt"
$CLICKHOUSE_CLIENT -q "SELECT count(n), sum(n) FROM test_01192.rmt"
$CLICKHOUSE_CLIENT -q "SELECT count(n), sum(n) FROM test_01192.mv"
$CLICKHOUSE_CLIENT -q "DROP DATABASE test_01192"