mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
rewrite static StorageReplicatedMergeTree::dropReplica
This commit is contained in:
parent
7723dc4935
commit
0101947403
@ -405,6 +405,9 @@ void InterpreterSystemQuery::restartReplicas(Context & system_context)
|
||||
|
||||
void InterpreterSystemQuery::dropReplica(ASTSystemQuery & query)
|
||||
{
|
||||
StorageReplicatedMergeTree::Status status;
|
||||
auto zookeeper = context.getZooKeeper();
|
||||
|
||||
if (!table_id.empty())
|
||||
{
|
||||
context.checkAccess(AccessType::SYSTEM_DROP_REPLICA, table_id);
|
||||
@ -412,7 +415,10 @@ void InterpreterSystemQuery::dropReplica(ASTSystemQuery & query)
|
||||
|
||||
if (auto * storage_replicated = dynamic_cast<StorageReplicatedMergeTree *>(table.get()))
|
||||
{
|
||||
storage_replicated->dropReplica(query.replica, false);
|
||||
storage_replicated->getStatus(status);
|
||||
if (query.replica == status.replica_name)
|
||||
throw Exception("We can't drop local replica, please use `DROP TABLE` if you want to clean the data and drop this replica", ErrorCodes::LOGICAL_ERROR);
|
||||
storage_replicated->dropReplica(zookeeper, status.zookeeper_path, query.replica, status.is_readonly ,false);
|
||||
LOG_TRACE(log, "DROP REPLICA " + table_id.getNameForLogs() + " [" + query.replica + "]: OK");
|
||||
}
|
||||
else
|
||||
@ -428,7 +434,10 @@ void InterpreterSystemQuery::dropReplica(ASTSystemQuery & query)
|
||||
if (auto * storage_replicated = dynamic_cast<StorageReplicatedMergeTree *>(iterator->table().get()))
|
||||
{
|
||||
context.checkAccess(AccessType::SYSTEM_DROP_REPLICA, iterator->table()->getStorageID());
|
||||
storage_replicated->dropReplica(query.replica, false);
|
||||
storage_replicated->getStatus(status);
|
||||
if (query.replica == status.replica_name)
|
||||
throw Exception("We can't drop local replica, please use `DROP TABLE` if you want to clean the data and drop this replica", ErrorCodes::LOGICAL_ERROR);
|
||||
storage_replicated->dropReplica(zookeeper, status.zookeeper_path, query.replica, status.is_readonly ,false);
|
||||
}
|
||||
}
|
||||
LOG_TRACE(log, "DROP REPLICA " + query.replica + " DATABSE " + database->getDatabaseName() + ": OK");
|
||||
@ -438,7 +447,36 @@ void InterpreterSystemQuery::dropReplica(ASTSystemQuery & query)
|
||||
}
|
||||
else if (!query.replica_zk_path.empty())
|
||||
{
|
||||
StorageReplicatedMergeTree::dropReplicaByZkPath(context, query.replica_zk_path, query.replica);
|
||||
auto remote_replica_path = query.replica_zk_path + "/replicas/" + query.replica;
|
||||
auto & catalog = DatabaseCatalog::instance();
|
||||
|
||||
for (auto & elem : catalog.getDatabases())
|
||||
{
|
||||
DatabasePtr & database = elem.second;
|
||||
for (auto iterator = database->getTablesIterator(context); iterator->isValid(); iterator->next())
|
||||
{
|
||||
if (auto * storage_replicated = dynamic_cast<StorageReplicatedMergeTree *>(iterator->table().get()))
|
||||
{
|
||||
storage_replicated->getStatus(status);
|
||||
if (status.replica_path.compare(remote_replica_path) == 0)
|
||||
throw Exception("We can't drop local replica, please use `DROP TABLE` if you want to clean the data and drop this replica",
|
||||
ErrorCodes::LOGICAL_ERROR);
|
||||
if (status.replica_path.compare(query.replica_zk_path + "/replicas/" + status.replica_name) == 0)
|
||||
{
|
||||
storage_replicated->dropReplica(zookeeper, query.replica_zk_path, query.replica, status.is_readonly ,false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// It may left some garbage if replica_path subtree are concurently modified
|
||||
/// check if is active replica if we drop other replicas
|
||||
if (zookeeper->exists(remote_replica_path + "/is_active"))
|
||||
throw Exception("Can't remove replica: " + query.replica + ", because it's active",
|
||||
ErrorCodes::LOGICAL_ERROR);
|
||||
|
||||
zookeeper->tryRemoveRecursive(remote_replica_path);
|
||||
LOG_INFO(log, "Removing replica {}", query.replica_zk_path + "/replicas/" + query.replica);
|
||||
}
|
||||
else if (query.is_drop_whole_replica)
|
||||
@ -453,7 +491,10 @@ void InterpreterSystemQuery::dropReplica(ASTSystemQuery & query)
|
||||
if (auto * storage_replicated = dynamic_cast<StorageReplicatedMergeTree *>(iterator->table().get()))
|
||||
{
|
||||
context.checkAccess(AccessType::SYSTEM_DROP_REPLICA, iterator->table()->getStorageID());
|
||||
storage_replicated->dropReplica(query.replica, false);
|
||||
storage_replicated->getStatus(status);
|
||||
if (query.replica == status.replica_name)
|
||||
throw Exception("We can't drop local replica, please use `DROP TABLE` if you want to clean the data and drop this replica", ErrorCodes::LOGICAL_ERROR);
|
||||
storage_replicated->dropReplica(zookeeper, status.zookeeper_path, query.replica, status.is_readonly ,false);
|
||||
}
|
||||
}
|
||||
LOG_TRACE(log, "DROP REPLICA " + query.replica + " DATABSE " + database->getDatabaseName() + ": OK");
|
||||
|
@ -620,15 +620,19 @@ void StorageReplicatedMergeTree::createReplica()
|
||||
|
||||
void StorageReplicatedMergeTree::drop()
|
||||
{
|
||||
/// There is also the case when user has configured ClickHouse to wrong ZooKeeper cluster,
|
||||
/// in this case, has_metadata_in_zookeeper = false, and we also permit to drop the table.
|
||||
|
||||
if (has_metadata_in_zookeeper)
|
||||
{
|
||||
auto zookeeper = tryGetZooKeeper();
|
||||
|
||||
/// If probably there is metadata in ZooKeeper, we don't allow to drop the table.
|
||||
if (is_readonly || !zookeeper)
|
||||
throw Exception("Can't drop readonly replicated table (need to drop data in ZooKeeper as well)", ErrorCodes::TABLE_IS_READ_ONLY);
|
||||
|
||||
shutdown();
|
||||
dropReplica(replica_name, true);
|
||||
dropReplica(zookeeper, zookeeper_path, replica_name, is_readonly ,true);
|
||||
}
|
||||
|
||||
dropAllData();
|
||||
@ -746,10 +750,11 @@ static time_t tryGetPartCreateTime(zkutil::ZooKeeperPtr & zookeeper, const Strin
|
||||
return res;
|
||||
}
|
||||
|
||||
void StorageReplicatedMergeTree::dropReplica(const String & replica, bool is_drop_table)
|
||||
void StorageReplicatedMergeTree::dropReplica(zkutil::ZooKeeperPtr zookeeper, const String & zookeeper_path, const String & replica, bool is_readonly, bool is_drop_table)
|
||||
{
|
||||
auto zookeeper = tryGetZooKeeper();
|
||||
static Poco::Logger * log = &Poco::Logger::get("StorageReplicatedMergeTree::dropReplica");
|
||||
|
||||
/// If probably there is metadata in ZooKeeper, we don't allow to drop the table.
|
||||
if (is_readonly || !zookeeper)
|
||||
throw Exception("Can't drop readonly replicated table (need to drop data in ZooKeeper as well)", ErrorCodes::TABLE_IS_READ_ONLY);
|
||||
|
||||
@ -758,8 +763,6 @@ void StorageReplicatedMergeTree::dropReplica(const String & replica, bool is_dro
|
||||
|
||||
if (!is_drop_table)
|
||||
{
|
||||
if (replica == replica_name)
|
||||
throw Exception("We can't drop local replica, please use `DROP TABLE` if you want to clean the data and drop this replica", ErrorCodes::LOGICAL_ERROR);
|
||||
if (zookeeper->exists(zookeeper_path + "/replicas/" + replica + "/is_active"))
|
||||
throw Exception("Can't drop replica: " + replica + ", because it's active",
|
||||
ErrorCodes::LOGICAL_ERROR);
|
||||
@ -849,43 +852,6 @@ void StorageReplicatedMergeTree::dropReplica(const String & replica, bool is_dro
|
||||
}
|
||||
}
|
||||
|
||||
void StorageReplicatedMergeTree::dropReplicaByZkPath(Context & context, const String & replica_zk_path, const String & replica)
|
||||
{
|
||||
auto remote_replica_path = replica_zk_path + "/replicas/" + replica;
|
||||
auto & catalog = DatabaseCatalog::instance();
|
||||
StorageReplicatedMergeTree::Status status;
|
||||
|
||||
for (auto & elem : catalog.getDatabases())
|
||||
{
|
||||
DatabasePtr & database = elem.second;
|
||||
for (auto iterator = database->getTablesIterator(context); iterator->isValid(); iterator->next())
|
||||
{
|
||||
if (auto * storage_replicated = dynamic_cast<StorageReplicatedMergeTree *>(iterator->table().get()))
|
||||
{
|
||||
storage_replicated->getStatus(status);
|
||||
if (status.replica_path.compare(remote_replica_path) == 0)
|
||||
throw Exception("We can't drop local replica, please use `DROP TABLE` if you want to clean the data and drop this replica",
|
||||
ErrorCodes::LOGICAL_ERROR);
|
||||
if (status.replica_path.compare(replica_zk_path + "/replicas/" + status.replica_name) == 0)
|
||||
{
|
||||
storage_replicated->dropReplica(replica, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// It may left some garbage if replica_path subtree are concurently modified
|
||||
auto zookeeper = context.getZooKeeper();
|
||||
|
||||
//check if is active replica if we drop other replicas
|
||||
if (zookeeper->exists(remote_replica_path + "/is_active"))
|
||||
throw Exception("Can't remove replica: " + replica + ", because it's active",
|
||||
ErrorCodes::LOGICAL_ERROR);
|
||||
|
||||
zookeeper->tryRemoveRecursive(remote_replica_path);
|
||||
}
|
||||
|
||||
void StorageReplicatedMergeTree::checkParts(bool skip_sanity_checks)
|
||||
{
|
||||
auto zookeeper = getZooKeeper();
|
||||
|
@ -117,10 +117,6 @@ public:
|
||||
|
||||
void truncate(const ASTPtr &, const Context &, TableStructureWriteLockHolder &) override;
|
||||
|
||||
/** Remove a specific replica from zookeeper.
|
||||
*/
|
||||
void dropReplica(const String & replica, bool is_drop_table);
|
||||
|
||||
void rename(const String & new_path_to_table_data, const StorageID & new_table_id) override;
|
||||
|
||||
bool supportsIndexForIn() const override { return true; }
|
||||
@ -184,9 +180,9 @@ public:
|
||||
|
||||
int getMetadataVersion() const { return metadata_version; }
|
||||
|
||||
/** Remove a specific replica from zookeeper by zkpath.
|
||||
/** Remove a specific replica from zookeeper.
|
||||
*/
|
||||
static void dropReplicaByZkPath(Context & context, const String & replica_zk_path, const String & replica);
|
||||
static void dropReplica(zkutil::ZooKeeperPtr zookeeper, const String & zookeeper_path, const String & replica, bool is_readonly, bool is_drop_table);
|
||||
|
||||
private:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user