Workstation Logo
Продукты
AI LabsАгенты OpenAIАгенты ClaudeGrok BotWorkstation CRM (WSL CRM)МаркетингВсе продукты
Решения ИИ
Рабочие станции ИИAI SME PackagesЧастный ИИКластеры GPUПограничный ИИЛаборатория корпоративного ИИИИ по отраслям
Услуги
Platform ModernisationDigital EngineeringData Foundations & AIAutonomous OperationsИИ-консалтингАвтоматизация DevOpsКибербезопасностьРазработка ПОСоздание агентовНастройка MLOps
О нас
ПартнёрыИстории клиентов
Статьи
Документация
WSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7
Блог
Связаться с намиLogin
Workstation

AI-рабочие станции, мультиагентное AI-ПО, GPU-инфраструктура и решения на базе интеллектуальных агентов для современного бизнеса.

Связаться с нами

AI-решения

Рабочие станции ИИAI SME PackagesЧастный ИИКластеры GPUПограничный ИИЛаборатория корпоративного ИИИИ по отраслям

Продукты

Все продуктыWSL CRM и ERPМаркетингАгенты OpenAIWSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7

Компания

О насПочему WorkstationПартнёрыИстории клиентовЦеныКонтакты

Ресурсы

СтатьиДокументацияБлогПоискКарта сайта
Офис в Великобритании
77-79 Marlowes, Hemel Hempstead HP1 1LFКак добраться: съезд 20 с трассы M25, Внешний ЛондонРег. номер компании: 11641870Пн - Пт: 9:00 - 18:00 GMT
+44 7515 356 146
Офис в Бельгии
Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, BrusselsBE 0751.518.683Пн - Пт: 9:00 - 18:00 CET
+32 492 45 67 46
Офис в Индии
#159 Sector 9, Pocket 1, DDA Flats, 110077 Dwarka, New Delhi
+91 98881 98841

© 2026 Workstation AI. Все права защищены.

КонфиденциальностьФайлы cookieУсловия использованияКарта сайта

Loading blog...

Home / Blog
DatabaseKubernetesDevOpsBackend

Высокая доступность MySQL в производстве: кластер InnoDB, групповая репликация и операторы Kubernetes

Руководство инженера-технолога по кластеру InnoDB, групповой репликации, оператору MySQL для Kubernetes, кластеру Percona XtraDB, многооблачным стратегиям и развертываниям k3s/Rancher на «голом железе» с хранилищем Longhorn.

Balinder Walia12 апреля 2026 г.26 min read

Использование MySQL в производственной среде знакомо большинству инженерных групп. Запуск его с подлинно высокой доступностью — когда сбой узла, сетевой раздел или выход из строя всей зоны доступности не приводит к простою или потере данных — требует продуманной архитектуры. В этом руководстве рассматриваются все уровни этой архитектуры: от примитивов репликации внутри самого MySQL, операторов Kubernetes, которые автоматизируют управление жизненным циклом, управляемых и самоуправляемых опций каждого крупного поставщика облачных услуг и вплоть до «голых» кластеров k3s, управляемых Rancher.

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

MySQL Кластерная архитектура InnoDB

InnoDB Cluster — это интегрированное решение Oracle высокой доступности для MySQL. Оно объединяет три компонента: групповую репликацию MySQL для синхронизации данных, оболочку MySQL для администрирования кластера и маршрутизатор MySQL для прозрачной маршрутизации соединений и автоматического переключения при сбое. Вместе они образуют самовосстанавливающийся кластер, который может выдерживать сбои узлов без ручного вмешательства.

Кластер MySQL InnoDB — архитектура высокой доступностиСерверы приложенийМаршрутизаторМаршрутизатор MySQLАвтоматическое аварийное переключение и усиление; Разделение чтения/записиУзлыЧтение/записьR/OR/OПервичный (Ч/З)MySQL-узел-1Порт 3306/33061Вторичный (R/O)mysql-узел-2Порт 3306/33061Вторичный (R/O)mysql-узел-3Порт 3306/33061Групповая репликация (консенсус на базе Paxos)Кластер InnoDBПервичный (Ч/З)Вторичный (R/O)Маршрутизатор MySQLГрупповая репликация

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

Основы групповой репликации

MySQL Групповая репликация является основой кластера InnoDB. Он использует протокол консенсуса на основе Paxos, чтобы гарантировать, что каждая транзакция, совершенная на основном узле, реплицируется на большинство узлов перед подтверждением. Это обеспечивает виртуальную синхронную репликацию— гарантию того, что зафиксированные данные существуют как минимум на большинстве элементов кластера на момент фиксации.

Групповая репликация

работает в двух режимах:

  • Одноосновной режим— один узел принимает запись (основной); все остальные являются вторичными устройствами только для чтения. Это рекомендуемый режим по умолчанию. Он полностью позволяет избежать конфликтов записи, поскольку только один узел может генерировать транзакции.
  • Многоосновной режим— все узлы принимают записи одновременно. Это обеспечивает более высокую пропускную способность записи для рабочих нагрузок, которые четко распределяют данные по разным таблицам или пространствам ключей, но при этом возникает вероятность конфликтов сертификации, когда одновременные транзакции изменяют одни и те же строки. Конфликтующие транзакции откатываются на одном узле. Используйте multi-primary только в том случае, если ваше приложение предназначено для обработки ошибок сертификации и логики повторных попыток.

Настройка кластера InnoDB с оболочкой MySQL

MySQL Shell предоставляет AdminAPI — набор функций, которые автоматизируют весь жизненный цикл кластера. Вот полная последовательность настройки для кластера из 3 узлов.

# Step 1: Prepare each MySQL instance (run on all 3 nodes)
# Ensure my.cnf has required settings
[mysqld]
server-id=1                          # unique per node: 1, 2, 3
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
binlog_transaction_dependency_tracking=WRITESET
transaction_write_set_extraction=XXHASH64
loose-group_replication_start_on_boot=OFF
plugin_load_add='group_replication.so'
plugin_load_add='mysql_clone.so'
report_host='mysql-node-1'           # unique per node

# Step 2: Use MySQL Shell to configure and create the cluster
mysqlsh -- dba configure-instance root@mysql-node-1:3306 --clusterAdmin=gradmin --clusterAdminPassword='SecurePass123!'
mysqlsh -- dba configure-instance root@mysql-node-2:3306 --clusterAdmin=gradmin --clusterAdminPassword='SecurePass123!'
mysqlsh -- dba configure-instance root@mysql-node-3:3306 --clusterAdmin=gradmin --clusterAdminPassword='SecurePass123!'

# Step 3: Connect to the first node and create the cluster
mysqlsh gradmin@mysql-node-1:3306
# Inside MySQL Shell:
var cluster = dba.createCluster('productionCluster', {
    memberWeight: 90,
    exitStateAction: 'ABORT_SERVER',
    consistency: 'BEFORE_ON_PRIMARY_FAILOVER',
    expelTimeout: 10
})

# Step 4: Add remaining nodes
cluster.addInstance('gradmin@mysql-node-2:3306', {recoveryMethod: 'clone'})
cluster.addInstance('gradmin@mysql-node-3:3306', {recoveryMethod: 'clone'})

# Step 5: Verify cluster status
cluster.status()

ОпцияrecoveryMethod: 'clone'использует подключаемый модуль клонирования MySQL для выполнения полного копирования данных с основного на присоединяемый элемент, что намного быстрее, чем инкрементное восстановление из двоичных журналов для больших наборов данных.

Конфигурация маршрутизатора MySQL

Маршрутизатор MySQL загружается с кластера и автоматически создает файл конфигурации.

# Bootstrap MySQL Router against the cluster
mysqlrouter --bootstrap gradmin@mysql-node-1:3306 \
  --directory /opt/mysqlrouter \
  --conf-use-sockets \
  --user=mysqlrouter \
  --name='production-router'

# Start MySQL Router
/opt/mysqlrouter/start.sh

# Default ports after bootstrap:
# 6446 — R/W (routes to primary)
# 6447 — R/O (round-robin across secondaries)
# 6448 — R/W (X Protocol)
# 6449 — R/O (X Protocol)
Приложения

подключаются к порту R/W маршрутизатора для записи и к порту R/O для реплик чтения. При выходе из строя основного маршрутизатора маршрутизатор обнаруживает изменение топологии и меняет маршрут в течение нескольких секунд.

Многорегиональное развертывание MySQL

Для аварийного восстановления и чтения с малой задержкой в разных географических регионах MySQL можно развернуть в нескольких регионах. InnoDB ClusterSet расширяет InnoDB Cluster для поддержки асинхронной репликации между основным кластером и одним или несколькими кластерами реплик в разных регионах.

Многорегиональное развертывание MySQL с помощью InnoDB ClusterSetСША-восток-1 (AWS)ПЕРВИЧНЫЙ КЛАСТЕРПервичный (Ч/З)ВторичныйВторичныйМаршрутизатор MySQLГрупповая репликацияСистема хранения данных EBS gp3/io2eu-west-1 (Azure)РЕПЛИКА КЛАСТЕРАОсновной (резервный)ВторичныйВторичныйМаршрутизатор MySQLГрупповая репликацияУправляемые диски Azureap-юго-восток-1 (GCP)РЕПЛИКА КЛАСТЕРАОсновной (резервный)ВторичныйВторичныйМаршрутизатор MySQLГрупповая репликацияПостоянный диск SSDАсинхронныйАсинхронныйГлобальный диспетчер трафика / маршрутизация на базе DNSRoute53/Azure Менеджер трафика/облако DNSПервичный кластерКластеры репликАсинхронная репликация

InnoDB ClusterSet работает с одним основным кластером, который обрабатывает все записи, и одним или несколькими кластерами реплик, которые получают изменения асинхронно. В случае аварии кластер реплик можно повысить до основного с помощью MySQL Shell.

# Create a ClusterSet from an existing InnoDB Cluster
mysqlsh gradmin@mysql-node-1:3306
var cluster = dba.getCluster()
var cs = cluster.createClusterSet('globalSet')

# Create a replica cluster in eu-west region
cs.createReplicaCluster('gradmin@mysql-eu-node-1:3306', 'euWestCluster', {
    recoveryMethod: 'clone'
})
var euCluster = cs.getCluster('euWestCluster')
euCluster.addInstance('gradmin@mysql-eu-node-2:3306', {recoveryMethod: 'clone'})
euCluster.addInstance('gradmin@mysql-eu-node-3:3306', {recoveryMethod: 'clone'})

# Emergency failover (when primary cluster is unreachable)
cs.forcePrimaryCluster('euWestCluster')

MySQL на Kubernetes — шаблон оператора

Для запуска MySQL на Kubernetes необходимо решить несколько задач, которые не применимы к рабочим нагрузкам без отслеживания состояния: стабильные сетевые идентификаторы, постоянное хранилище, упорядоченный запуск и завершение работы, а также проверки работоспособности с учетом кластера. Операторы Kubernetes кодируют эти специфичные для предметной области эксплуатационные знания в контроллере, который наблюдает за пользовательскими ресурсами и согласовывает фактическое состояние MySQL с желаемым состоянием, заявленным в YAML.

MySQL на Kubernetes — архитектура оператораКластер KubernetesПользовательский ресурсInnoDBCluster CRРеплики: 3, маршрутизатор: 2ОператорчасыОператор MySQLКонтроллер/консилерУправляет жизненным циклом и аварийное переключениесоздаетКарта конфигурацииУслугиКарта конфигурацииУслугиКластерIP/безголовыйStatefulSet: mysqlУпорядоченное управление модулями, стабильные идентификаторыmysql-0 (основной)mysqld + коляскаR/W — порт 3306mysql-1 (вторичный)mysqld + коляскаR/O — порт 3306mysql-2 (вторичный)mysqld + коляскаR/O — порт 3306PVC: данные-mysql-0PVC: данные-mysql-1PVC: данные-mysql-2Класс хранилища: gp3/премиум-ssd/longhornПоставщик: ebs.csi / disk.csi / longhorn.ОператорStatefulSet

Оператор MySQL для Kubernetes (Oracle)

Оператор Oracle MySQL для Kubernetes развертывает и управляет экземплярами кластера InnoDB непосредственно на Kubernetes. Он создает наборы StatefulSet для модулей серверов MySQL, развертывания для маршрутизатора MySQL и обрабатывает автоматическое переключение при сбое, масштабирование, резервное копирование и изменения конфигурации.

# Install the MySQL Operator via Helm
helm repo add mysql-operator https://mysql.github.io/mysql-operator/
helm repo update

helm install mysql-operator mysql-operator/mysql-operator \
  --namespace mysql-operator \
  --create-namespace \
  --set image.pullPolicy=IfNotPresent

После запуска оператора разверните кластер InnoDB, создав собственный ресурс.

apiVersion: v1
kind: Secret
metadata:
  name: mysql-root-credentials
  namespace: production
stringData:
  rootUser: root
  rootHost: '%'
  rootPassword: 'ProductionSecurePass123!'
---
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
  name: production-mysql
  namespace: production
spec:
  secretName: mysql-root-credentials
  instances: 3
  tlsUseSelfSigned: true
  router:
    instances: 2
  datadirVolumeClaimTemplate:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 100Gi
    storageClassName: gp3-encrypted
  mycnf: |
    [mysqld]
    innodb_buffer_pool_size=4G
    innodb_log_file_size=1G
    innodb_flush_log_at_trx_commit=1
    sync_binlog=1
    max_connections=500
    innodb_io_capacity=2000
    innodb_io_capacity_max=4000
    innodb_read_io_threads=8
    innodb_write_io_threads=8
    performance_schema=ON
    slow_query_log=ON
    long_query_time=1
  podSpec:
    containers:
      - name: mysql
        resources:
          requests:
            cpu: "2"
            memory: 8Gi
          limits:
            cpu: "4"
            memory: 16Gi
    affinity:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
                - key: component
                  operator: In
                  values: [mysqld]
            topologyKey: topology.kubernetes.io/zone

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

Оператор Percona для MySQL (PXC)

Оператор Percona для MySQL развертывает Percona XtraDB Cluster (PXC), решение для синхронной репликации с несколькими первичными системами на основе Galera. PXC отличается от кластера InnoDB тем, что каждый узел может принимать записи (настоящий многоосновной), а репликация синхронна на уровне сертификации с использованием wsrep API.

# Install Percona Operator
helm repo add percona https://percona.github.io/percona-helm-charts/
helm repo update

helm install pxc-operator percona/pxc-operator \
  --namespace pxc \
  --create-namespace
# Percona XtraDB Cluster Custom Resource
apiVersion: pxc.percona.com/v1
kind: PerconaXtraDBCluster
metadata:
  name: production-pxc
  namespace: pxc
spec:
  crVersion: '1.14.0'
  secretsName: pxc-secrets
  pxc:
    size: 3
    image: percona/percona-xtradb-cluster:8.0.35
    resources:
      requests:
        memory: 8Gi
        cpu: "2"
      limits:
        memory: 16Gi
        cpu: "4"
    volumeSpec:
      persistentVolumeClaim:
        storageClassName: gp3-encrypted
        accessModes: [ReadWriteOnce]
        resources:
          requests:
            storage: 200Gi
    affinity:
      antiAffinityTopologyKey: topology.kubernetes.io/zone
    configuration: |
      [mysqld]
      innodb_buffer_pool_size=4G
      innodb_flush_log_at_trx_commit=1
      wsrep_provider_options="gcache.size=2G; gcs.fc_limit=256"
      wsrep_slave_threads=8
      wsrep_certify_nonPK=1
      wsrep_trx_fragment_size=10M
      max_connections=500
  haproxy:
    enabled: true
    size: 3
    image: percona/haproxy:2.8.5
    resources:
      requests:
        memory: 1Gi
        cpu: 500m
  proxysql:
    enabled: false
  backup:
    image: percona/percona-xtradb-cluster-operator:1.14.0-pxc8.0-backup-pxb8.0.35
    storages:
      s3-backup:
        type: s3
        verifyTLS: true
        s3:
          bucket: production-mysql-backups
          region: us-east-1
          credentialsSecret: aws-s3-credentials
    schedule:
      - name: daily-full
        schedule: "0 3 * * *"
        keep: 7
        storageName: s3-backup
      - name: hourly-incremental
        schedule: "0 * * * *"
        keep: 24
        storageName: s3-backup

Оператор Percona выполняет автоматическое резервное копирование на S3, восстановление на определенный момент времени, последовательные обновления, а также ProxySQL или HAProxy для маршрутизации соединений. Репликация на основе Galera в PXC обеспечивает настоящую синхронную запись с несколькими первичными узлами — каждая зафиксированная транзакция гарантированно существует на всех узлах.

Маршрутизация соединений

: маршрутизатор MySQL и ProxySQL

Маршрутизатор MySQL и ProxySQL служат прокси-серверами базы данных, но у них разные преимущества.

Маршрутизатор MySQLспециально создан для кластера InnoDB. Он считывает метаданные кластера, отслеживает изменения топологии и направляет соединения к правильному первичному или вторичному серверу. Его конфигурация минимальна и легко интегрируется с экосистемой MySQL. Недостатком является ограниченная маршрутизация на уровне запроса — она работает на уровне соединения, а не на уровне запроса.

ProxySQL— это прокси-сервер MySQL общего назначения с расширенными функциями: разделение чтения/записи на уровне запроса, кэширование запросов, мультиплексирование соединений, перезапись запросов и сложные правила маршрутизации. Он отлично подходит для сред, где вам необходим детальный контроль над распределением запросов.

# ProxySQL configuration for read/write splitting
# proxysql.cnf

mysql_servers:
(
    { hostgroup_id=10, hostname="mysql-primary", port=3306, max_connections=200, weight=1000 },
    { hostgroup_id=20, hostname="mysql-secondary-1", port=3306, max_connections=200, weight=500 },
    { hostgroup_id=20, hostname="mysql-secondary-2", port=3306, max_connections=200, weight=500 }
)

mysql_query_rules:
(
    { rule_id=1, active=1, match_digest="^SELECT .* FOR UPDATE$", destination_hostgroup=10, apply=1 },
    { rule_id=2, active=1, match_digest="^SELECT", destination_hostgroup=20, apply=1 },
    { rule_id=3, active=1, match_digest=".*", destination_hostgroup=10, apply=1 }
)

mysql_replication_hostgroups:
(
    { writer_hostgroup=10, reader_hostgroup=20, comment="InnoDB Cluster" }
)

В средах Kubernetes ProxySQL может работать как дополнительный контейнер в модулях приложений или как выделенное развертывание. Запуск его в качестве дополнительного модуля исключает сетевые переходы, но увеличивает использование ресурсов модуля; выделенным развертыванием легче управлять в масштабе.

Сравнение облачных провайдеров

: управляемый и самоуправляемый

AWS: RDS Multi-AZ, Aurora и самостоятельное управление на EKS

Amazon RDS Multi-AZобеспечивает автоматическое переключение при сбое между основным и резервным инстансом в разных зонах доступности. Аварийное переключение обычно занимает 60–120 секунд. Он использует синхронную физическую репликацию на резервный сервер. Реплики чтения можно добавлять для масштабирования чтения, но они используют асинхронную репликацию. RDS занимается резервным копированием, исправлениями и мониторингом, но ограничивает ваш контроль над конфигурацией MySQL и выбором версии.

Amazon Aurora MySQL— это облачная переработанная версия механизма хранения MySQL. Он отделяет вычисления от хранилища: уровень хранения представляет собой распределенную отказоустойчивую систему, которая реплицирует данные шестью способами в трех зонах доступности. Aurora обеспечивает аварийное переключение менее чем за 10 секунд, до 15 реплик чтения с минимальной задержкой репликации и автоматическое масштабирование хранилища до 128 ТиБ. В Aurora Serverless v2 добавлено автоматическое масштабирование вычислений для непредсказуемых рабочих нагрузок. Компромиссом является стоимость (Aurora на 20–40 % дороже, чем RDS) и ограниченная совместимость с некоторыми функциями MySQL.

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

# EKS StorageClass for MySQL with gp3 volumes
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gp3-encrypted
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "6000"
  throughput: "250"
  encrypted: "true"
  fsType: ext4
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
allowVolumeExpansion: true

Azure: гибкий сервер или самоуправляемый сервер на AKS

База данных Azure для гибкого сервера MySQLпредлагает зону высокой доступности с автоматическим переключением при сбое, реплики чтения в том же регионе и хранилище объемом до 16 ТиБ. Он поддерживает настраиваемые окна обслуживания, возможность остановки/запуска экземпляров (полезно для экономии затрат на разработку/тестирование) и интеграцию с Azure Private Link для изоляции сети. Уровень Business Critical обеспечивает наилучшую производительность при использовании локального SSD-накопителя.

с самостоятельным управлением на AKSиспользует управляемые диски Azure (твердотельный накопитель премиум-класса версии 2, рекомендуемый для рабочих нагрузок базы данных) с оператором MySQL или оператором Percona. AKS обеспечивает поддержку зон доступности и Azure CNI для интеграции виртуальной сети на уровне модуля.

# AKS StorageClass for MySQL
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: premium-ssd-zrs
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_ZRS
  cachingMode: None
  DiskIOPSReadWrite: "5000"
  DiskMBpsReadWrite: "200"
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
allowVolumeExpansion: true

Google Cloud: Cloud SQL против самостоятельного управления на GKE

Google Cloud SQL для MySQLпредлагает региональные экземпляры с автоматическим переключением при сбое между зонами, репликами чтения (в том числе между регионами) и автоматическим резервным копированием с восстановлением на определенный момент времени. Cloud SQL обеспечивает высочайший уровень удобства управления благодаря интеграции с IAM, VPC и экосистемой мониторинга Google. Уровень Enterprise Plus обеспечивает практически нулевое обслуживание и кэширование данных для повышения производительности чтения.

Самоуправляемый на GKEиспользует SSD-накопитель Persistent Disk или Hyperdisk для хранения данных. GKE Autopilot упрощает управление узлами и позволяет запускать оператор MySQL с минимальными эксплуатационными расходами.

# GKE StorageClass for MySQL
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ssd-regional
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
  replication-type: regional-pd
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
allowVolumeExpansion: true

Голый металл: k3s + Rancher + Longhorn

Не каждая рабочая нагрузка находится в общедоступном облаке. Для обеспечения суверенитета данных, соответствия требованиям, оптимизации затрат или требований к задержке кластеры Kubernetes без ОС, работающие под управлением k3s с управлением Rancher и системой хранения данных Longhorn, представляют собой платформу производственного уровня для MySQL HA.

Bare Metal k3s/Rancher MySQL Архитектура высокой доступностиСервер управления RancherОбеспечение кластера, мониторинг, RBACКластер k3sПлоскость управления (x3)etcd + Сервер API + ПланировщикМеталлLBБалансировщик нагрузки L2/BGPОператор MySQLOracle или PerconaРабочий узел 1mysql-0 (основной)CPU: 4 | Оперативная память: 16 ГБМодуль маршрутизатора MySQLОбъем Longhorn: 200 ГигабайтРабочий узел 2mysql-1 (вторичный)CPU: 4 | Оперативная память: 16 ГБМодуль маршрутизатора MySQLLonghorn Объем: 200 ГигабайтРабочий узел 3mysql-2 (вторичный)CPU: 4 | Оперативная память: 16 ГБМодуль маршрутизатора MySQLОбъем Longhorn: 200 ГигабайтРаспределенная система хранения данных Longhorn3 реплики на том | Снимки | Резервное копирование на S3/NFSNVMe SSD — узел 1NVMe SSD — узел 2NVMe SSD — узел 3

Установка и настройка k3s

k3s — это легкий сертифицированный дистрибутив Kubernetes, идеально подходящий для работы на периферии и на голом железе. Он объединяет все компоненты плоскости управления в один двоичный файл и использует SQLite или встроенный etcd для хранения состояния.

# Install k3s server (first control-plane node)
curl -sfL https://get.k3s.io | sh -s - server \
  --cluster-init \
  --tls-san 10.10.0.10 \
  --disable traefik \
  --disable servicelb \
  --write-kubeconfig-mode 644

# Join additional server nodes
curl -sfL https://get.k3s.io | K3S_TOKEN=$(cat /var/lib/rancher/k3s/server/node-token) sh -s - server \
  --server https://10.10.0.10:6443 \
  --tls-san 10.10.0.10

# Join worker nodes
curl -sfL https://get.k3s.io | K3S_URL=https://10.10.0.10:6443 \
  K3S_TOKEN=$(cat /var/lib/rancher/k3s/server/node-token) sh -s -

Система хранения данных Longhorn для MySQL

Longhorn — это облачная распределенная блочная система хранения данных, созданная для Kubernetes. Он реплицирует данные между узлами, предоставляет моментальные снимки и резервные копии, а также естественным образом интегрируется с драйвером Kubernetes CSI. Для MySQL Longhorn предоставляет постоянный, реплицируемый уровень хранения, который поставщики облачных услуг используют в своих предложениях по управляемым дискам.

# Install Longhorn
helm repo add longhorn https://charts.longhorn.io
helm repo update

helm install longhorn longhorn/longhorn \
  --namespace longhorn-system \
  --create-namespace \
  --set defaultSettings.defaultReplicaCount=3 \
  --set defaultSettings.storageMinimalAvailablePercentage=15 \
  --set defaultSettings.guaranteedInstanceManagerCPU=12

# StorageClass for MySQL on Longhorn
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-mysql
provisioner: driver.longhorn.io
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880"
  dataLocality: best-effort
  diskSelector: ssd
  fsType: ext4
reclaimPolicy: Retain
volumeBindingMode: Immediate
allowVolumeExpansion: true

MetalLB для балансировки нагрузки

На «голом железе» облачного балансировщика нагрузки нет. MetalLB заполняет этот пробел, назначая внешние IP-адреса службам Kubernetes типа LoadBalancer с использованием режима Layer 2 (ARP) или BGP.

# MetalLB IP Address Pool and L2 Advertisement
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: mysql-pool
  namespace: metallb-system
spec:
  addresses:
    - 10.10.0.100-10.10.0.110
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: mysql-l2
  namespace: metallb-system
spec:
  ipAddressPools:
    - mysql-pool
Стратегии резервного копирования и восстановления

Кластер высокой доступности защищает от сбоев узлов. Резервные копии защищают от повреждения данных, случайного удаления, ошибок приложений и сценариев аварийного восстановления, при которых теряется весь кластер. Вам нужны оба.

Логическое резервное копирование с помощью mysqldump

mysqldumpсоздает портативные и удобочитаемые резервные копии в формате SQL. Для баз данных размером менее 50 ГБ это самый простой вариант. Для больших наборов данных время блокировки и экспорта делает непрактичным их использование в рабочее время.

# Full logical backup with consistent snapshot
mysqldump --all-databases \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --set-gtid-purged=ON \
  --result-file=/backups/full-$(date +%Y%m%d-%H%M%S).sql

# Compressed backup piped to S3
mysqldump --all-databases --single-transaction | \
  gzip | aws s3 cp - s3://mysql-backups/full-$(date +%Y%m%d).sql.gz

Физическое резервное копирование с помощью Percona XtraBackup

Percona XtraBackup выполняет горячее неблокирующее физическое резервное копирование данных InnoDB. Он копирует файлы данных InnoDB, отслеживая журнал повторов, а затем применяет журнал повторов на этапе подготовки для создания согласованной резервной копии. Он значительно быстрее, чем mysqldump, для больших наборов данных и поддерживает инкрементное резервное копирование.

# Full physical backup
xtrabackup --backup \
  --target-dir=/backups/full \
  --user=backup_user \
  --password=SecureBackupPass \
  --parallel=4 \
  --compress \
  --compress-threads=4

# Incremental backup based on previous full
xtrabackup --backup \
  --target-dir=/backups/incr-$(date +%H) \
  --incremental-basedir=/backups/full \
  --user=backup_user \
  --password=SecureBackupPass

# Prepare (apply redo log) and restore
xtrabackup --prepare --target-dir=/backups/full
xtrabackup --prepare --target-dir=/backups/full \
  --incremental-dir=/backups/incr-01

# Copy back to data directory
xtrabackup --copy-back --target-dir=/backups/full --datadir=/var/lib/mysql
chown -R mysql:mysql /var/lib/mysql

Двоичный журнал (binlog) Восстановление на определенный момент времени

Двоичные журналы записывают каждую транзакцию, изменяющую данные. В сочетании с полным резервным копированием они обеспечивают восстановление на определенный момент времени (PITR) — восстановление до любого конкретного момента, а не только до момента создания последней резервной копии.

# Enable binlog retention (my.cnf)
[mysqld]
log_bin=mysql-bin
binlog_expire_logs_seconds=604800   # 7 days
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON

# Restore from backup then replay binlogs to a specific point
mysqlbinlog --start-datetime="2026-04-12 08:00:00" \
  --stop-datetime="2026-04-12 09:30:00" \
  mysql-bin.000042 mysql-bin.000043 | mysql -u root -p

# Or replay to a specific GTID position
mysqlbinlog --include-gtids="3c2d4f9e-d17e-ec59-9029-6aafa8accef8:1-5000" \
  mysql-bin.000042 | mysql -u root -p

Kubernetes Резервное копирование CronJob

В Kubernetes резервное копирование должно выполняться как CronJobs, а не как специальные команды. Это гарантирует, что резервное копирование автоматизировано, контролируется и может быть предупреждено в случае сбоя.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: mysql-backup
  namespace: production
spec:
  schedule: "0 2 * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 7
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      activeDeadlineSeconds: 7200
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: backup
              image: percona/percona-xtrabackup:8.0.35
              command:
                - /bin/sh
                - -c
                - |
                  BACKUP_DIR=/backups/$(date +%Y%m%d-%H%M%S)
                  mkdir -p $BACKUP_DIR
                  xtrabackup --backup \
                    --host=production-mysql.production.svc \
                    --user=backup_user \
                    --password=$BACKUP_PASSWORD \
                    --target-dir=$BACKUP_DIR \
                    --parallel=4 \
                    --compress
                  xtrabackup --prepare --target-dir=$BACKUP_DIR
                  # Upload to S3
                  aws s3 sync $BACKUP_DIR s3://mysql-backups/$(date +%Y%m%d)/
                  # Cleanup local
                  rm -rf $BACKUP_DIR
              env:
                - name: BACKUP_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: mysql-backup-credentials
                      key: password
              volumeMounts:
                - name: backup-scratch
                  mountPath: /backups
              resources:
                requests:
                  cpu: "1"
                  memory: 2Gi
                limits:
                  cpu: "2"
                  memory: 4Gi
          volumes:
            - name: backup-scratch
              emptyDir:
                sizeLimit: 100Gi

Мониторинг с помощью Percona Monitoring and Management (PMM)

Percona Monitoring and Management (PMM) — это платформа мониторинга с открытым исходным кодом, специально созданная для наблюдения за базами данных. В то время как Prometheus и Grafana обеспечивают общий мониторинг Kubernetes, PMM добавляет информацию, специфичную для MySQL: аналитику запросов (QAN), которая определяет медленные запросы, информационные панели задержек репликации, коэффициенты попадания в буферный пул InnoDB, конфликты за блокировку таблиц и многое другое.

# Deploy PMM Server on Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pmm-server
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pmm-server
  template:
    metadata:
      labels:
        app: pmm-server
    spec:
      containers:
        - name: pmm-server
          image: percona/pmm-server:2
          ports:
            - containerPort: 443
          env:
            - name: DISABLE_TELEMETRY
              value: "1"
          volumeMounts:
            - name: pmm-data
              mountPath: /srv
          resources:
            requests:
              cpu: "1"
              memory: 4Gi
            limits:
              cpu: "2"
              memory: 8Gi
      volumes:
        - name: pmm-data
          persistentVolumeClaim:
            claimName: pmm-data-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: pmm-server
  namespace: monitoring
spec:
  type: ClusterIP
  selector:
    app: pmm-server
  ports:
    - port: 443
      targetPort: 443
# Register MySQL instances with PMM Client (run on each MySQL pod or sidecar)
pmm-admin config --server-url=https://admin:password@pmm-server.monitoring:443 --server-insecure-tls
pmm-admin add mysql \
  --username=pmm_monitor \
  --password=MonitorPass123 \
  --host=127.0.0.1 \
  --port=3306 \
  --query-source=perfschema \
  --service-name=mysql-node-1
Аналитика запросов

PMM особенно ценна в производстве. Он фиксирует каждый запрос, выполняемый на сервере (через схему производительности или журнал медленных запросов), объединяет их по отпечаткам пальцев и показывает такие показатели, как средняя задержка, количество проверенных и отправленных строк, а также время блокировки. Таким образом вы определяете запросы, которые снижают производительность вашего приложения.

Настройка производственной конфигурации

Конфигурация MySQL по умолчанию настроена на небольшую рабочую нагрузку общего назначения. Производственные среды с выделенными серверами баз данных требуют совершенно других настроек. Вот критические параметры и способы их определения.

Буферный пул InnoDB

Буферный пул InnoDB — это место, где MySQL кэширует данные таблиц и индексов в памяти. Это единственный наиболее важный параметр конфигурации. Для выделенного сервера MySQL установите значение 70–80 % доступной оперативной памяти.

[mysqld]
# Memory: 16Gi container limit -> allocate ~12Gi to buffer pool
innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8          # 1 per GB (up to 64)
innodb_buffer_pool_chunk_size = 1536M     # pool_size / instances

Конфигурация журнала повторов

Журнал повторного выполнения поглощает записи до того, как они будут записаны в файлы данных. Журналы повторного выполнения большего размера уменьшают частоту сбросов контрольных точек и повышают пропускную способность записи. В MySQL 8.0.30+ используетсяinnodb_redo_log_capacityвместо более старогоinnodb_log_file_size.

[mysqld]
# MySQL 8.0.30+
innodb_redo_log_capacity = 4G

# MySQL 8.0.29 and earlier
# innodb_log_file_size = 2G
# innodb_log_files_in_group = 2

: компромисс между долговечностью и производительностью

Комбинацияinnodb_flush_log_at_trx_commitиsync_binlogопределяет вашу гарантию долговечности.

  • Максимальная долговечность(рекомендовано к производству):innodb_flush_log_at_trx_commit=1+sync_binlog=1. Каждая транзакция перед подтверждением записывается в журнал повторного выполнения и двоичный журнал на диске. Нулевая потеря данных при сбое.
  • Сбалансированный:innodb_flush_log_at_trx_commit=2+sync_binlog=1. Журнал повторов записывается в кэш ОС при каждом коммите, но сбрасывается на диск только один раз в секунду. При сбое ОС может быть потеряно до 1 секунды транзакций (сбой MySQL по-прежнему безопасен).
  • Максимальная производительность(не рекомендуется к производству):innodb_flush_log_at_trx_commit=0+sync_binlog=0. Записи периодически группируются и сбрасываются. Риск потери до 1 секунды транзакций при любом сбое.
[mysqld]
# Production durability settings
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
innodb_doublewrite = ON
innodb_checksum_algorithm = crc32
Конфигурация ввода-вывода

[mysqld]
# SSD-optimised I/O settings
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_flush_method = O_DIRECT
innodb_file_per_table = ON
innodb_open_files = 10000

Соединение и управление потоками

[mysqld]
max_connections = 500
max_connect_errors = 1000000
thread_cache_size = 64
table_open_cache = 4096
table_open_cache_instances = 16
back_log = 1500

# Thread pool (MySQL Enterprise or Percona)
thread_pool_size = 16
thread_pool_max_threads = 1000

Временные таблицы и буферы сортировки

[mysqld]
tmp_table_size = 64M
max_heap_table_size = 64M
sort_buffer_size = 4M
join_buffer_size = 4M
read_rnd_buffer_size = 2M

Шаблон полной производственной конфигурации

[mysqld]
# Identity
server-id = 1
report_host = mysql-node-1

# GTID Replication
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_format = ROW
log_bin = mysql-bin
binlog_expire_logs_seconds = 604800
log_slave_updates = ON
relay_log_recovery = ON

# InnoDB Engine
innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8
innodb_redo_log_capacity = 4G
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
innodb_doublewrite = ON
innodb_flush_method = O_DIRECT
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_file_per_table = ON
innodb_open_files = 10000
innodb_adaptive_hash_index = ON
innodb_change_buffering = all

# Connections
max_connections = 500
max_connect_errors = 1000000
thread_cache_size = 64
table_open_cache = 4096
table_open_cache_instances = 16
back_log = 1500

# Temp / Sort
tmp_table_size = 64M
max_heap_table_size = 64M
sort_buffer_size = 4M
join_buffer_size = 4M

# Monitoring
performance_schema = ON
slow_query_log = ON
long_query_time = 1
log_queries_not_using_indexes = ON
log_throttle_queries_not_using_indexes = 60

# Security
local_infile = OFF
skip_name_resolve = ON
default_authentication_plugin = caching_sha2_password

# Group Replication (InnoDB Cluster)
plugin_load_add = 'group_replication.so'
plugin_load_add = 'mysql_clone.so'
loose-group_replication_start_on_boot = OFF
loose-group_replication_bootstrap_group = OFF
loose-group_replication_recovery_use_ssl = ON
loose-group_replication_ssl_mode = REQUIRED

Тестирование аварийного переключения и хаос-инжиниринг

Система высокой доступности, которая никогда не тестировалась в условиях сбоя, не является действительно высокой доступностью — это гипотеза. Тестирование отказоустойчивости должно быть частью вашего обычного рабочего графика, а не чем-то, что вы обнаружите, что оно работает (или не работает) во время реального инцидента.

Тестирование управляемого аварийного переключения

# Test 1: Graceful primary failover (InnoDB Cluster)
mysqlsh gradmin@mysql-node-1:3306
var cluster = dba.getCluster()
cluster.setPrimaryInstance('gradmin@mysql-node-2:3306')
# Verify: cluster.status() should show node-2 as PRIMARY

# Test 2: Simulate primary crash
# On the primary node:
kill -9 $(pidof mysqld)
# Monitor: watch the cluster elect a new primary
# Verify: applications reconnect via MySQL Router within seconds

# Test 3: Network partition simulation
# On the primary node, block Group Replication port:
iptables -A INPUT -p tcp --dport 33061 -j DROP
iptables -A OUTPUT -p tcp --dport 33061 -j DROP
# The isolated node should be expelled; cluster continues with remaining members
# Cleanup:
iptables -D INPUT -p tcp --dport 33061 -j DROP
iptables -D OUTPUT -p tcp --dport 33061 -j DROP

# Test 4: Kubernetes pod deletion
kubectl delete pod mysql-0 -n production --grace-period=0 --force
# The StatefulSet controller recreates the pod
# The operator rejoins it to the cluster

Хаос-инжиниринг с помощью Litmus или Chaos Mesh

Инструменты структурированного хаоса систематически выявляют сбои и измеряют радиус взрыва. Chaos Mesh, проект CNCF, изначально интегрируется с Kubernetes.

# Chaos Mesh: Kill a MySQL pod randomly
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: mysql-pod-kill
  namespace: production
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app.kubernetes.io/component: mysqld
  scheduler:
    cron: "0 */4 * * *"
---
# Chaos Mesh: Network delay between MySQL pods
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: mysql-network-delay
  namespace: production
spec:
  action: delay
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app.kubernetes.io/component: mysqld
  delay:
    latency: "200ms"
    jitter: "50ms"
  duration: "5m"
  scheduler:
    cron: "30 */6 * * *"
---
# Chaos Mesh: Disk I/O stress
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
  name: mysql-io-latency
  namespace: production
spec:
  action: latency
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app.kubernetes.io/component: mysqld
  volumePath: /var/lib/mysql
  path: '*'
  delay: '100ms'
  percent: 50
  duration: '5m'

Что измерять во время тестов аварийного переключения

  • Целевое время восстановления (RTO)— Сколько времени проходит от обнаружения сбоя до восстановления обслуживания? Кластер InnoDB обычно достигает 5–30 секунд. Кластер Percona XtraDB может работать быстрее, поскольку здесь нет выборов (все узлы доступны для записи).
  • Целевая точка восстановления (RPO)— какой объем данных теряется во время аварийного переключения? При синхронной репликации (групповая репликация в одноосновном режиме, PXC) RPO для зафиксированных транзакций равен нулю. При асинхронной репликации (межрегиональный набор кластеров) RPO равен задержке репликации.
  • Частота ошибок приложений— Сколько запросов приложений терпят неудачу во время периода аварийного переключения? При этом проверяется не только аварийное переключение базы данных, но и логика повторных попыток подключения вашего приложения, а также скорость повторной маршрутизации маршрутизатора MySQL.
  • Время разрядки соединения— Сколько времени требуется существующим подключениям к старому основному устройству для разрядки и повторного подключения к новому основному устройству?

Runbook: контрольный список сбоев основного узла

  1. Убедитесь, что кластер выбрал новый основной узел:cluster.status()
  2. .
  3. Убедитесь, что маршрутизатор MySQL выполняет маршрутизацию к новому основному устройству: проверьте журналы маршрутизатора и количество подключений.
  4. Мониторинг задержки репликации на остальных вторичных серверах:SELECT * FROM performance_schema.replication_group_member_stats
  5. Если вышедший из строя узел можно восстановить, повторно присоединитесь к нему:cluster.rejoinInstance('gradmin@failed-node:3306')
  6. Если неисправный узел невозможно восстановить, удалите его и добавьте новый:cluster.removeInstance('gradmin@failed-node:3306', {force: true})
  7. Проверка работоспособности кластера: все участники ОНЛАЙН, ошибок репликации нет, расписание резервного копирования не повреждено
  8. Обновите свой план мощности: работа с двумя узлами означает нулевую отказоустойчивость до тех пор, пока третий не будет восстановлен.

Усиление безопасности

Производственное развертывание MySQL должно решать несколько проблем безопасности, помимо базовой аутентификации.

Шифрование при передаче и хранении

[mysqld]
# TLS for client connections
ssl_ca = /etc/mysql/certs/ca.pem
ssl_cert = /etc/mysql/certs/server-cert.pem
ssl_key = /etc/mysql/certs/server-key.pem
require_secure_transport = ON
tls_version = TLSv1.3

# Encryption at rest (InnoDB tablespace encryption)
early-plugin-load = keyring_file.so
keyring_file_data = /var/lib/mysql-keyring/keyring
innodb_undo_log_encrypt = ON
innodb_redo_log_encrypt = ON
default_table_encryption = ON

Секреты Kubernetes и запечатанные секреты

# Never store database credentials in plain YAML
# Use Sealed Secrets or an external secret manager
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: mysql-root-credentials
  namespace: production
spec:
  encryptedData:
    rootUser: AgBy3i4OJSWK+PiTy...
    rootPassword: AgCtr7pJ2XQWK+Pi...
  template:
    metadata:
      name: mysql-root-credentials
      namespace: production
    type: Opaque

Журнал аудита

[mysqld]
# MySQL Enterprise Audit (or Percona Audit Log plugin)
plugin-load-add = audit_log.so
audit_log_format = JSON
audit_log_policy = LOGINS
audit_log_rotate_on_size = 100M
audit_log_rotations = 10
Матрица решений

: выбор архитектуры высокой доступности MySQL

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

  • Единое облако, управляемые предпочтения, совместимость с MySQL— используйте Aurora (AWS), Flexible Server Business Critical (Azure) или Cloud SQL Enterprise Plus (GCP). Они обеспечивают минимальные эксплуатационные накладные расходы.
  • Единое облако с самоуправлением, требует полного управления MySQL.— используйте оператор MySQL или оператор Percona на EKS/AKS/GKE с собственными облачными классами хранения.
  • Мультиоблачное или гибридное облако— используйте оператор Percona с PXC или оператор MySQL с кластером InnoDB. Уровень абстракции Kubernetes делает развертывание MySQL переносимым в облаках.
  • Голый металл или край— используйте k3s с Rancher, хранилищем Longhorn, MetalLB и оператором MySQL или оператором Percona.
  • Максимальная пропускная способность записи, требуется несколько основных процессоров— используйте кластер Percona XtraDB (Galera) с оператором Percona. Все узлы принимают записи с синхронной сертификацией.
  • Глобальное распространение с аварийным восстановлением.— используйте InnoDB ClusterSet с асинхронной репликацией между регионами. Примите компромисс между RPO асинхронной репликации и преимуществами задержки при локальной записи.
Контрольный список эксплуатации

для производственного MySQL HA

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

  1. Состояние кластера— все участники сообщают о статусе ОНЛАЙН. Репликация группы не показывает ошибок.
  2. Автоматическое резервное копирование— CronJob или резервное копирование, управляемое оператором, выполняется по расписанию. Резервные копии проверены периодическими тестами восстановления.
  3. Мониторинг— PMM или Prometheus/Grafana для сбора показателей MySQL. Оповещения настроены для задержки репликации, насыщенности соединений, коэффициента попадания в буферный пул ниже 99 % и дискового пространства.
  4. Проверено аварийное переключение— основное аварийное переключение протестировано в течение последних 30 дней. RTO и RPO измерены и находятся в пределах целевых показателей SLA.
  5. Маршрутизация соединений— маршрутизатор MySQL или ProxySQL с проверкой работоспособности и балансировкой нагрузки. Строки подключения приложения указывают на маршрутизатор, а не на отдельные экземпляры MySQL.
  6. Безопасность— TLS требуется для всех подключений. Шифрование неактивных данных включено. Учетные данные хранятся в секретном менеджере. Ведение журнала аудита активно. Пользователи базы данных с наименьшими привилегиями для каждого приложения.
  7. Ограничения ресурсов— соответствующие запросы и ограничения ресурсов Kubernetes. PodDisruptionБюджеты на месте. Антисвязность модулей, распределяющая модули MySQL по зонам.
  8. План емкости— использование хранилища отслеживается с помощью предупреждений на уровне 70 % и 85 %. Расширение объема проверено. Документированы процедуры вертикального и горизонтального масштабирования.
  9. Runbook— документированные процедуры первичного переключения при сбое, замены узла, восстановления из резервной копии, обновления версии и аварийного режима только для чтения.
  10. Тестирование хаоса— запланированы регулярные эксперименты с хаосом для проверки предположений об устойчивости.

Заключение

Высокая доступность MySQL в производстве — это не просто выбор технологии — это система взаимосвязанных решений, охватывающая уровень репликации, платформу оркестрации, подсистему хранения, стек мониторинга и связанные с ними операционные процессы. Кластер InnoDB с групповой репликацией обеспечивает базовый примитив высокой доступности. Операторы Kubernetes из Oracle и Percona автоматизируют управление жизненным циклом, которое в противном случае потребовало бы значительного времени на разработку. Управление обменом облачными услугами для удобства. Развертывание «голого железа» с k3s, Rancher и Longhorn доказывает, что вам не нужен облачный провайдер для запуска MySQL HA промышленного уровня.

Наиболее важным моментом является то, что высокая доступность — это свойство всей системы, а не только базы данных. Сюда входит то, как ваше приложение обрабатывает сбои и повторные попытки подключения, как ваш прокси-уровень обнаруживает вышедшие из строя узлы и маршрутизирует их, как ваш мониторинг предупреждает об этом до того, как пользователи это заметят, как ваша стратегия резервного копирования обеспечивает восстановление в сценариях, с которыми не может справиться только HA, и как ваша команда практикует процедуры аварийного переключения, чтобы они выполнялись без ошибок в условиях реального инцидента.

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