Как-то раз появилась по работе задача — есть вроде как настроенный тестовый innoDB cluster на нескольких виртуалках с centos 7.5, надо его поизучать и добавить еще пару нод. Можно ломать и издеваться как угодно. Звучит заманчиво.
До этого у меня опыта работы с этим кластером не было, ну да гугл в помощь.
За несколькими исключениями, все ссылки что в нем, что в яндексе вели либо на dev.mysql.com, либо на эту статью на Хабре. Вроде как по ней и был настроен кластер из двух нод.
Чтож, статью я прочитал, несколько удивился сложности добавления нод и отсутствию многих подробностей, ну да ладно. Добавил с грехом пополам новую ноду (часть команд не пригодилась, часть вообще все ломала), после чего начал экспериментировать с перезапуском нод и т.д.
После нескольких подходов и бесчисленных смертей нервных клеток кластер не выдержал. Одна нода не хотела добавляться ни при каких условиях, другая зависала при попытке любого обращения к базе, третья делала вид, что все в порядке. Пришлось пристрелить и начать с нуля.
При создании нового кластера к сожалению возникла не меньшая куча проблем и нестыковок. Возможно дело в версиях программ, я пробовал mysql 5.7. Возможно в дистрибутиве. В итоге я прекратил бездумные потуги делать все по бумажке и стал настраивать его методом тыка. И гугла.
Пара приятных вечеров и ночей и кластер собрался и даже отказался рушиться.
При этом способ его создания заметно отличался от предыдущих попыток и мне захотелось им поделиться, т.к. на просторах интернета других актуальных подробных понятных инструкций по настройке inndoDB cluster я не нашел.
Итак, имеем три одинаковых виртуалки со свежеустановленным Centos 7.5 minimal 1804 и отключенными selinux и firewalld:
1.1.1.1
1.1.1.2
1.1.1.3
По работе я использовал mysql 5.7, так что ее и используем. Начнем с 1.1.1.1:
1. Установим репозиторий mysql-community:
rpm -i https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
Выключим репозиторий для 8, включим для 5.7 и проверим — если все ок, то устанавливаем mysql:
yum install yum-utils yum-config-manager --disable mysql80-community yum-config-manager --enable mysql57-community yum repolist yum install mysql-community-server mysql-shell
2. Приводим /etc/my.cnf к такому виду:
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid bind-address=0.0.0.0 port=3301 # Replication part server_id=1 gtid_mode=ON enforce_gtid_consistency=ON master_info_repository=TABLE relay_log_info_repository=TABLE binlog_checksum=NONE log_slave_updates=ON log_bin=binlog binlog_format=ROW plugin-load = group_replication.so # Group replication part transaction_write_set_extraction=XXHASH64 loose-group_replication_start_on_boot = OFF loose-group_replication_local_address = 1.1.1.1:33011 loose-group_replication_bootstrap_group = OFF report_port = 3301 report_host = 1.1.1.1
Здесь 3301 это порт, на котором будет слушать mysql, а 33011 порт, на котором ноды общаются между собой.
3. Запустим mysql и выполним предварительную настройку:
systemctl start mysqld grep 'password' /var/log/mysqld.log mysql_secure_installation
4. Ну и создадим кластер, а так же отдельного пользователя для управления им. Если вы знаете заранее ip-адреса нод, то можно их сразу перечислить в ipWhitelist. Сделаем вид, что мы пока не знаем про 1.1.1.2. и 1.1.1.3:
mysqlsh > \c 127.0.0.1:3301 > dba.configureLocalInstance("127.0.0.1:3301", {mycnfPath: "/etc/my.cnf", clusterAdmin: "cladmin", clusterAdminPassword: "SomePassword!123"}) > \c cladmin@1.1.1.1:3301 > dba.checkInstanceConfiguration() > cl=dba.createCluster('TestCluster', {ipWhitelist: '1.1.1.1'}) > dba.configureLocalInstance() > cl.status()
Готово! cl.status должен вывести что-то типа этого:
{ "clusterName": "TestCluster", "defaultReplicaSet": { "name": "default", "primary": "1.1.1.1:3301", "ssl": "REQUIRED", "status": "OK_NO_TOLERANCE", "statusText": "Cluster is NOT tolerant to any failures.", "topology": { "1.1.1.1:3301": { "address": "1.1.1.1:3301", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } }, "groupInformationSourceMember": "mysql://cladmin@1.1.1.1:3301" }
При изменении кластера надо будет выполнять на всех нодах локально команду dba.configureLocalInstance() для сохранения изменений:
WARNING: On instance '1.1.1.1:3301' membership change cannot be persisted since MySQL version 5.7.23 does not support the SET PERSIST command (MySQL version >= 8.0.11 required). Please use the <Dba>.configureLocalInstance command locally to persist the changes.
Т.к. мы собираемся добавить еще парочку нод, то не закрываем связь с сервером 1.1.1.1, он нам еще пригодится.
Теперь попробуем добавить в кластер ноду 1.1.1.2. Для этого выполняем на ней все те же команды до 3 шага включительно, не забывая поменять server_id, loose-group_replication_local_address и report_host.
4. Выполняем на 1.1.1.2:
mysql -p > set GLOBAL group_replication_allow_local_disjoint_gtids_join=ON;
Я пытался задавать эту переменную через mysqlsh, переключаясь в режим sql, но действия там никак не влияли на нее в mysql. Далее:
mysqlsh > \c 127.0.0.1:3301 > dba.configureLocalInstance("127.0.0.1:3301", {mycnfPath: "/etc/my.cnf", clusterAdmin: "cladmin", clusterAdminPassword: "SomePassword!123"}) > \c cladmin@1.1.1.2:3301 > dba.checkInstanceConfiguration()
5. Возвращаемся к первой ноде 1.1.1.1. Если закрыли соединение, то можно быстро подключиться к кластеру так:
mysqlsh --uri cladmin@1.1.1.1:3301 --cluster > \sql > STOP GROUP_REPLICATION; > SET GLOBAL group_replication_ip_whitelist="1.1.1.1,1.1.1.2"; > START GROUP_REPLICATION; > \js > cluster.addInstance('cladmin@1.1.1.2:3301', {ipWhitelist: '1.1.1.1,1.1.1.2'}) > cluster.status()
Почему-то при добавлении ноды без опции ipWhitelist он ей не передается автоматически, поэтому указываем вручную.
Если whitelist у вас изначально настроен на все ноды или подсеть, то команды в sql режиме можно пропустить.
Не забываем выполнить dba.configureLocalInstance() на всех нодах для сохранения конфигурации.
Получился кластер их двух нод:
{ "clusterName": "TestCluster", "defaultReplicaSet": { "name": "default", "primary": "1.1.1.1:3301", "ssl": "REQUIRED", "status": "OK_NO_TOLERANCE", "statusText": "Cluster is NOT tolerant to any failures.", "topology": { "1.1.1.1:3301": { "address": "1.1.1.1:3301", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "1.1.1.2:3301": { "address": "1.1.1.2:3301", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } }, "groupInformationSourceMember": "mysql://cladmin@1.1.1.1:3301" }
Чтож, кластер из двух нод есть, но в режиме «Cluster is NOT tolerant to any failures.»
Добавим третью, алгоритм в принципе не отличается от добавления второй.
Если вам опять требуется поменять whitelist, то выполнять команды надо на r/w ноде, т.к. на r/o нодах это ни к чему вроде не приводит. При этом r/o ноды отвалятся и их надо будет пересоединить, попутно сообщив новый whitelist.
В нашем случае:
> cluster.rejoinInstance('cladmin@1.1.1.2:3301', {ipWhitelist: '1.1.1.1,1.1.1.2,1.1.1.3'})
Ну и опять же не забываем выполнить dba.configureLocalInstance() на всех нодах для сохранения конфигурации.
Кластер из трех нод выглядит так:
{ "clusterName": "TestCluster", "defaultReplicaSet": { "name": "default", "primary": "1.1.1.1:3301", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "1.1.1.1:3301": { "address": "1.1.1.1:3301", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "1.1.1.2:3301": { "address": "1.1.1.2:3301", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "1.1.1.3:3301": { "address": "1.1.1.3:3301", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } }, "groupInformationSourceMember": "mysql://cladmin@1.1.1.1:3301" }
В случае, если кластер развалился до состояния одной ноды, его надо будет запускать с параметром loose-group_replication_bootstrap_group = ON в /etc/my.cnf
После запуска параметр надо будет выключить обратно, иначе эта нода всегда будет отделяться от кластера и поддерживать свой.
Установка mysql-router хорошо описана тут, так что дублировать смысла не вижу.
На этом все вроде все, надеюсь кому-то мой опыт пригодится.
Спасибо за внимание.
ссылка на оригинал статьи https://habr.com/post/423587/
Добавить комментарий