[Документация Yandex Cloud](../../index.md) > [Практические руководства](../index.md) > [Построение Data Platform](index.md) > Миграция БД из Managed Service for MySQL® в сторонний кластер MySQL®

# Миграция базы данных из Yandex Managed Service for MySQL® в сторонний кластер MySQL®

# Миграция базы данных из Managed Service for MySQL® в сторонний кластер MySQL®

{% note info %}

Миграция данных из стороннего кластера MySQL® описана в статье [Миграция базы данных из стороннего кластера MySQL®](../../managed-mysql/tutorials/data-migration/index.md).

{% endnote %}

Чтобы перенести базу данных, развернутую в кластере Managed Service for MySQL®, на сторонний кластер MySQL®:

1. Перенесите данные.
1. Закройте старую базу данных на запись.
1. Переведите нагрузку на сторонний кластер.

Поддерживается миграция между разными версиями: например, можно перенести базы из MySQL® версии 5.7 в версию 8. При этом мажорная версия MySQL® на стороннем кластере должна быть не ниже версии на кластере Managed Service for MySQL®.

Перенести данные из _кластера-источника_ Managed Service for MySQL® в сторонний _кластер-приемник_ MySQL® можно двумя способами:

* [Перенос данных с использованием сервиса Yandex Data Transfer](#data-transfer).

    Этот способ позволяет перенести базу целиком без остановки обслуживания пользователей.

    Подробнее в разделе [Какие задачи решает сервис Yandex Data Transfer](../../data-transfer/concepts/use-cases.md).

* [Перенос данных с помощью внешней репликации](#binlog-replication).

    [_Внешняя репликация_](https://dev.mysql.com/doc/refman/8.0/en/replication-configuration.html) позволяет мигрировать базы данных между кластерами MySQL®, используя встроенные средства СУБД.

    Используйте этот способ только в том случае, если перенос данных с помощью Yandex Data Transfer по каким-либо причинам невозможен.

## Перед началом работы {#before-you-begin}

Подготовьте кластер-приемник:

* [Создайте базу данных MySQL®](https://dev.mysql.com/doc/refman/8.0/en/creating-database.html) любой подходящей конфигурации.
* Убедитесь, что к хостам кластера-приемника можно подключиться из интернета.

Дополнительно для переноса с помощью внешней репликации MySQL®:

* Убедитесь, что все хосты кластера-источника доступны по публичному IP-адресу, чтобы кластер-приемник мог подключаться к источнику. Для этого:
   * [Добавьте хосты](../../managed-mysql/operations/hosts.md#add) с публичными IP-адресами.
   * [Удалите хосты](../../managed-mysql/operations/hosts.md#remove) без публичных IP-адресов.
* Установите на хосты кластера-приемника [серверные SSL-сертификаты Managed Service for MySQL®](../../managed-mysql/operations/connect/index.md#get-ssl-cert). Они требуются для подключения к публично доступному кластеру-источнику.
* При необходимости настройте межсетевой экран (firewall) и [группы безопасности](../../managed-mysql/operations/connect/index.md#configuring-security-groups), чтобы можно было подключаться из кластера-приемника к кластеру-источнику, а также к каждому кластеру в отдельности (например, с помощью [утилиты mysql](https://dev.mysql.com/doc/refman/8.0/en/mysql.html)).
* Убедитесь, что с хостов кластера-приемника можно подключиться к хостам кластера-источника.
* Убедитесь, что можно [подключиться к кластеру-источнику](../../managed-mysql/operations/connect/index.md) и к кластеру-приемнику с SSL.

## Перенос данных с использованием сервиса Yandex Data Transfer {#data-transfer}


### Необходимые платные ресурсы {#paid-resources-with-data-transfer}

* Кластер Managed Service for MySQL®: выделенные хостам вычислительные ресурсы, объем хранилища и резервных копий ([тарифы Managed Service for MySQL®](../../managed-mysql/pricing.md)).
* Публичные IP-адреса, если для хостов кластера включен публичный доступ ([тарифы Virtual Private Cloud](../../vpc/pricing.md)).
* Каждый трансфер: использование вычислительных ресурсов и количество переданных строк данных ([тарифы Data Transfer](../../data-transfer/pricing.md)).


### Перенесите базу данных {#database-migration}

{% note info %}

В [регионе Казахстан](../../overview/concepts/region.md) доступна только [зона доступности](../../overview/concepts/geo-scope.md) `kz1-a`.

{% endnote %}

# Перенос данных с использованием сервиса Yandex Data Transfer {#data-transfer}

1. [Подготовьте базу данных кластера-источника](../../data-transfer/operations/prepare.md#source-my).
1. [Подготовьте базу данных кластера-приемника](../../data-transfer/operations/prepare.md#target-my).
1. Создайте эндпоинты и трансфер:

    {% list tabs group=instructions %}

    - Вручную {#manual}

        1. [Создайте эндпоинт для источника](../../data-transfer/operations/endpoint/index.md#create):

            * **Тип базы данных** — `MySQL`.
            * **Настройки подключения** — `Кластер Managed Service for MySQL`.

                Укажите идентификатор кластера-источника.

        1. [Создайте эндпоинт для приемника](../../data-transfer/operations/endpoint/index.md#create):

            * **Тип базы данных** — `MySQL`.
            * **Настройки подключения** — `Пользовательская инсталляция`.
                
                Укажите параметры подключения к кластеру-приемнику.

        1. [Создайте трансфер](../../data-transfer/operations/transfer.md#create) типа _**Копирование и репликация**_, использующий созданные эндпоинты.

        1. [Активируйте трансфер](../../data-transfer/operations/transfer.md#activate).

    - Terraform {#tf}

        1. Если у вас еще нет Terraform, [установите его](../infrastructure-management/terraform-quickstart.md#install-terraform).
        1. [Получите данные для аутентификации](../infrastructure-management/terraform-quickstart.md#get-credentials). Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.
        1. [Настройте и инициализируйте провайдер](../infrastructure-management/terraform-quickstart.md#configure-provider). Чтобы не создавать конфигурационный файл с настройками провайдера вручную, [скачайте его](https://github.com/yandex-cloud-examples/yc-terraform-provider-settings/blob/main/provider.tf).
        1. Поместите конфигурационный файл в отдельную рабочую директорию и [укажите значения параметров](../infrastructure-management/terraform-quickstart.md#configure-provider). Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.

        1. Скачайте в ту же рабочую директорию файл конфигурации трансфера и эндпоинтов [data-transfer-mmy-mysql.tf](https://github.com/yandex-cloud-examples/yc-data-transfer-from-cloud-mysql-to-on-premise/blob/main/data-transfer-mmy-mysql.tf).

        1. Укажите в файле конфигурации:

            * [параметры эндпоинта-источника](../../data-transfer/operations/endpoint/source/mysql.md#managed-service);
            * [параметры эндпоинта-приемника](../../data-transfer/operations/endpoint/target/mysql.md#on-premise).

        1. Проверьте корректность файлов конфигурации Terraform с помощью команды:

            ```bash
            terraform validate
            ```

            Если в файлах конфигурации есть ошибки, Terraform на них укажет.

        1. Создайте необходимую инфраструктуру:

            1. Выполните команду для просмотра планируемых изменений:
            
               ```bash
               terraform plan
               ```
            
               Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
            
            1. Если вас устраивают планируемые изменения, внесите их:
               1. Выполните команду:
            
                  ```bash
                  terraform apply
                  ```
            
               1. Подтвердите изменение ресурсов.
               1. Дождитесь завершения операции.

            В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в [консоли управления](https://kz.console.yandex.cloud).

            Трансфер активируется автоматически после создания.

    {% endlist %}

    {% note warning %}

    Избегайте любых изменений в схеме данных на кластере-источнике и кластере-приемнике во время работы трансфера. Подробнее в разделе [Работа с базами данных во время трансфера](../../data-transfer/operations/db-actions.md).

    {% endnote %}

1. Дождитесь перехода трансфера в статус **Реплицируется**.
1. Переведите кластер-источник в режим <q>только чтение</q> и переключите нагрузку на кластер-приемник.
1. На странице [мониторинга трансфера](../../data-transfer/operations/monitoring.md) дождитесь снижения до нуля характеристики **Maximum data transfer delay**. Это значит, что в кластер-приемник перенесены все изменения, произошедшие в кластере-источнике после завершения копирования данных.
1. [Деактивируйте](../../data-transfer/operations/transfer.md#deactivate-transfer) трансфер и дождитесь его перехода в статус **Остановлен**.

    Подробнее о статусах трансфера смотрите в разделе [Жизненный цикл трансфера](../../data-transfer/concepts/transfer-lifecycle.md#statuses).

1. Чтобы снизить потребление ресурсов, которые вам не нужны, удалите их:

    {% list tabs group=instructions %}

    - Вручную {#manual}

      1. [Удалите остановленный трансфер](../../data-transfer/operations/transfer.md#delete).
      1. [Удалите эндпоинты для источника и приемника](../../data-transfer/operations/endpoint/index.md#delete).

    - Terraform {#tf}

      1. В терминале перейдите в директорию с планом инфраструктуры.
      
          {% note warning %}
      
          Убедитесь, что в директории нет Terraform-манифестов с ресурсами, которые вы хотите сохранить. Terraform удаляет все ресурсы, которые были созданы с помощью манифестов в текущей директории.
      
          {% endnote %}
      
      1. Удалите ресурсы:
      
          1. Выполните команду:
      
              ```bash
              terraform destroy
              ```
      
          1. Подтвердите удаление ресурсов и дождитесь завершения операции.
      
          Все ресурсы, которые были описаны в Terraform-манифестах, будут удалены.

    {% endlist %}

## Перенос данных с помощью внешней репликации {#binlog-replication}

1. [Перенесите логический дамп базы данных](#migrate-schema).
1. [Настройте пользователя в кластере-источнике для управления репликацией](#configure-user).
1. [Запустите репликацию в кластере-приемнике](#start-replica).
1. [Отслеживайте процесс миграции](#monitor-migration) до его завершения.
1. [Закончите миграцию](#finish-migration).


### Необходимые платные ресурсы {#paid-resources-binlog-replication}

* Кластер Managed Service for MySQL®: выделенные хостам вычислительные ресурсы, объем хранилища и резервных копий ([тарифы Managed Service for MySQL®](../../managed-mysql/pricing.md)).
* Публичные IP-адреса, если для хостов кластера включен публичный доступ ([тарифы Virtual Private Cloud](../../vpc/pricing.md)).


### Перенесите логический дамп базы данных {#migrate-schema}

_Логический дамп_ — файл с набором команд, последовательное выполнение которых позволяет восстановить состояние базы данных. Он создается с помощью [утилиты mysqldump](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html). Чтобы обеспечить полноту логического дампа, перед его созданием приостановите запись в базу данных.

{% note warning %}

Если в базе данных есть пользовательские хранимые процедуры, для выполнения логического дампа [выдайте](../../managed-mysql/operations/grant.md#grant-privilege) владельцу БД административную привилегию [SHOW ROUTINE](../../managed-mysql/concepts/settings-list.md#setting-administrative-privileges).

{% endnote %}

1. Запросите текущую позицию бинарного лога для консистентности восстановления логического дампа:

    ```sql
    SHOW MASTER STATUS;
    ```

    ```text
    +-------------------------+----------+--------------+------------------+-----------------------------+
    | File                    | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set           |
    +-------------------------+----------+--------------+------------------+-----------------------------+
    | mysql-bin-log-...000224 |  2058567 |              |                  | d827098b-...00b86:1-1575866 |
    +-------------------------+----------+--------------+------------------+-----------------------------+
    1 row in set (0.00 sec)
    ```

    Запишите значения `File` и `Position`. Они понадобятся при запуске репликации.

1. Создайте дамп базы кластера-источника:

   ```bash
   mysqldump \
       --databases=<имя_БД> \
       --routines \
       --host=<FQDN_хоста-мастера> \
       --ssl-ca=<путь_к_SSL-сертификату> \
       --user=<имя_пользователя-владельца_БД> > <файл_дампа>
   ```

   {% note tip %}
   
   Используйте [особый FQDN](../../managed-mysql/concepts/network.md#fqdn-master), который всегда указывает на текущий хост-мастер в кластерах Managed Service for MySQL®.
   
   {% endnote %}

1. Восстановите базу данных из дампа в кластере-приемнике:

    {% list tabs group=connection %}

    - Подключение с SSL {#with-ssl}

       ```bash
       mysql --host=<FQDN_хоста-мастера> \
             --user=<имя_пользователя> \
             --password \
             --port=3306 \
             --ssl-ca=<путь_к_SSL-сертификату> \
             --ssl-mode=VERIFY_IDENTITY \
             --line-numbers \
             <имя_БД> < <файл_дампа>
       ```

    - Подключение без SSL {#without-ssl}

       ```bash
       mysql --host=<FQDN_хоста-мастера> \
             --user=<имя_пользователя> \
             --password \
             --port=3306 \
             --line-numbers \
             <имя_БД> < <файл_дампа>
       ```

    {% endlist %}

1. Создайте в кластере-приемнике пользователя с полными правами на доступ к переносимой базе данных:

   ```sql
   CREATE USER '<имя_пользователя>'@'%' IDENTIFIED BY '<пароль>';
   GRANT ALL PRIVILEGES ON <имя_БД>.* TO '<имя_пользователя>'@'%';
   ```

### Настройте пользователя в кластере-источнике для управления репликацией {#configure-user}

MySQL® использует модель <q>мастер-реплика</q> при выполнении репликации: кластер-приемник копирует изменения бинарного лога кластера-источника в свой лог, который называется логом ретрансляции (relay log). Хост-реплика воспроизводит изменения из лога ретрансляции, применяя их к собственным данным.

Чтобы получать изменения бинарного лога и управлять потоком репликации в кластере-источнике:
1. [Создайте пользователя](../../managed-mysql/operations/cluster-users.md#adduser).
1. [Назначьте роль](../../managed-mysql/operations/grant.md) `ALL_PRIVILEGES` этому пользователю на базу кластера-источника.
1. [Назначьте глобальные привилегии](../../managed-mysql/operations/cluster-users.md#update-settings) `REPLICATION CLIENT` и `REPLICATION SLAVE` этому пользователю.

Кластер-приемник будет подключаться к кластеру-источнику от имени этого пользователя.

### Запустите репликацию в кластере-приемнике {#start-replica}

1. Измените файл конфигурации кластера-приемника `/etc/mysql/my.cnf` для начала репликации:

   ```bash
   [mysqld]
   ...
   log_bin = mysql-bin
   server_id = 2
   relay-log = /var/lib/mysql/mysql-relay-bin
   relay-log-index = /var/lib/mysql/mysql-relay-bin.index

   gtid-mode = on
   enforce-gtid-consistency = on
   ```

   Где:

   * `log_bin` — имя бинарного лога в кластере-приемнике.
   * `server_id` — идентификатор кластера-приемника. Значение по умолчанию — `1`, но для репликации необходимо, чтобы значения идентификаторов кластера-источника и кластера-приемника различались.
   * `relay-log` — путь к логу ретрансляции.
   * `relay-log-index` — путь к индексу лога ретрансляции.

   Также для репликации включите настройки `gtid-mode` и `enforce-gtid-consistency`. В кластерах Managed Service for MySQL® они включены всегда.

1. Перезапустите сервис `mysql`:

    ```bash
    sudo systemctl restart mysql
    ```

1. Подключитесь к кластеру-приемнику от имени пользователя с полными правами на доступ к переносимой базе данных.
1. Включите репликацию базы данных и отключите репликацию служебных баз данных (по умолчанию они реплицируются):

   ```sql
   CHANGE REPLICATION FILTER
       REPLICATE_DO_DB=(
           <имя_БД_кластера-приемника>
       ),
       REPLICATE_IGNORE_DB=(
           sys,
           mysql,
           performance_schema,
           information_schema
       );
   ```

1. Чтобы назначить мастера для кластера-приемника, укажите параметры хоста-мастера кластера-источника:

   {% note tip %}
   
   Используйте [особый FQDN](../../managed-mysql/concepts/network.md#fqdn-master), который всегда указывает на текущий хост-мастер в кластерах Managed Service for MySQL®.
   
   {% endnote %}

   ```sql
   CHANGE MASTER TO
         MASTER_HOST = '<FQDN_хоста-мастера>',
         MASTER_USER = '<пользователь_для_репликации>',
         MASTER_PASSWORD = '<пароль_пользователя>',
         MASTER_LOG_FILE = '<значение_File_из_запроса_позиции_бинарного_лога>',
         MASTER_LOG_POS = <значение_Position_из_запроса_позиции_бинарного_лога>,
         MASTER_SSL_CA = '<путь_к_SSL-сертификату>',
         MASTER_SSL_VERIFY_SERVER_CERT = 0,
         MASTER_SSL = 1;
   ```

1. Запустите воспроизведение лога ретрансляции:

   ```sql
   START SLAVE;
   ```

   Начнется процесс миграции данных из базы кластера-источника в базу кластера-приемника.

1. После успешного запуска репликации однократно выполните команду:

   ```sql
   STOP SLAVE;
   CHANGE MASTER TO MASTER_AUTO_POSITION = 1;
   START SLAVE;
   ```

   Это необходимо, чтобы при смене мастера в кластере-источнике репликация корректно перенастроилась на новый хост-мастер. Подробнее о настройке смотрите в [документации MySQL®](https://dev.mysql.com/doc/refman/8.0/en/change-master-to.html).

### Отслеживайте процесс миграции {#monitor-migration}

Используйте команду, которая показывает *статус репликации*:

```sql
SHOW SLAVE STATUS\G
```

```text
*************************** 1. row ***************************
           Slave_IO_State: Waiting for master to send event
              Master_Host: rc1a-hxk9audl********.mdb.yandexcloud.kz
              Master_User: replica-my
              Master_Port: 3306
            Connect_Retry: 60
          Master_Log_File: mysql-bin-log-rc1a-hxk9audl********-mdb-yandexcloud-net.000225
      Read_Master_Log_Pos: 1702815
           Relay_Log_File: 6b6d647a39b6-relay-bin.000084
            Relay_Log_Pos: 409
            ...
```

Сведения о статусе репликации содержатся в значениях следующих полей:

* `Slave_IO_State`, `Slave_SQL_Running_State` — состояние I/O потока бинарного лога и потока лога ретрансляции. При успешной репликации активны оба потока.
* `Read_Master_Log_Pos` — последняя позиция, прочитанная из лога хоста-мастера.
* `Seconds_Behind_Master` — отставание реплики от мастера (в секундах).
* `Last_IO_Error`, `Last_SQL_Error` — ошибки репликации.

Подробнее о статусе репликации смотрите в [документации MySQL®](https://dev.mysql.com/doc/refman/8.0/en/replication-administration-status.html).

### Закончите миграцию {#finish-migration}

1. Снимите нагрузку с кластера-источника и убедитесь, что приложение не пишет данные в базу кластера-источника. Для этого можно [изменить пользовательскую настройку кластера-источника](../../managed-mysql/operations/cluster-users.md#update-settings) `MAX_UPDATES_PER_HOUR` на `1`.
1. Дождитесь снижения до нуля характеристики `Seconds_Behind_Master`. Это значит, что на кластер-приемник перенесены все изменения, произошедшие в кластере-источнике после создания логического дампа.
1. Остановите репликацию в кластере-приемнике:

   ```sql
   STOP SLAVE;
   ```

1. Переключите нагрузку на кластер-приемник.
1. [Удалите пользователя](../../managed-mysql/operations/cluster-users.md#removeuser) для управления репликацией в кластере-источнике.
1. Удалите пользователя с полными правами на доступ к переносимой базе в кластере-приемнике, если он больше не нужен.