[Документация Yandex Cloud](../../index.md) > [Yandex Managed Service for MySQL®](../index.md) > [Пошаговые инструкции](index.md) > Кластеры > Обновление версии MySQL®

# Обновление версии MySQL®

Вы можете обновить кластер Managed Service for MySQL® до любой поддерживаемой версии: минорной или мажорной.

В однохостовых кластерах на обновление выводится единственный хост-мастер. Во время обновления такие кластеры недоступны для чтения и записи, в отличие от кластеров из двух и более хостов. После возобновления работы СУБД потребуется время на «прогрев» буферного пула, что может временно повлиять на производительность запросов — это особенно заметно на больших базах данных с активным использованием индексов.

В многохостовых кластерах обновление проводится в следующем порядке:

1. Хосты-реплики последовательно выводятся на обновление и отключаются. Порядок реплик в очереди определяется случайным образом. После обновления реплики возвращаются в работу. На этом этапе возможно временное снижение производительности операций чтения, так как часть реплик будет недоступна.

1. Хост-мастер отключается и обновляется. На время обновления мастера его роль переходит к одной из реплик, которая открывается для записи. После завершения обновления мастером становится хост с наибольшим [приоритетом мастера](../concepts/replication.md#master-failover). Если в кластере есть несколько хостов с максимальным приоритетом, выбирается хост с наименьшим отставанием от мастера.

    Чтобы после обновления хост-мастер сохранил роль мастера, задайте для него наибольший приоритет мастера. Задать приоритет мастера можно при [создании кластера](cluster-create.md) или [изменении настроек хоста](hosts.md#update).

{% note info %}

В MySQL® версии 8.0 переключение реплик происходит более надежно и эффективно благодаря улучшенной обработке метаданных.

{% endnote %}

Об обновлениях в рамках одной версии и обслуживании хостов читайте в разделе [Техническое обслуживание](../concepts/maintenance.md).

{% note alert %}

* После обновления СУБД вернуть кластер к предыдущей версии невозможно.
* Обновляйте кластер в период низкой нагрузки на него — это снизит риски и уменьшит влияние на пользователей.
* Успешность обновления версии MySQL® зависит от многих факторов, например:

   * Настройки кластера и специфические конфигурации.
   * Особенности хранимых данных и их структуры.
   * Используемые возможности MySQL® (особенно JSON-функциональность и полнотекстовый поиск).
   * Совместимость приложений с новой версией.
   * Корректность хранимых процедур и триггеров.
   * Состояние текущей базы данных и качество данных.

   Рекомендуется сначала [обновить тестовый кластер](#before-update), который использует те же данные и настройки.

{% endnote %}

## Узнать доступные версии {#version-list}

{% list tabs group=instructions %}

- Консоль управления {#console}

    В [консоли управления](https://kz.console.yandex.cloud) откройте страницу [создания](cluster-create.md) или [изменения кластера](update.md) Managed Service for MySQL®. Список доступен в поле **Версия**.

- REST API {#api}

    1. [Получите IAM-токен для аутентификации в API](../api-ref/authentication.md) и поместите токен в переменную среды окружения:

        ```bash
        export IAM_TOKEN="<IAM-токен>"
        ```

    1. Воспользуйтесь методом [Versions.List](../api-ref/Versions/list.md) и выполните запрос, например, с помощью [cURL](https://curl.se/):

        ```bash
        curl \
            --request GET \
            --header "Authorization: Bearer $IAM_TOKEN" \
            --url 'https://mdb.api.yandexcloud.kz/managed-mysql/v1/versions'
        ```

    1. Убедитесь, что запрос был выполнен успешно, изучив [ответ сервера](../api-ref/Versions/list.md#responses).

- gRPC API {#grpc-api}

    1. [Получите IAM-токен для аутентификации в API](../api-ref/authentication.md) и поместите токен в переменную среды окружения:

        ```bash
        export IAM_TOKEN="<IAM-токен>"
        ```

    1. Клонируйте репозиторий [cloudapi](https://github.com/yandex-cloud/cloudapi):
       
       ```bash
       cd ~/ && git clone --depth=1 https://github.com/yandex-cloud/cloudapi
       ```
       
       Далее предполагается, что содержимое репозитория находится в директории `~/cloudapi/`.

    1. Воспользуйтесь вызовом [VersionsService.List](../api-ref/grpc/Versions/list.md) и выполните запрос, например, с помощью [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/versions_service.proto \
            -rpc-header "Authorization: Bearer $IAM_TOKEN" \
            mdb.api.yandexcloud.kz:443 \
            yandex.cloud.mdb.mysql.v1.VersionsService.List
        ```

    1. Убедитесь, что запрос был выполнен успешно, изучив [ответ сервера](../api-ref/grpc/Versions/list.md#yandex.cloud.mdb.mysql.v1.ListVersionsResponse).

{% endlist %}

## Перед обновлением версии {#before-update}

При подготовке к обновлению особенно важен комплексный подход к тестированию и анализу совместимости. Наш опыт показывает, что большинство проблем при обновлении можно предотвратить на этапе подготовки:

1. Посмотрите в [истории изменений](https://docs.percona.com/percona-server/8.0/release-notes/release-notes_index.html) MySQL®, как обновления могут повлиять на работу ваших приложений.

   {% cut "Примеры изменений в MySQL® 8.0" %}

   * Изменения в поведении SQL-функций и оптимизатора запросов:

      ```sql
      -- Пример запроса для анализа плана выполнения
      EXPLAIN ANALYZE
      SELECT * FROM <имя_таблицы>
      WHERE complex_condition
      ORDER BY <поле>;
      ```

   * Устаревшие и удаленные возможности, особенно в области безопасности:

      ```sql
      -- Проверка механизмов аутентификации
      SELECT user, host, plugin 
      FROM mysql.user 
      WHERE user NOT LIKE 'mysql.%';
      ```

   * Изменения в работе полнотекстового поиска и обработке JSON:

      ```sql
      -- Проверка использования JSON-функций
      SELECT COUNT(*) 
      FROM information_schema.routines 
      WHERE routine_definition LIKE '%JSON%';
      ```

   * Новые значения по умолчанию для настроек СУБД.
   * Особенности работы с метаданными и временными таблицами.

   {% endcut %}

1. Попробуйте обновить версию на тестовом кластере.
   
   1. Разверните тестовый кластер из резервной копии основного кластера, используя окружение `PRESTABLE`, и обновите его до нужной версии.
   1. Проверьте работу критичных запросов и хранимых процедур.
   1. Проверьте функционал, использующий JSON и полнотекстовый поиск.
   1. Проведите нагрузочное тестирование:

      ```sql
      -- Мониторинг производительности во время тестов
      SELECT EVENT_NAME, COUNT_STAR, AVG_TIMER_WAIT
      FROM performance_schema.events_statements_summary_by_digest
      WHERE SCHEMA_NAME = '<имя_базы_данных>'
      ORDER BY AVG_TIMER_WAIT DESC
      LIMIT 10;
      ```

1. [Создайте резервную копию](cluster-backups.md) основного кластера непосредственно перед обновлением.

1. Обеспечьте [высокую доступность](../concepts/high-availability.md) кластера:
   
   1. Убедитесь, что в основном и тестовом кластере есть хотя бы один мастер и одна реплика. При необходимости [добавьте хосты](hosts.md#add).
   1. (Опционально) Проверьте состояние репликации и задержки:

     ```sql
     -- Проверка статуса репликации
     SHOW SLAVE STATUS\G

     -- Проверка задержек репликации
     SELECT
       SUBSTRING_INDEX(HOST, ':', 1) AS slave_host,
       SUBSTRING_INDEX(HOST, ':', -1) AS slave_port,
       SECONDS_BEHIND_MASTER,
       SLAVE_IO_RUNNING,
       SLAVE_SQL_RUNNING
     FROM information_schema.PROCESSLIST
     WHERE COMMAND = 'Binlog Dump';
     ```

## Обновить версию MySQL® {#start-update}

{% list tabs group=instructions %}

- Консоль управления {#console}

   1. Перейдите в сервис **Managed Service for&nbsp;MySQL**.
   1. Выберите нужный кластер в списке и нажмите кнопку ![image](../../_assets/pencil.svg) **Редактировать**.
   1. В поле **Версия** выберите номер новой версии.
   1. Нажмите кнопку **Сохранить изменения**.

   После запуска обновления кластер переходит в статус **Updating**. Дождитесь окончания операции и проверьте версию кластера.

   Время обновления зависит от многих факторов, например от объема данных или количества баз данных в кластере. Обновление обычно занимает несколько минут, для больших БД — от 10 минут.

- CLI {#cli}

   Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), [установите и инициализируйте его](../../cli/quickstart.md#install).

   По умолчанию используется каталог, указанный при [создании](../../cli/operations/profile/profile-create.md) профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду `yc config set folder-id <идентификатор_каталога>`. Также для любой команды вы можете указать другой каталог с помощью параметров `--folder-name` или `--folder-id`. Если вы обращаетесь к ресурсу по имени, поиск будет выполнен в каталоге по умолчанию. Если вы обращаетесь к ресурсу по идентификатору, поиск будет выполнен глобально — во всех каталогах с учетом прав доступа.

   Чтобы обновить версию MySQL®:

   1. Получите список ваших кластеров MySQL® командой:

      ```bash
      yc managed-mysql cluster list
      ```

   1. Получите информацию о нужном кластере и проверьте версию MySQL®, указанную в свойстве `config.version`:

      ```bash
      yc managed-mysql cluster get <имя_или_идентификатор_кластера>
      ```

   1. Запустите обновление MySQL®:

      ```bash
      yc managed-mysql cluster update <имя_или_идентификатор_кластера> \
         --mysql-version <номер_новой_версии>
      ```

   Время обновления зависит от многих факторов, например от объема данных или количества баз данных в кластере. Обновление обычно занимает несколько минут, для больших БД — от 10 минут.

- Terraform {#tf}

   1. Откройте актуальный конфигурационный файл Terraform с планом инфраструктуры.

      Как создать такой файл описано в разделе [Создание кластера](cluster-create.md).

   1. Добавьте поле `version` в ресурс `yandex_mdb_mysql_cluster` или измените значение поля, если оно уже существует:

      ```hcl
      resource "yandex_mdb_mysql_cluster" "<имя_кластера>" {
         ...
         version = "<версия_MySQL®>"
         ...
      }
      ```

   1. Проверьте корректность настроек.

      1. В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры.
      1. Выполните команду:
      
         ```bash
         terraform validate
         ```
      
         Если в файлах конфигурации есть ошибки, Terraform на них укажет.

   1. Подтвердите изменение ресурсов.

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

   Подробнее о параметрах ресурса `yandex_mdb_mysql_cluster` смотрите в [документации провайдера](../../terraform/resources/mdb_mysql_cluster.md).

   {% note warning "Ограничения по времени" %}
   
   Провайдер Terraform ограничивает время на выполнение операций с кластером Managed Service for MySQL®:
   
   * создание кластера, в том числе путем восстановления из резервной копии, — 15 минут;
   * изменение кластера, в том числе обновление версии MySQL®, — 60 минут;
   * удаление кластера — 15 минут.
   
   Операции, длящиеся дольше указанного времени, прерываются.
   
   {% cut "Как изменить эти ограничения?" %}
   
   Добавьте к описанию кластера блок `timeouts`, например:
   
   ```hcl
   resource "yandex_mdb_mysql_cluster" "<имя_кластера>" {
     ...
     timeouts {
       create = "1h30m" # Полтора часа
       update = "2h"    # 2 часа
       delete = "30m"   # 30 минут
     }
   }
   ```
   
   {% endcut %}
   
   {% endnote %}

- REST API {#api}

   1. [Получите IAM-токен для аутентификации в API](../api-ref/authentication.md) и поместите токен в переменную среды окружения:

      ```bash
      export IAM_TOKEN="<IAM-токен>"
      ```

   1. Воспользуйтесь методом [Cluster.update](../api-ref/Cluster/update.md) и выполните запрос, например, с помощью [cURL](https://curl.se/):

      {% note warning %}
      
      Метод API переопределит все параметры изменяемого объекта, которые не были явно переданы в запросе, на значения по умолчанию. Чтобы избежать этого, перечислите настройки, которые вы хотите изменить, в параметре `updateMask` (одной строкой через запятую).
      
      {% endnote %}

      ```bash
      curl \
         --request PATCH \
         --header "Authorization: Bearer $IAM_TOKEN" \
         --header "Content-Type: application/json" \
         --url 'https://mdb.api.yandexcloud.kz/managed-mysql/v1/clusters/<идентификатор_кластера>' \
         --data '{
                   "updateMask": "configSpec.version",
                   "configSpec": {
                     "version": "<версия_MySQL®>"
                   }
                 }'
      ```

      Где:

      * `updateMask` — перечень изменяемых параметров в одну строку через запятую.

         В данном случае передается только один параметр.

      * `configSpec.version` — новая версия MySQL®.

      Идентификатор кластера можно запросить со [списком кластеров в каталоге](cluster-list.md#list-clusters).

   1. Убедитесь, что запрос был выполнен успешно, изучив [ответ сервера](../api-ref/Cluster/update.md#yandex.cloud.operation.Operation).

- gRPC API {#grpc-api}

   1. [Получите IAM-токен для аутентификации в API](../api-ref/authentication.md) и поместите токен в переменную среды окружения:

      ```bash
      export IAM_TOKEN="<IAM-токен>"
      ```

   1. Клонируйте репозиторий [cloudapi](https://github.com/yandex-cloud/cloudapi):
      
      ```bash
      cd ~/ && git clone --depth=1 https://github.com/yandex-cloud/cloudapi
      ```
      
      Далее предполагается, что содержимое репозитория находится в директории `~/cloudapi/`.
   1. Воспользуйтесь вызовом [ClusterService/Update](../api-ref/grpc/Cluster/update.md) и выполните запрос, например, с помощью [gRPCurl](https://github.com/fullstorydev/grpcurl):

      {% note warning %}
      
      Метод API переопределит все параметры изменяемого объекта, которые не были явно переданы в запросе, на значения по умолчанию. Чтобы избежать этого, перечислите настройки, которые вы хотите изменить, в параметре `update_mask` (в виде массива строк `paths[]`).
      
      {% cut "Формат перечисления настроек" %}
      
      ```yaml
      "update_mask": {
          "paths": [
              "<настройка_1>",
              "<настройка_2>",
              ...
              "<настройка_N>"
          ]
      }
      ```
      
      {% endcut %}
      
      {% endnote %}

      ```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": "<идентификатор_кластера>",
               "update_mask": {
                 "paths": [
                   "config_spec.version"
                 ]
               },
               "config_spec": {
                 "version": "<версия_MySQL®>"
               }
             }' \
         mdb.api.yandexcloud.kz:443 \
         yandex.cloud.mdb.mysql.v1.ClusterService.Update
      ```

      Где:

      * `update_mask` — перечень изменяемых параметров в виде массива строк `paths[]`.

         В данном случае передается только один параметр.

      * `config_spec.version` — новая версия MySQL®.

      Идентификатор кластера можно запросить со [списком кластеров в каталоге](cluster-list.md#list-clusters).

   1. Убедитесь, что запрос был выполнен успешно, изучив [ответ сервера](../api-ref/grpc/Cluster/create.md#yandex.cloud.operation.Operation).

{% endlist %}

Время обновления зависит от многих факторов, например от объема данных или количества баз данных в кластере. Обновление обычно занимает несколько минут, для больших БД — от 10 минут.

## Примеры {#examples}

Рассмотрим практический пример обновления кластера с версии 5.7 до 8.0. Этот сценарий особенно интересен, так как включает наиболее существенные изменения в архитектуре MySQL®.

{% list tabs group=instructions %}

- CLI {#cli}

   1. Получите список кластеров и узнайте их идентификаторы и имена:

      ```bash
      yc managed-mysql cluster list
      ```

      Пример результата:

      ```text
      +----------------------+------------+---------------------+--------+---------+
      |          ID          |    NAME    |     CREATED AT      | HEALTH | STATUS  |
      +----------------------+------------+---------------------+--------+---------+
      | c9q8p8j2gaih******** |  mysql406  | 2021-10-23 12:44:17 | ALIVE  | RUNNING |
      +----------------------+------------+---------------------+--------+---------+
      ```

   1. Получите детальную информацию о конкретном кластере:

      ```bash
      yc managed-mysql cluster get mysql406
      ```

      В выводе будет указана текущая версия MySQL®:

      ```text
        id: c9q8p8j2gaih********
        ...
        config:
          version: "5.7"
          ...
      ```

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

      ```bash
      yc managed-mysql cluster update mysql406 --mysql-version 8.0
      ```

      После выполнения этой команды начнется процесс обновления, который может занять от нескольких минут до часа, в зависимости от размера базы данных и конфигурации кластера.

- Terraform {#tf}

   1. Откройте актуальный конфигурационный файл Terraform с планом инфраструктуры.
   1. В поле `version` в ресурсе `yandex_mdb_mysql_cluster` укажите значение `8.0`:

      ```hcl
      resource "yandex_mdb_mysql_cluster" "<имя_кластера>" {
         ...
         version = "8.0"
         ...
      }
      ```

   1. Проверьте корректность настроек:

      1. В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры.
      1. Выполните команду:
      
         ```bash
         terraform validate
         ```
      
         Если в файлах конфигурации есть ошибки, Terraform на них укажет.

   1. Примените изменения:

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

   Terraform автоматически определит необходимость обновления версии и запустит процесс.

{% endlist %}

После успешного обновления:

1. Проверьте статус всех критичных компонентов:

   ```sql
   -- Проверка статуса InnoDB
   SHOW ENGINE INNODB STATUS\G

   -- Проверка состояния репликации
   SHOW SLAVE STATUS\G
   ```

1. Убедитесь в корректности работы приложений:

   * Проверьте время выполнения критичных запросов.
   * Проконтролируйте статистику ошибок.
   * Отследите использование ресурсов.

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

   ```sql
   -- Анализ использования буферного пула
   SELECT POOL_ID, POOL_SIZE, FREE_BUFFERS, DATABASE_PAGES
   FROM information_schema.INNODB_BUFFER_POOL_STATS;
   
   -- Проверка настроек производительности
   SHOW VARIABLES LIKE '%buffer%';
   ```

## Полезные ссылки {#see-also}

* [Технический обзор особенностей MySQL® 8.0](../concepts/mysql-57-80-comparison.md), рассматривающий изменения в производительности и функциональности новой версии.