Я пытаюсь создать автоматическое развертывание 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