Статьи

mysqld_multi: как запустить несколько экземпляров MySQL

Первоначально написано Фернандо Лаударес

Необходимость иметь несколько экземпляров MySQL (известный процесс mysqld ), выполняющихся на одном и том же сервере одновременно прозрачным образом, вместо того, чтобы выполнять их в отдельных контейнерах / виртуальных машинах, не очень распространена. Тем не менее, время от времени команда поддержки Percona получает запрос от клиента для помощи в настройке такой среды. MySQL предоставляет инструмент для облегчения выполнения нескольких экземпляров, называемый mysqld_multi :

«Mysqld_multi предназначен для управления несколькими процессами mysqld, которые прослушивают соединения с различными файлами сокетов Unix и портами TCP / IP. Он может запускать или останавливать серверы или сообщать об их текущем состоянии ».

Для тестирования и разработки MySQL Sandbox может быть более практичным, и я лично предпочитаю использовать его для собственных тестов Оба инструмента работают вокруг запуска и управления несколькими процессами mysqld, но у Sandbox, как следует из названия, есть подход «песочницы», позволяющий легко создавать и размещать новый экземпляр (включая все данные внутри него). Чаще всего mysqld_multi используется на производственных серверах: он поставляется с серверным пакетом и использует тот же единственный файл конфигурации, на который люди обращают внимание при настройке MySQL. Итак, как это работает? Как мы настраиваем и управляем экземплярами? И, что важно, как мы создаем резервные копии всех созданных нами экземпляров?

Понимание концепции групп в my.cnf

Вы, возможно, уже заметили, что основной файл конфигурации MySQL (или « файл опций »), my.cnf, расположен под так называемой структурой группы : разделы, определяющие параметры конфигурации, специфичные для данной программы или цели. Обычно сама программа дает имя группе, которая отображается в квадратных скобках. Вот простой my.cnf, показывающий три такие группы:

[client]
port= 3306
socket= /var/run/mysqld/mysqld.sock
user            = john
password        = p455w0rd
[mysqld]
user= mysql
pid-file= /var/run/mysqld/mysqld.pid
socket= /var/run/mysqld/mysqld.sock
port= 3306
datadir= /var/lib/mysql
[xtrabackup]
target_dir = /backups/mysql/

Опции, определенные в группе [клиент] выше, используются  инструментом командной строки mysql  . Таким образом, если вы не укажете никакой другой параметр при выполнении  mysql, он попытается подключиться к локальному серверу MySQL через сокет в /var/run/mysqld/mysqld.sock и использовать учетные данные, указанные в этой группе. Аналогично,  mysqld  будет искать опции, определенные в своем разделе при запуске, и то же самое происходит с Percona XtraBackup, когда вы запускаете резервное копирование с помощью этого инструмента. Однако рабочие параметры, определенные вышеупомянутыми группами, также могут быть указаны как параметры командной строки во время выполнения программы, и в этом случае они заменяют параметры, определенные в my.cnf.

Начало работы с несколькими экземплярами

Чтобы запустить несколько экземпляров MySQL, мы должны заменить группу [mysqld] в файле конфигурации my.cnf на столько групп [mysql N ], сколько мы хотим, чтобы экземпляры работали, причем «N» — положительное целое число, также называемое номером группы опций , Этот номер используется mysqld_multi для идентификации каждого экземпляра, поэтому он должен быть уникальным для всего сервера. Помимо отдельного имени группы, те же параметры, которые действительны для [mysqld], применяются к [mysqld N] групп, разница в том, что их указание необязательно для [mysqld] (можно запустить MySQL с пустым my.cnf, так как используются значения по умолчанию, если не указано явно), некоторые из них (например, socket, port, pid-file) и datadir) обязательны при определении нескольких экземпляров, поэтому они не наступают друг другу на ноги. Вот простой модифицированный my.cnf, показывающий исходную группу [mysqld] плюс два других экземпляра:

[mysqld]
user= mysql
pid-file= /var/run/mysqld/mysqld.pid
socket= /var/run/mysqld/mysqld.sock
port= 3306
datadir= /var/lib/mysql
[mysqld1]
user= mysql
pid-file= /var/run/mysqld/mysqld1.pid
socket= /var/run/mysqld/mysqld1.sock
port= 3307
datadir= /data/mysql/mysql1
[mysqld7]
user= mysql
pid-file= /var/run/mysqld/mysqld7.pid
socket= /var/run/mysqld/mysqld7.sock
port= 3308
datadir= /data/mysql/mysql7

Кроме того , используя различные Pid файлы, порты и разъемы для новых экземпляров я также определили различные DATADIR для каждого — это очень важно , что экземпляры этого не одни и те же DATADIR . Скорее всего, вы импортируете данные из резервной копии, но если это не так, вы можете просто использовать mysql_install_db для создания каждого дополнительного каталога данных (но убедитесь, что родительский каталог существует и что у пользователя mysql есть права на запись в него):

mysql_install_db --user=mysql --datadir=/data/mysql/mysql7

Обратите внимание, что если / data / mysql / mysql7 не существует и вы в любом случае запускаете этот экземпляр, myqld_multi сам вызовет mysqld_install_db, чтобы создать каталог данных и установить в нем системные таблицы. В качестве альтернативы, восстановив резервную копию или создав новый каталог данных, вы можете сделать физическую копию существующего из основного экземпляра — просто обязательно сначала остановите его с чистым завершением работы, чтобы все ожидающие изменения были сброшены на диск в первую очередь.

Теперь вы, возможно, заметили, что я писал выше, что вам нужно заменить исходную группу экземпляров MySQL ([mysqld]) на группу с номером группы опций ([mysql N ]). Это не совсем так, поскольку они могут сосуществовать в гармонии. Однако обычный скрипт запуска / остановки, используемый для управления MySQL, не будет работать с дополнительными экземплярами, и mysqld_multi действительно не управляет [mysqld]. Простое решение здесь состоит в том, чтобы переименовать группу [mysqld] с суффиксным целым числом, скажем, [mysqld0] (вам не нужно вносить какие-либо изменения в ее текущие параметры), и позволить mysqld_multi управлять всеми экземплярами.

Две команды, которые могут оказаться полезными при настройке нескольких экземпляров:

$ mysqld_multi --example

… Который предоставляет пример файла my.cnf, настроенного с несколькими экземплярами и показывающего использование различных параметров, и:

$ my_print_defaults --defaults-file=/etc/my.cnf mysqld7

… Который показывает, как данная группа («mysqld7» в примере выше) была определена в my.cnf.

Управление несколькими экземплярами

mysqld_multi позволяет запускать, останавливать, перезагружать (что фактически является перезапуском) и сообщать о текущем состоянии данного экземпляра, всех экземпляров или их подмножества. Наиболее важным наблюдением здесь является то, что действие «stop» управляется через mysqladmin — и внутренне это происходит на индивидуальной основе, с одним вызовом «mysqladmin… stop» на экземпляр, даже если у вас mysqld_multi остановит все из них. Чтобы это работало должным образом, вам нужно настроить учетную запись MySQL с привилегией SHUTDOWN, которая определена с одним и тем же именем пользователя и паролем во всех случаях. Да, это будет работать из коробки, если вы запустите mysqld_multi от имени пользователя root на только что установленном сервере, где пользователь root может получить доступ к MySQL без пароля во всех случаях. Но как руководство предполагает, что для этой цели лучше создать специальную учетную запись:

mysql> GRANT SHUTDOWN ON *.* TO 'multi_admin'@'localhost' IDENTIFIED BY 'multipass';
mysql> FLUSH PRIVILEGES;

Если вы планируете реплицировать каталог данных главного сервера на другие ваши экземпляры, вы можете создать эту учетную запись, прежде чем создавать ее копии, в противном случае вам просто нужно подключиться к каждому экземпляру и создать аналогичную учетную запись (помните, привилегированная учетная запись является только необходим mysqld_multi для остановки экземпляров, а не для их запуска). В my.cnf можно использовать специальную группу для определения параметров mysqld_multi, которая должна использоваться для хранения этих учетных данных. Там вы также можете указать путь для бинарных файлов mysqladmin и mysqld (или mysqld_safe ), которые можно использовать, хотя у вас может быть определенный двоичный файл mysqld, определенный для каждого экземпляра в соответствующей группе. Вот один пример:

[mysqld_multi]
mysqld     = /usr/bin/mysqld_safe
mysqladmin = /usr/bin/mysqladmin
user       = multi_admin
password   = multipass

Вы можете использовать mysqld_multi, чтобы запускать, останавливать, перезапускать или сообщать о состоянии определенного экземпляра, всех экземпляров или их подмножества. Вот несколько примеров, которые говорят сами за себя:

$ mysqld_multi report
Reporting MySQL (Percona Server) servers
MySQL (Percona Server) from group: mysqld0 is not running
MySQL (Percona Server) from group: mysqld1 is not running
MySQL (Percona Server) from group: mysqld7 is not running
$ mysqld_multi start
$ mysqld_multi report
Reporting MySQL (Percona Server) servers
MySQL (Percona Server) from group: mysqld0 is running
MySQL (Percona Server) from group: mysqld1 is running
MySQL (Percona Server) from group: mysqld7 is running
$ mysqld_multi stop 7,0
$ mysqld_multi report 7
Reporting MySQL (Percona Server) servers
MySQL (Percona Server) from group: mysqld7 is not running
$ mysqld_multi report
Reporting MySQL (Percona Server) servers
MySQL (Percona Server) from group: mysqld0 is not running
MySQL (Percona Server) from group: mysqld1 is running
MySQL (Percona Server) from group: mysqld7 is not running

Управление демоном MySQL

Чего здесь не хватает, так это сценария инициализации для автоматизации запуска / остановки всех экземпляров при инициализации / завершении работы сервера; теперь, когда мы используем mysqld_multi для управления экземплярами, обычный /etc/init.d/mysql больше не будет работать. Но аналогичный скрипт запуска (хотя и намного более простой и менее надежный), использующий mysqld_multi, предоставляется вместе с MySQL / Percona Server, который можно найти в /usr/share/<mysql|percona-server>/mysqld_multi.server. Вы можете просто скопировать его как /etc/init.d/mysql, эффективно заменив оригинальный скрипт, сохранив его имя. Пожалуйста, обратите внимание:Возможно, вам придется сначала отредактировать его и изменить первые две строки, определяющие «basedir» и «bindir», так как этот сценарий не предназначен для определения хороших рабочих значений для этих переменных, которые являются исходными для одного экземпляра / etc / init. d / mysql делает. Учитывая, что в / usr / bin установлен mysqld_multi, достаточно установить следующие переменные:

basedir=/usr
bindir=/usr/bin

Конфигурирование экземпляра с другой версией MySQL

Если вы планируете запускать несколько экземпляров MySQL одновременно, возможно, вы захотите использовать разные версии для каждой из них, например, во время цикла разработки для проверки совместимости приложений. Это обычное использование mysqld_multi и достаточно простое для достижения. Чтобы продемонстрировать его использование, я скачал последнюю доступную версию MySQL 5.6 и извлек файл TAR в / opt:

$ tar -zxvf mysql-5.6.20-linux-glibc2.5-x86_64.tar.gz -C /opt

Затем я сделал холодную копию dadadir из одного из существующих экземпляров в / data / mysql / mysqld574:

$ mysqld_multi stop 0
$ cp -r /data/mysql/mysql1 /data/mysql/mysql5620
$ chown mysql:mysql -R /data/mysql/mysql5620

и добавил новую группу в my.cnf следующим образом:

[mysqld5620]
user            = mysql
pid-file        = /var/run/mysqld/mysqld5620.pid
socket          = /var/run/mysqld/mysqld5620.sock
port            = 3309
datadir         = /data/mysql/mysql5620
basedir         = /opt/mysql-5.6.20-linux-glibc2.5-x86_64
mysqld          = /opt/mysql-5.6.20-linux-glibc2.5-x86_64/bin/mysqld_safe

Обратите внимание на использование basedir, указывающее на путь, куда были извлечены двоичные файлы для MySQL 5.6.20, а также определенный mysqld для использования с этим экземпляром. Если вы сделали копию каталога данных из экземпляра, на котором запущена предыдущая версия MySQL / Percona Server, вам нужно будет рассмотреть тот же подход, который используется при обновлении и запустить  mysql_upgrade .

* Я пытался использовать последний экспериментальный выпуск MySQL 5.7 (mysql-5.7.4-m14-linux-glibc2.5-x86_64.tar.gz), но он потерпел крах с:

*** glibc detected *** bin/mysqld: double free or corruption (!prev): 0x0000000003627650 ***

Использование обычных инструментов для запуска и остановки экземпляра

Хотя mysqld_multi облегчает управление в целом, давайте не будем забывать, что это обертка; Вы все еще можете полагаться (хотя и не всегда, как показано ниже) на обычные инструменты для запуска и остановки экземпляра: mysqld * и mysqladmin. Просто убедитесь, что вы используете параметр  –defaults-group-суффикс, чтобы определить, какой экземпляр вы хотите запустить:

mysqld --defaults-group-suffix=5620

и –socket для обозначения того, кого вы хотите остановить:

$mysqladmin -S /var/run/mysqld/mysqld5620.sock shutdown

* Однако mysqld не будет работать для запуска экземпляра, если вы переопределили параметр «mysqld» в группе конфигурации, как я сделал для [mysqld5620] выше, заявив:

[ERROR] mysqld: unknown variable 'mysqld=/opt/mysql-5.6.20-linux-glibc2.5-x86_64/bin/mysqld_safe'

Я протестировал использование «ledir», чтобы указать путь к каталогу, содержащему двоичные файлы для MySQL 5.6.20 вместо «mysqld», но он также потерпел неудачу с похожей ошибкой. Если ничего другого, это показывает, что вам нужно придерживаться mysqld_multi при запуске экземпляров в среде со смешанной версией.

Резервные копии

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

$ mysqldump --socket=/var/run/mysqld/mysqld7.sock --all-databases > mysqld7.sql

В Percona XtraBackup есть опция с именем   –defaults-group, которая должна использоваться в средах, в которых запущено несколько экземпляров, чтобы указать, какой из них вы хотите сделать резервную копию:

$ innobackupex --defaults-file=/etc/my.cnf --defaults-group=mysqld7 --socket=/var/run/mysqld/mysqld7.sock /root/Backup/

Да, вам также необходимо указать путь к сокету (при локальном запуске команды), даже если эта информация уже доступна в «–defaults-group = mysqld7»; оказывается, что только инструмент Percona XtraBackup (который вызывается innobackupex в процессе резервного копирования) использует информацию, доступную в параметре группы. Вам также может потребоваться предоставить учетные данные («–user» и «–password»), и не забывайте, что впоследствии вам потребуется подготовить резервную копию. Опция «группа по умолчанию» доступна не во всех версиях Percona XtraBackup, поэтому обязательно используйте самую последнюю версию.

Резюме

Запуск нескольких экземпляров MySQL одновременно на одном и том же сервере прозрачно и без какой-либо контекстуализации или уровня виртуализации возможен как с mysqld_multi, так и с MySQL Sandbox. Мы воспользовались последним в службе поддержки Percona, чтобы быстро подключать новые одноразовые экземпляры (хотя вы могли бы так же легко сохранять их работающими бесконечно). В этом посте я рассмотрел mysqld_multi, который поставляется с сервером MySQL и остается официальным решением для обеспечения среды с несколькими экземплярами.

Ключевым аспектом при настройке нескольких экземпляров в my.cnf является понятие опции имени группы, поскольку вы заменяете один раздел [mysqld] на столько разделов [mysqld N ], сколько вы хотите, чтобы экземпляры работали. Однако важно уделять внимание некоторым деталям при определении параметров для каждой из этих групп, особенно при смешивании экземпляров из разных версий MySQL / Percona Server . В отличие от MySQL Sandbox, где каждый экземпляр опирается на свой собственный файл конфигурации, вы должны быть осторожны каждый раз, когда редактируете общий файл my.cnf как синтаксическую ошибку, когда настройка одного параметра группы препятствует запуску всех экземпляров на сервере ( ) инициализации.

Я надеюсь, что здесь были рассмотрены основные моменты, связанные с mysqld_multi, но не стесняйтесь оставлять нам примечание ниже, если у вас есть что добавить или оставить комментарий.