**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.
ReplicatedMergeTreePartCheckThread part_check_thread;
    
    ReplicatedMergeTreeRestartingThread restarting_thread;
    PartMovesBetweenShardsOrchestrator part_moves_between_shards_orchestrator;
    
    bool other_replicas_fixed_granularity = false;
    
    const RenamingRestrictions renaming_restrictions;
    const size_t replicated_fetches_pool_size;
    
    
    ThrottlerPtr replicated_fetches_throttler;
    ThrottlerPtr replicated_sends_throttler;
    
    UUID table_shared_id;
    std::mutex last_broken_disks_mutex;
    std::set<String> last_broken_disks;
    template <class Func>
    void foreachActiveParts(Func && func, bool select_sequential_consistency) const;
    /** Creates the minimum set of nodes in ZooKeeper and create first replica.
      * Returns true if was created, false if exists.
      */
    bool createTableIfNotExists(const StorageMetadataPtr & metadata_snapshot);
    /**
     * Creates a replica in ZooKeeper and adds to the queue all that it takes to catch up with the rest of the replicas.
     */
    void createReplica(const StorageMetadataPtr & metadata_snapshot);
    /** Create nodes in the ZK, which must always be, but which might not exist when older versions of the server are running.
      */