Назад | Перейти на главную страницу

Кластер Galera (MariaDB) на Docker / CoreOS: второй узел не работает с первой попытки

Я пытаюсь создать автоматическое развертывание Galera Cluster с MariaDB, работающее внутри контейнеров Docker на CoreOS.

Используемое программное обеспечение: - Официальный представитель MariaDB Образ докера, версия 10.1.10 - CoreOS 899.5.0, с Docker 1.9.1

Все работает на двух отдельных виртуальных машинах: 10.2.0.4 и 10.2.0.5.

Я могу успешно запустить первый узел (10.2.0.4) и запустить кластер.

Однако, когда я запускаю второй узел, я получаю много ошибок с репликацией mysql.time_zone_transition_type и mysql.time_zone_name стол. После этого mysqld демон НЕ аварийно завершает работу, поэтому мой контейнер Docker продолжает работать (он работает без проблем в течение нескольких минут), но, похоже, он не присоединился к кластеру (запрос статуса на первом узле показывает, что только 1 узел присоединился), и он не принимает любое соединение (попытка подключения к этому узлу не удалась). Однако, как ни странно, если я перезапускаю контейнер Docker (сохраняя папку данных), он затем присоединяется к узлу и работает безупречно.

Вот файл конфигурации MySQL (добавлен в /etc/mysql/conf.d в контейнере Docker):

# this is read by the standalone daemon and embedded servers
[server]

# this is only for the mysqld standalone daemon
[mysqld]

#
# * Galera-related settings
#
[galera]
# Mandatory settings
wsrep_on=ON
wsrep_provider="/usr/lib/galera/libgalera_smm.so"
wsrep_cluster_address="gcomm://10.2.0.4,10.2.0.5"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
innodb_locks_unsafe_for_binlog=1
query_cache_size=0
query_cache_type=0
wsrep-sst-method=rsync

#
# Allow server to accept connections on all interfaces.
#
bind-address=0.0.0.0
#
# Optional setting
#wsrep_slave_threads=1
#innodb_flush_log_at_trx_commit=0

# this is only for embedded server
[embedded]

# This group is only read by MariaDB servers, not by MySQL.
# If you use the same .cnf file for MySQL and MariaDB,
# you can put MariaDB-only options here
[mariadb]

# This group is only read by MariaDB-10.1 servers.
# If you use the same .cnf file for MariaDB of different versions,
# use this group for options that older servers don't understand
[mariadb-10.1]

Я начинаю первый узел с:

$ docker rm -f some-mariadb
$ rm -rf /mnt/resource/data/*
# Note: we need to pass the IP of the VM or mysqld will get the IP from the Docker container
$ docker run \
  --name some-mariadb \
  -v /mnt/resource/mysql.conf.d:/etc/mysql/conf.d \
  -v /mnt/resource/data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=my-secret-pw \
  -d \
  -p 3306:3306 \
  -p 4567:4567/udp \
  -p 4567-4568:4567-4568 \
  -p 4444:4444 \
  mariadb:10.1 \
  --wsrep-new-cluster \
  --wsrep_node_address=10.2.0.4

И второй:

$ rm -rf /mnt/resource/data/*
$ docker rm -f some-mariadb
# Create a "/var/lib/mysql/mysql" folder so the Docker container won't initialize the db again (won't re-execute mysql_install_db)
$ mkdir -p /mnt/resource/data/mysql
$ docker run \
  --name some-mariadb \
  -v /mnt/resource/mysql.conf.d:/etc/mysql/conf.d \
  -v /mnt/resource/data:/var/lib/mysql \
  -d \
  -p 3306:3306 \
  -p 4567:4567/udp \
  -p 4567-4568:4567-4568 \
  -p 4444:4444 \
  mariadb:10.1 \
  --wsrep_node_address=10.2.0.5

Все мои ошибки репликации выглядят так:

2016-01-23 23:57:52 140131133560576 [ERROR] Slave SQL: Error 'Column 'Time_zone_id' cannot be null' on query. Default database: 'mysql'. Query: 'INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('Etc/GMT', @time_zone_id)', Internal MariaDB error code: 1048
2016-01-23 23:57:52 140131133560576 [Warning] WSREP: RBR event 1 Query apply warning: 1, 1536
2016-01-23 23:57:52 140131133560576 [Warning] WSREP: Ignoring error for TO isolated action: source: 09357a0e-c22d-11e5-963a-0a6f9b6b61c4 version: 3 local: 0 state: APPLYING flags: 65 conn_id: 5 trx_id: -1 seqnos (l: 1147, g: 1536, s: 1535, d: 1535, ts: 73713003335315)

Полный журнал можно найти по этой ссылке (это 4,2 МБ! слишком велик для публикации)

Опять же, обратите внимание, что как только я перезапускаю контейнер на втором узле (с сохранением данных), репликация работает - и работает хорошо! Но этот "странный" процесс запуска ненормален, и я не могу на него полагаться (мне нужно будет написать сценарий всей установки, создав юниты fleet.d, позже)

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

Ключевой проблемой является то, что образ Docker по умолчанию (вероятно, имитирующий то, что делает образ MySQL) добавляет данные о часовом поясе в базу данных и по какой-либо причине (может быть, потому, что он использует таблицы MyISAM?), Что вызывает огромные проблемы с этой настройкой.

Решение: при запуске первой ноды передать MYSQL_INITDB_SKIP_TZINFO=yes переменная окружения в контейнер Docker. Итак, команда для запуска первого контейнера Docker:

docker run \
  --name some-mariadb \
  -v /mnt/resource/mysql.conf.d:/etc/mysql/conf.d \
  -v /mnt/resource/data:/var/lib/mysql \
  -e MYSQL_INITDB_SKIP_TZINFO=yes \
  -e MYSQL_ROOT_PASSWORD=my-secret-pw \
  -d \
  -p 3306:3306 \
  -p 4567:4567/udp \
  -p 4567-4568:4567-4568 \
  -p 4444:4444 \
  mariadb:10.1 \
  --wsrep-new-cluster \
  --wsrep_node_address=10.2.0.4