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

# Migrating MySQL® cluster hosts to a different availability zone


Managed Service for MySQL® cluster hosts reside in Yandex Cloud [availability zones](../../overview/concepts/geo-scope.md). To migrate hosts from one availability zone to another, do the following:

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. Navigate to **Managed Service for&nbsp;MySQL**.
      1. Click the cluster name and navigate to the **Hosts** tab.
      1. Click ![image](../../_assets/console-icons/plus.svg) **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-mysql host add \
         --cluster-name <cluster_name> \
         --host 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` parameter, specify the target availability zone for your hosts.

   - Terraform {#tf}

      1. Add the host manifest to the Terraform configuration file describing your infrastructure:

         ```hcl
         resource "yandex_mdb_mysql_cluster" "<cluster_name>" {
           ...
           host {
             zone             = "<availability_zone>"
             subnet_id        = "<new_subnet_ID>"
             assign_public_ip = <allow_public_access_to_host>
           }
         }
         ```

         In the `zone` parameter, 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 put it into 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-mysql/v1/clusters/<cluster_ID>/hosts:batchCreate' \
            --data '{
                      "hostSpecs": [
                        {
                          "zoneId": "<availability_zone>",
                          "subnetId": "<new_subnet_ID>",
                          "assignPublicIp": <allow_public_access_to_host>
                        }
                      ]
                    }'
         ```

         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/mysql/v1/cluster_service.proto \
            -rpc-header "Authorization: Bearer $IAM_TOKEN" \
            -d '{
                  "cluster_id": "<cluster_ID>",
                  "host_specs": [
                    {
                      "zone_id": "<availability_zone>",
                      "subnet_id": "<new_subnet_ID>",
                      "assign_public_ip": <allow_public_access_to_host>
                    }
                  ]
                }' \
            mdb.api.cloud.yandex.net:443 \
            yandex.cloud.mdb.mysql.v1.ClusterService.AddHosts
         ```

         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/grpc/Cluster/create.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-mysql 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#fqdn-master).

1. Delete the hosts in the source availability zone:

   {% list tabs group=instructions %}

   - Management console {#console}

      1. Navigate to **Managed Service for&nbsp;MySQL**.
      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-mysql host delete <host_FQDN> --cluster-name <cluster_name>
      ```

   - Terraform {#tf}

      1. In your Terraform infrastructure configuration file, locate your cluster description and delete the `host` sections with the source availability zone.
      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-mysql/v1/clusters/<cluster_ID>/hosts:batchDelete' \
            --data '{
                      "hostNames": [
                        "<host_FQDN>"
                      ]
                    }'
         ```

         Where `hostNames` is the array containing the host you want to delete.

         You can provide only one host FQDN per request. If you need to delete multiple hosts, make a separate request for each of them.

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

   - gRPC API {#grpc-api}

      1. Use the [ClusterService/DeleteHosts](../api-ref/grpc/Cluster/deleteHosts.md) call and send the following request, e.g., via [gRPCurl](https://github.com/fullstorydev/grpcurl):

         ```bash
         grpcurl \
            -format json \
            -import-path ~/cloudapi/ \
            -import-path ~/cloudapi/third_party/googleapis/ \
            -proto ~/cloudapi/yandex/cloud/mdb/mysql/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.mysql.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, send a separate request for each one.

      1. Check 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, navigate to the folder dashboard and select **Managed Service for&nbsp;MySQL**. You can see the cluster state in the **Availability** column.

{% 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 %}

## 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).

{% note info %}

Enable GTID mode (`GTID-MODE = ON`) for your MySQL® cluster used as a source endpoint during a transfer.

{% endnote %}