**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.
{
            LOG_WARNING(log, "Empty part {} is not created instead of lost part because there are no parts in partition {} (it's empty), "
                             "resolve this manually using DROP/DETACH PARTITION.", lost_part_name, new_part_info.partition_id);
            return false;
        }
    }
    new_data_part->minmax_idx = std::move(minmax_idx);
    new_data_part->is_temp = true;
    SyncGuardPtr sync_guard;
    if (new_data_part->isStoredOnDisk())
    {
        
        if (data_part_storage_builder->exists())
        {
            LOG_WARNING(log, "Removing old temporary directory {}", new_data_part->data_part_storage->getFullPath());
            data_part_storage_builder->removeRecursive();
        }
        data_part_storage_builder->createDirectories();
        if (getSettings()->fsync_part_directory)
            sync_guard = data_part_storage_builder->getDirectorySyncGuard();
    }
    
    
    auto compression_codec = getContext()->chooseCompressionCodec(0, 0);
    const auto & index_factory = MergeTreeIndexFactory::instance();
    MergedBlockOutputStream out(new_data_part, data_part_storage_builder, metadata_snapshot, columns,
        index_factory.getMany(metadata_snapshot->getSecondaryIndices()), compression_codec, NO_TRANSACTION_PTR);
    bool sync_on_insert = settings->fsync_after_insert;
    out.write(block);