[Yandex Cloud documentation](../../index.md) > [Yandex Managed Service for ClickHouse®](../index.md) > [Step-by-step guides](index.md) > Clusters > Managing hosts > Migrating hosts to a different availability zone

# Migrating ClickHouse® cluster hosts to a different availability zone


ClickHouse® and ZooKeeper hosts of a Managed Service for ClickHouse® cluster reside in Yandex Cloud [availability zones](../../overview/concepts/geo-scope.md). Follow this guide to migrate ClickHouse® and ZooKeeper hosts to a different availability zone. If you want to migrate hosts with built-in ClickHouse® Keeper, contact [support](https://center.yandex.cloud/support).

{% note info %}

Clusters with hosts residing in the `ru-central1-d` [availability zone](../../overview/concepts/geo-scope.md) do not support:

- Intel Broadwell
- Local SSD storage if using Intel Cascade Lake

{% endnote %}

## Migrating ClickHouse® hosts {#clickhouse-hosts}

1. Make sure the migration will only move [replicated tables](../concepts/replication.md#replicated-tables) on the `ReplicatedMergeTree` family engine.

   Non-replicated tables will be lost during migration.

1. If the cluster does not have a coordination service, [enable](update.md#enable-coordination) one. Without a coordination service, you will not be able to add new hosts to [shards](../concepts/sharding.md) and perform migration.
1. [Create a subnet](../../vpc/operations/subnet-create.md) in your target availability zone.
1. Add a host to your cluster:

   {% list tabs group=instructions %}

   - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder containing the cluster.
      1. Navigate to **Managed Service for&nbsp;ClickHouse**.
      1. Click the cluster name and navigate to the **Hosts** tab.
      1. Click **Create host**.
      1. Specify the following host settings:

         * Target availability zone for your hosts.
         * New subnet.
         * To make the host accessible from outside Yandex Cloud, select **Public access**.

      1. Click **Save**.

   - CLI {#cli}

      If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

      The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

      Run this command:

      ```bash
      yc managed-clickhouse host add \
         --cluster-name <cluster_name> \
         --host type=clickhouse,`
               `zone-id=<availability_zone>,`
               `subnet-id=<new_subnet_ID>,`
               `assign-public-ip=<allow_public_access_to_host>
      ```

      You can get the cluster name with the [list of clusters in the folder](cluster-list.md#list-clusters). In the `zone-id` argument, specify the target availability zone for your hosts.

   
   - Terraform {#tf}

      1. In the Terraform infrastructure configuration file, add a new ClickHouse® host to the `hosts` section:

         ```hcl
         resource "yandex_mdb_clickhouse_cluster_v2" "<cluster_name>" {
           ...
           hosts = {
             ...
             <host_name> = {
               type             = "CLICKHOUSE"
               zone             = "<availability_zone>"
               subnet_id        = "<new_subnet_ID>"
               assign_public_ip = <allow_public_access_to_host>
               shard_name       = "<shard_name>"
             }
           }
         }
         ```

         In the `zone` attribute, specify the target availability zone for your hosts.

      1. Make sure the settings are correct.

         1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
         1. Run this command:
         
            ```bash
            terraform validate
            ```
         
            Terraform will show any errors found in your configuration files.

      1. Confirm updating the resources.

         1. Run this command to view the planned changes:
         
            ```bash
            terraform plan
            ```
         
            If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
         
         1. If everything looks correct, apply the changes:
            1. Run this command:
         
               ```bash
               terraform apply
               ```
         
            1. Confirm updating the resources.
            1. Wait for the operation to complete.


   - REST API {#api}

      1. [Get an IAM token for API authentication](../api-ref/authentication.md) and place it in an environment variable:

         ```bash
         export IAM_TOKEN="<IAM_token>"
         ```

      1. Call the [Cluster.AddHosts](../api-ref/Cluster/addHosts.md) method, e.g., via the following [cURL](https://curl.se/) request:

         ```bash
         curl \
             --request POST \
             --header "Authorization: Bearer $IAM_TOKEN" \
             --header "Content-Type: application/json" \
             --url 'https://mdb.api.cloud.yandex.net/managed-clickhouse/v1/clusters/<cluster_ID>/hosts:batchCreate' \
             --data '{
                       "hostSpecs": [
                         {
                           "type": "CLICKHOUSE",
                           "zoneId": "<availability_zone>",
                           "subnetId": "<subnet_ID>",
                           "assignPublicIp": <allow_public_access_to_host>
                         }
                       ]
                     }'
         ```

         Where `hostSpecs` is the array of settings for the new hosts. Each array element contains the configuration for a single host and has the following structure:

         * `type`: Host type, which is always `CLICKHOUSE` for ClickHouse® hosts.
         * `zoneId`: Availability zone.
         * `subnetId`: Subnet ID.
         * `assignPublicIp`: Internet access to the host via a public IP address, `true` or `false`.

         You can get the cluster ID with the [list of clusters in the folder](cluster-list.md#list-clusters).

      1. View the [server response](../api-ref/Cluster/addHosts.md#yandex.cloud.operation.Operation) to make sure your request was successful.

   - gRPC API {#grpc-api}

      1. [Get an IAM token for API authentication](../api-ref/authentication.md) and put it into an environment variable:

         ```bash
         export IAM_TOKEN="<IAM_token>"
         ```

      1. Clone the [cloudapi](https://github.com/yandex-cloud/cloudapi) repository:
         
         ```bash
         cd ~/ && git clone --depth=1 https://github.com/yandex-cloud/cloudapi
         ```
         
         Below, we assume that the repository contents reside in the `~/cloudapi/` directory.
      1. Call the [ClusterService.AddHosts](../api-ref/grpc/Cluster/addHosts.md) method, e.g., via the following [gRPCurl](https://github.com/fullstorydev/grpcurl) request:

         ```bash
         grpcurl \
             -format json \
             -import-path ~/cloudapi/ \
             -import-path ~/cloudapi/third_party/googleapis/ \
             -proto ~/cloudapi/yandex/cloud/mdb/clickhouse/v1/cluster_service.proto \
             -rpc-header "Authorization: Bearer $IAM_TOKEN" \
             -d '{
                     "cluster_id": "<cluster_ID>",
                     "host_specs": [
                         {
                             "type": "CLICKHOUSE",
                             "zone_id": "<availability_zone>",
                             "subnet_id": "<subnet_ID>",
                             "assign_public_ip": <allow_public_access_to_host>
                         }
                     ]
                 }' \
             mdb.api.cloud.yandex.net:443 \
             yandex.cloud.mdb.clickhouse.v1.ClusterService.AddHosts
         ```

         Where `host_specs` is the array of settings for the new hosts. Each array element contains the configuration for a single host and has the following structure:

         * `type`: Host type, which is always `CLICKHOUSE` for ClickHouse® hosts.
         * `zone_id`: Availability zone.
         * `subnet_id`: Subnet ID.
         * `assign_public_ip`: Internet access to the host via a public IP address, `true` or `false`.

         You can get the cluster ID with the [list of clusters in the folder](cluster-list.md#list-clusters).

      1. View the [server response](../api-ref/grpc/Cluster/addHosts.md#yandex.cloud.operation.Operation) to make sure your request was successful.

   {% endlist %}

1. To connect to the database after migration, specify the new host’s FQDN in your backend or client, e.g., in your application code or graphical IDE. Delete the original host's FQDN in the source availability zone.

   You can get this FQDN from the list of hosts in your cluster:

   ```bash
   yc managed-clickhouse host list --cluster-name <cluster_name>
   ```

   You will see the FQDN under `NAME` in the command output. Alternatively, you can connect using a [special FQDN](connect/fqdn.md#auto).

1. Delete the hosts in the source availability zone:

   {% list tabs group=instructions %}

   - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder containing the cluster.
      1. Navigate to **Managed Service for&nbsp;ClickHouse**.
      1. Click the name of your cluster and select the **Hosts** tab.
      1. Click ![image](../../_assets/console-icons/ellipsis.svg) in the host row, select **Delete**, and confirm the deletion.

   - CLI {#cli}

      Run the following command for each host:

      ```bash
      yc managed-clickhouse host delete <host_FQDN> --cluster-name <cluster_name>
      ```

      
   - Terraform {#tf}

      1. In your Terraform infrastructure configuration file, delete the ClickHouse® host with the source availability zone from the `hosts` section.
      1. Make sure the settings are correct.

         1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
         1. Run this command:
         
            ```bash
            terraform validate
            ```
         
            Terraform will show any errors found in your configuration files.

      1. Type `yes` and press **Enter**.

         1. Run this command to view the planned changes:
         
            ```bash
            terraform plan
            ```
         
            If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
         
         1. If everything looks correct, apply the changes:
            1. Run this command:
         
               ```bash
               terraform apply
               ```
         
            1. Confirm updating the resources.
            1. Wait for the operation to complete.


   - REST API {#api}

      1. Call the [Cluster.DeleteHosts](../api-ref/Cluster/deleteHosts.md) method, e.g., via the following [cURL](https://curl.se/) request:
      
          ```bash
          curl \
             --request POST \
             --header "Authorization: Bearer $IAM_TOKEN" \
             --header "Content-Type: application/json" \
             --url 'https://mdb.api.cloud.yandex.net/managed-clickhouse/v1/clusters/<cluster_ID>/hosts:batchDelete' \
             --data '{
                       "hostNames": [
                         "<host_FQDN>"
                       ]
                     }'
          ```
      
          Where `hostNames` is the array containing the host you want to delete.
      
          You can only specify one host FQDN per request. If you need to delete multiple hosts, make a separate request for each of them.
      
      1. View the [server response](../api-ref/Cluster/deleteHosts.md#yandex.cloud.operation.Operation) to make sure your request was successful.

   - gRPC API {#grpc-api}

      1. Call the [ClusterService.DeleteHosts](../api-ref/grpc/Cluster/deleteHosts.md) method, e.g., via the following [gRPCurl](https://github.com/fullstorydev/grpcurl) request:
      
          ```bash
          grpcurl \
             -format json \
             -import-path ~/cloudapi/ \
             -import-path ~/cloudapi/third_party/googleapis/ \
             -proto ~/cloudapi/yandex/cloud/mdb/clickhouse/v1/cluster_service.proto \
             -rpc-header "Authorization: Bearer $IAM_TOKEN" \
             -d '{
                   "cluster_id": "<cluster_ID>",
                   "host_names": [
                     "<host_FQDN>"
                   ]
                 }' \
             mdb.api.cloud.yandex.net:443 \
             yandex.cloud.mdb.clickhouse.v1.ClusterService.DeleteHosts
          ```
      
          Where `host_names` is the array containing the host you want to delete.
      
          You can only specify one host FQDN per request. If you need to delete multiple hosts, make a separate request for each of them.
      
      1. View the [server response](../api-ref/grpc/Cluster/create.md#yandex.cloud.operation.Operation) to make sure your request was successful.

   {% endlist %}

1. Wait for the cluster state to change to **Alive**. In the management console, go to **Managed Service for&nbsp;ClickHouse**. You can check the cluster state in the **Availability** column.

## Migrating ZooKeeper hosts {#zookeeper-hosts}

1. [Create a subnet](../../vpc/operations/subnet-create.md) in your target availability zone.
1. Add a host to your cluster:

   {% list tabs group=instructions %}

   - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder containing the cluster.
      1. Navigate to **Managed Service for&nbsp;ClickHouse**.
      1. Click the cluster name and navigate to the **Hosts** tab.
      1. Click **Create ZooKeeper host**.
      1. Specify the new subnet and the availability zone to move the hosts to.
      1. Click **Save**.

   - CLI {#cli}

      If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

      The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

      Run this command:

      ```bash
      yc managed-clickhouse host add \
         --cluster-name <cluster_name> \
         --host type=zookeeper,`
               `zone-id=<availability_zone>,`
               `subnet-id=<new_subnet_ID>,`
               `assign-public-ip=<allow_public_access_to_host>
      ```

      You can get the cluster name with the [list of clusters in the folder](cluster-list.md#list-clusters). In the `zone-id` argument, specify the target availability zone for your hosts.

   
   - Terraform {#tf}

      1. In the Terraform infrastructure configuration file, add a new ZooKeeper host to the `hosts` section:

         ```hcl
         resource "yandex_mdb_clickhouse_cluster_v2" "<cluster_name>" {
           ...
           hosts = {
             ...
             <host_name> = {
               type      = "ZOOKEEPER"
               zone      = "<availability_zone>"
               subnet_id = "<new_subnet_ID>"
             }
           }
         }
         ```

         In the `zone` attribute, specify the target availability zone for your hosts.

      1. Make sure the settings are correct.

         1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
         1. Run this command:
         
            ```bash
            terraform validate
            ```
         
            Terraform will show any errors found in your configuration files.

      1. Confirm updating the resources.

         1. Run this command to view the planned changes:
         
            ```bash
            terraform plan
            ```
         
            If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
         
         1. If everything looks correct, apply the changes:
            1. Run this command:
         
               ```bash
               terraform apply
               ```
         
            1. Confirm updating the resources.
            1. Wait for the operation to complete.


   - REST API {#api}

      1. [Get an IAM token for API authentication](../api-ref/authentication.md) and place it in an environment variable:

         ```bash
         export IAM_TOKEN="<IAM_token>"
         ```

      1. Call the [Cluster.AddHosts](../api-ref/Cluster/addHosts.md) method, e.g., via the following [cURL](https://curl.se/) request:

         ```bash
         curl \
             --request POST \
             --header "Authorization: Bearer $IAM_TOKEN" \
             --header "Content-Type: application/json" \
             --url 'https://mdb.api.cloud.yandex.net/managed-clickhouse/v1/clusters/<cluster_ID>/hosts:batchCreate' \
             --data '{
                       "hostSpecs": [
                         {
                           "type": "ZOOKEEPER",
                           "zoneId": "<availability_zone>",
                           "subnetId": "<subnet_ID>",
                           "assignPublicIp": <allow_public_access_to_host>
                         }
                       ]
                     }'
         ```

         Where `hostSpecs` is the array of settings for the new host. Each array element contains the configuration for a single host and has the following structure:

         * `type`: Host type, `ZOOKEEPER`.
         * `zoneId`: Availability zone.
         * `subnetId`: Subnet ID.
         * `assignPublicIp`: Internet access to the host via a public IP address, `true` or `false`.

         You can get the cluster ID with the [list of clusters in the folder](cluster-list.md#list-clusters).

      1. Check the [server response](../api-ref/Cluster/addHosts.md#yandex.cloud.operation.Operation) to make sure your request was successful.

   - gRPC API {#grpc-api}

      1. [Get an IAM token for API authentication](../api-ref/authentication.md) and put it into an environment variable:

         ```bash
         export IAM_TOKEN="<IAM_token>"
         ```

      1. Clone the [cloudapi](https://github.com/yandex-cloud/cloudapi) repository:
         
         ```bash
         cd ~/ && git clone --depth=1 https://github.com/yandex-cloud/cloudapi
         ```
         
         Below, we assume that the repository contents reside in the `~/cloudapi/` directory.
      1. Call the [ClusterService.AddHosts](../api-ref/grpc/Cluster/addHosts.md) method, e.g., via the following [gRPCurl](https://github.com/fullstorydev/grpcurl) request:

         ```bash
         grpcurl \
             -format json \
             -import-path ~/cloudapi/ \
             -import-path ~/cloudapi/third_party/googleapis/ \
             -proto ~/cloudapi/yandex/cloud/mdb/clickhouse/v1/cluster_service.proto \
             -rpc-header "Authorization: Bearer $IAM_TOKEN" \
             -d '{
                     "cluster_id": "<cluster_ID>",
                     "host_specs": [
                         {
                             "type": "ZOOKEEPER",
                             "zone_id": "<availability_zone>",
                             "subnet_id": "<subnet_ID>",
                             "assign_public_ip": <allow_public_access_to_host>
                         }
                 }' \
             mdb.api.cloud.yandex.net:443 \
             yandex.cloud.mdb.clickhouse.v1.ClusterService.AddHosts
         ```

         Where `host_specs` is the array of settings for the new hosts. Each element of the `host_specs` array contains settings for a single host and has the following structure:

         * `type`: `ZOOKEEPER` host type.
         * `zone_id`: Availability zone.
         * `subnet_id`: Subnet ID.
         * `assign_public_ip`: Internet access to the host via a public IP address, `true` or `false`.

         You can get the cluster ID with the [list of clusters in the folder](cluster-list.md#list-clusters).

      1. View the [server response](../api-ref/grpc/Cluster/addHosts.md#yandex.cloud.operation.Operation) to make sure your request was successful.

   {% endlist %}

1. Delete the hosts in the source availability zone:

   {% list tabs group=instructions %}

   - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder containing the cluster.
      1. Navigate to **Managed Service for&nbsp;ClickHouse**.
      1. Click the name of your cluster and select the **Hosts** tab.
      1. Click ![image](../../_assets/console-icons/ellipsis.svg) in the host row, select **Delete**, and confirm the deletion.

   - CLI {#cli}

      Run the following command for each host:

      ```bash
      yc managed-clickhouse host delete <host_FQDN> --cluster-name <cluster_name>
      ```

   
   - Terraform {#tf}

      1. In your Terraform infrastructure configuration file, delete the ZooKeeper host with the source availability zone from the `hosts` section.
      1. Make sure the settings are correct.

         1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
         1. Run this command:
         
            ```bash
            terraform validate
            ```
         
            Terraform will show any errors found in your configuration files.

      1. Type `yes` and press **Enter**.

         1. Run this command to view the planned changes:
         
            ```bash
            terraform plan
            ```
         
            If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
         
         1. If everything looks correct, apply the changes:
            1. Run this command:
         
               ```bash
               terraform apply
               ```
         
            1. Confirm updating the resources.
            1. Wait for the operation to complete.

   
   - REST API {#api}

      1. Call the [Cluster.DeleteHosts](../api-ref/Cluster/deleteHosts.md) method, e.g., via the following [cURL](https://curl.se/) request:
      
          ```bash
          curl \
             --request POST \
             --header "Authorization: Bearer $IAM_TOKEN" \
             --header "Content-Type: application/json" \
             --url 'https://mdb.api.cloud.yandex.net/managed-clickhouse/v1/clusters/<cluster_ID>/hosts:batchDelete' \
             --data '{
                       "hostNames": [
                         "<host_FQDN>"
                       ]
                     }'
          ```
      
          Where `hostNames` is the array containing the host you want to delete.
      
          You can only specify one host FQDN per request. If you need to delete multiple hosts, make a separate request for each of them.
      
      1. View the [server response](../api-ref/Cluster/deleteHosts.md#yandex.cloud.operation.Operation) to make sure your request was successful.

   - gRPC API {#grpc-api}

      1. Call the [ClusterService.DeleteHosts](../api-ref/grpc/Cluster/deleteHosts.md) method, e.g., via the following [gRPCurl](https://github.com/fullstorydev/grpcurl) request:
      
          ```bash
          grpcurl \
             -format json \
             -import-path ~/cloudapi/ \
             -import-path ~/cloudapi/third_party/googleapis/ \
             -proto ~/cloudapi/yandex/cloud/mdb/clickhouse/v1/cluster_service.proto \
             -rpc-header "Authorization: Bearer $IAM_TOKEN" \
             -d '{
                   "cluster_id": "<cluster_ID>",
                   "host_names": [
                     "<host_FQDN>"
                   ]
                 }' \
             mdb.api.cloud.yandex.net:443 \
             yandex.cloud.mdb.clickhouse.v1.ClusterService.DeleteHosts
          ```
      
          Where `host_names` is the array containing the host you want to delete.
      
          You can only specify one host FQDN per request. If you need to delete multiple hosts, make a separate request for each of them.
      
      1. View the [server response](../api-ref/grpc/Cluster/create.md#yandex.cloud.operation.Operation) to make sure your request was successful.

   {% endlist %}

1. Wait for the cluster state to change to **Alive**. In the management console, go to **Managed Service for&nbsp;ClickHouse**. You can check the cluster state in the **Availability** column.

## Specifics of migration in Yandex Data Transfer {#data-transfer}

If your cluster is used as an [endpoint](../../data-transfer/concepts/index.md#endpoint) when transferring data with Data Transfer, and the [transfer type](../../data-transfer/concepts/transfer-lifecycle.md#transfer-types) is **Replication** or **Snapshot and increment**, restart the transfer after migrating the cluster. This way, the transfer will get data about the cluster's new topology.

You do not need to restart **Snapshot** transfers, as information about the new topology is provided automatically upon their activation.

To restart a transfer, choose one of the two methods:

* [Deactivate](../../data-transfer/operations/transfer.md#deactivate) the transfer and wait for its status to change to **Stopped**. Next, [reactivate](../../data-transfer/operations/transfer.md#activate) the transfer and wait for its status to change to **Replicating**.
* Update any [setting for the transfer](../../data-transfer/operations/transfer.md#update) or [endpoint](../../data-transfer/operations/endpoint/index.md#update).

For more information, see [Migrating a Data Transfer transfer and endpoints to a different availability zone](../../data-transfer/operations/endpoint/migration-to-an-availability-zone.md).

_ClickHouse® is a registered trademark of [ClickHouse, Inc](https://clickhouse.com)._