Docker/CoreOS 上的 Galera 集群(MariaDB):第二个节点第一次尝试时无法工作

Docker/CoreOS 上的 Galera 集群(MariaDB):第二个节点第一次尝试时无法工作

我正在尝试使用 MariaDB 创建 Galera Cluster 的自动部署,并在 CoreOS 上的 Docker 容器内运行。

所用软件: - MariaDB 官方Docker 映像,版本 10.1.10 - CoreOS 899.5.0,带有 Docker 1.9.1

所有内容都在 2 个独立的虚拟机上运行: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.dDocker 容器中):

# 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.2MB!对于帖子来说太大了)

再次提醒,请注意,一旦我在第二个节点重新启动容器(保留数据),复制就会起作用 - 并且运行良好!但这种“奇怪”的启动过程并不正常,我不能依赖它(我需要稍后通过创建 fleet.d 单元来编写整个设置的脚本)

答案1

经过几天的努力,我终于能够让它发挥作用了。

关键问题是默认的 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

相关内容