**Describe the solution you'd like**

We already can run clickhouse-server without configured ZooKeeper (the tables will start in read-only mode)
and with configured ZooKeeper, if it starts to be inaccessible at runtime (the tables will be read-only until the session is re-established).

Let's also make it possible to start up when ZooKeeper is unavailable.

**Additional context**

If that will be very hard to implement, we can consider other options:
- lazy attaching of the tables after sever start-up;
- a maintenance mode when the tables are not attached at start-up and require manual ATTACH queries.
zkutil::ZooKeeper & zookeeper, const String & partition_id, bool detach,
    Coordination::Requests & ops, std::vector<LogEntryPtr> & entries,
    std::vector<EphemeralLockInZooKeeper> & delimiting_block_locks,
    std::vector<size_t> & log_entry_ops_idx)
{
    MergeTreePartInfo drop_range_info;
    
    std::optional<EphemeralLockInZooKeeper> delimiting_block_lock;
    if (!getFakePartCoveringAllPartsInPartition(partition_id, drop_range_info, delimiting_block_lock))
    {
        LOG_INFO(log, "Will not drop partition {}, it is empty.", partition_id);
        return false;
    }
    clearBlocksInPartition(zookeeper, partition_id, drop_range_info.min_block, drop_range_info.max_block);
    String drop_range_fake_part_name = getPartNamePossiblyFake(format_version, drop_range_info);
    LOG_DEBUG(log, "Disabled merges covered by range {}", drop_range_fake_part_name);
    
    auto entry = std::make_shared<LogEntry>();
    entry->type = LogEntry::DROP_RANGE;
    entry->source_replica = replica_name;
    entry->new_part_name = drop_range_fake_part_name;
    entry->detach = detach;
    entry->create_time = time(nullptr);
    log_entry_ops_idx.push_back(ops.size());
    ops.emplace_back(zkutil::makeCreateRequest(fs::path(zookeeper_path) / "log/log-", entry->toString(),
                                               zkutil::CreateMode::PersistentSequential));
    delimiting_block_lock->getUnlockOps(ops);
    delimiting_block_locks.push_back(std::move(*delimiting_block_lock));
    entries.push_back(std::move(entry));
    return true;