Repository: ClickHouse/ClickHouse
File: src/Interpreters/DDLWorker.cpp (C++)

Code before:
    // Reset all active_node_holders
    for (auto & it : active_node_holders)
    {
        auto & active_node_holder = it.second.second;
        if (active_node_holder)
            active_node_holder->setAlreadyRemoved();
        active_node_holder.reset();
    }

    active_node_holders.clear();

    const auto maybe_secure_port = context->getTCPPortSecure();
    const auto port = context->getTCPPort();

    Coordination::Stat replicas_stat;
    Strings host_ids = zookeeper->getChildren(replicas_dir, &replicas_stat);
    NameSet local_host_ids;
    for (const auto & host_id : host_ids)
    {
        try
        {
            HostID host = HostID::fromString(host_id);
            if (DDLTask::isSelfHostID(log, host, maybe_secure_port, port))
                local_host_ids.emplace(host_id);
        }
        catch (const Exception & e)
        {
            LOG_WARNING(log, "Unable to check if host {} is a local address, exception: {}", host_id, e.displayText());
            continue;
        }
    }

    for (const auto & host_id : local_host_ids)
    {
        auto it = active_node_holders.find(host_id);
        if (it != active_node_holders.end())
            continue;

        String active_path = fs::path(replicas_dir) / host_id / "active";
        String active_id = toString(ServerUUID::get());

        LOG_TRACE(log, "Trying to mark a replica active: active_path={}, active_id={}", active_path, active_id);
        if (HostID::fromString(host_id).isLoopbackHost())
        {
            String content;
            Coordination::Stat stat;
            if (zookeeper->tryGet(active_path, content, &stat))
            {
                // For a loopback host, many replicas might try to claim it as their own host.
                // If the host is claimed by a replica, we skip it.
                // Loopback host is supposed to be used in test environment.

Review comment (suggestion):
So this is the main part that will fix the issue in the cloud

The problem was that `context->getClusters()` does not return Replicated DB clusters, so the list of hosts was empty in the cloud. However, we don't need to check all hosts in Replicated DB clusters because it's enough to simply use `getInterserverIOAddress` which is our host for sure

And for `remote_servers` config, we notify DDLWorker on config changes, but it's a separate fix 

Code after:
}

void DDLWorker::createReplicaDirs(const ZooKeeperPtr & zookeeper, const NameSet & host_ids)
{
    for (const auto & host_id : host_ids)
    {
        LOG_INFO(log, "Creating replica dir for host id {}", host_id);
        zookeeper->createAncestors(fs::path(replicas_dir) / host_id / "");
    }
}

void DDLWorker::markReplicasActive(bool reinitialized)
{
    auto zookeeper = getZooKeeper();
    const auto maybe_secure_port = context->getTCPPortSecure();
    const auto port = context->getTCPPort();

    auto all_host_ids = getAllHostIDsFromClusters();

    // Add interserver IO host IDs for Replicated DBs
    try
    {
        auto host_port = context->getInterserverIOAddress();
        HostID interserver_io_host_id = {host_port.first, port};
        all_host_ids.emplace(interserver_io_host_id.toString());
        LOG_INFO(log, "Add interserver IO host ID {}", interserver_io_host_id.toString());
        if (maybe_secure_port)
        {
            HostID interserver_io_secure_host_id = {host_port.first, *maybe_secure_port};
            all_host_ids.emplace(interserver_io_secure_host_id.toString());
            LOG_INFO(log, "Add interserver IO secure host ID  {}", interserver_io_secure_host_id.toString());
        }
    }
    catch (const Exception & e)
    {
        LOG_INFO(log, "Unable to get interserver IO address, error {}", e.what());
    }

    createReplicaDirs(zookeeper, all_host_ids);

    if (reinitialized)
    {
        // Reset all active_node_holders
        for (auto & it : active_node_holders)
        {
            auto & active_node_holder = it.second.second;
            if (active_node_holder)
                active_node_holder->setAlreadyRemoved();
            active_node_holder.reset();
        }
        active_node_holders.clear();