乐趣区

关于mysql:​在Docker中部署GreatSQL并构建MGR集群

  • GreatSQL 社区原创内容未经受权不得随便应用,转载请分割小编并注明起源。

为了方面社区用户体验 GreatSQL,咱们同时还提供 Docker 镜像,本文具体介绍如何在 Docker 中部署 GreatSQL,并且构建一个 MGR 集群。

本文波及的运行环境如下:

[root@greatsql]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

[root@greatsql]# uname -a
Linux GreatSQL 3.10.0-1160.11.1.el7.x86_64 #1 SMP Fri Dec 18 16:34:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

1、装置 Docker

间接用 yum 装置 docker,十分省事。

[root@greatsql]# yum install -y docker

之后启动 docker 服务,并设置开机自启动。

[root@greatsql]# systemctl enable docker
[root@greatsql]# systemctl start docker

2、拉取 GreatSQL 镜像,并创立容器

2.1 拉取镜像

拉取 GreatSQL 官网镜像:

[root@greatsql]# docker pull greatsql/greatsql
docker pull greatsql/greatsql
Using default tag: latest
Trying to pull repository docker.io/greatsql/greatsql ...
latest: Pulling from docker.io/greatsql/greatsql
...
Digest: sha256:63eff1b099a75bb4e96b2c5bc7144889f6b3634a6163b56642a71a189183966c
Status: Downloaded newer image for docker.io/greatsql/greatsql:latest

查看是否胜利:

[root@greatsql]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
docker.io/greatsql/greatsql   latest              d1963ef0c403        3 days ago          582 MB

2.2 创立新容器

之后,就能够间接创立一个新的容器了,先用惯例形式。

[root@greatsql]# docker run -d \
--name mgr1 --hostname=mgr1 \
-p 3306:3306 -p 33060:33060 -p 33061:33061 \
-e MYSQL_ALLOW_EMPTY_PASSWORD=1 \
-e MYSQL_IBP=1G \
-e MYSQL_MGR_NAME='aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa1' \
-e MYSQL_MGR_LOCAL='172.17.0.2:33061' \
-e MYSQL_MGR_SEEDS='172.17.0.2:33061,172.17.0.3:33061,172.17.0.4:33061' \
-e MYSQL_INIT_MGR=1 \
-e MYSQL_MGR_USER='repl' \
-e MYSQL_MGR_USER_PWD='repl' \
greatsql/greatsql

几个参数别离解释如下:

greatsql/greatsql,是镜像名,也能够指定为镜像的 ID,例如 d1963ef0c403。

如果不想让 root 账户应用空明码,能够把 MYSQL_ALLOW_EMPTY_PASSWORD=1 参数替换成诸如 MYSQL_ROOT_PASSWORD=’GreatSQL3#)^’ 或者指定随机明码 MYSQL_RANDOM_ROOT_PASSWORD=1 即可。

当启用选项 MYSQL_INIT_MGR=1 时,会主动创立 MGR 所需的账户,并执行 CHANGE MASTER TO 指定 MGR 复制通道。

若没有同时指定 MYSQL_MGR_USER 或 MYSQL_MGR_USER_PWD 的话,则采纳各自的默认值创立 MGR 账户。

这就胜利创立一个新的容器了,并且会主动实现 GreatSQL 的初始化并启动。

2.3 容器治理

先确认容器的状态:

[root@greatsql]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                       NAMES
2e277c852f52        d1963ef0c403        "/docker-entrypoin..."   4 minutes ago       Up 12 minutes        3306/tcp, 33060-33061/tcp   mgr1

看到容器状态是 Up 的,示意已失常启动了。

再进入容器查看:

[root@greatsql]# docker exec -it mgr1 /bin/bash
[root@mgr1 ~]# mysqladmin ver
mysqladmin  Ver 8.0.23-14 for Linux on x86_64 (GreatSQL (GPL), Release 14, Revision)
...
Server version  8.0.23-14
Protocol version 10
Connection  Localhost via UNIX socket
UNIX socket  /data/GreatSQL/mysql.sock
Uptime:   11 min 19 sec

Threads: 2  Questions: 2  Slow queries: 0  Opens: 120  Flush tables: 3  Open tables: 36  Queries per second avg: 0.002

看到容器曾经实现初始化,并且能够间接无明码登入。

查看 MGR 账户及相应复制通道:

[root@GreatSQL][(none)]> show grants for repl;
+----------------------------------------------+
| Grants for repl@%                            |
+----------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO `repl`@`%` |
| GRANT BACKUP_ADMIN ON *.* TO `repl`@`%`      |
+----------------------------------------------+

[root@GreatSQL][none]> select * from performance_schema.replication_group_members;
+---------------------------+-----------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME              | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+-----------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier |           |             |        NULL | OFFLINE      |             |                |
+---------------------------+-----------+-------------+-------------+--------------+-------------+----------------+

还能够把这个容器当做服务对其进行敞开、启动、重启、挂起等操作:

  kill        Kill one or more running containers
  pause       Pause all processes within one or more containers
  ps          List containers
  restart     Restart one or more containers
  rm          Remove one or more containers
  start       Start one or more stopped containers
  stop        Stop one or more running containers
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

能够自行挨个尝试。

2.4 容器销毁

如果想要销毁该容器,须要先进行该容器后,再执行 docker rm [容器 ID| 容器名] 命令即可:

[root@greatsql]# docker stop mgr1
[root@greatsql]# docker rm mgr1

如果是想销毁某个镜像,运行 docker rmi [镜像 ID| 镜像名] 命令即可,不过要先确保该镜像目前没有被其余容器所应用后,方可删除:

[root@greatsql]# docker rmi greatsql/greatsql

销毁容器、镜像之后,相应的数据目录也不再须要了,能够执行上面的命令革除:

[root@greatsql]# docker volume prune
WARNING! This will remove all volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
5a68a6286361f92430dbc4c1a2d1bd65a2db707274bd4d3dd9d53cdf58a5ac5f
3ae2211c61187371c312a606e36bc361e549e830ab5896356e7a920266574666
cbbfa248d2fc827d92ceac231b52b61ab7cfe92479f2e84969bd516dd211416f
1c95278033575062b7f15e3e3f1319290d8dcfc7caba1c50b47592f665ba5456

Total reclaimed space: 13.08 GB

3、构建 MGR 集群

跨宿主机之间的 docker 容器网络通信绝对麻烦一些,为了简略起见,本次先在单机环境下构建由 3 个 docker 容器组成的 MGR 集群。

3.1 创立专用子网

首先创立一个用于 MGR 集群的网络:

[root@greatsql]# docker network create mgr-net

[root@greatsql]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
70c3ac08c7a9        bridge              bridge              local
3a480a3ec570        host                host                local
191d6d902b26        mgr-net             bridge              local
1e3e6267dcda        none                null                local

查看这个子网的配置信息:

[root@greatsql]# docker inspect  mgr-net
[
    {
        "Name": "mgr-net",
...
                    "Subnet": "172.18.0.0/16",   <-- 网段
                    "Gateway": "172.18.0.1"   <-- 网关
...

3.2 创立 3 个新容器

别离启动三个 docker 容器:

[root@greatsql]# docker run -d \
--name mgr1 --hostname=mgr1 --net=mgr-net \
-e MYSQL_ALLOW_EMPTY_PASSWORD=1 \
-e MYSQL_MGR_LOCAL='172.18.0.2:33061' \
-e MYSQL_MGR_SEEDS='172.18.0.2:33061,172.18.0.3:33061,172.18.0.4:33061' \
-e MYSQL_INIT_MGR=1 \
greatsql/greatsql

前面的两个实例,只把 –name 和 –hostname 参数中的 mgr1 改成 mgr2、mgr3,并且把 -e MYSQL_MGR_LOCAL=’172.18.0.2:33061′ 参数的的 IP 地址递增,例如 -e MYSQL_MGR_LOCAL=’172.18.0.3:33061’。

查看容器运行状态:

[root@greatsql]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                       NAMES
1bcd23c6f378        d1963ef0c403        "/docker-entrypoin..."   2 minutes ago       Up 2 minutes        3306/tcp, 33060-33061/tcp   mgr3
9d12ab273d81        d1963ef0c403        "/docker-entrypoin..."   2 minutes ago       Up 2 minutes        3306/tcp, 33060-33061/tcp   mgr2
56fd564a1789        d1963ef0c403        "/docker-entrypoin..."   4 minutes ago       Up 4 minutes        3306/tcp, 33060-33061/tcp   mgr1

别离查看 3 个容器的 IP 地址:

[root@greatsql]# docker inspect mgr1 | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.18.0.2",
                    "IPAddress": "172.18.0.2",

第一个容器的 IP 地址是 172.18.0.2,另外两个容器别离是 172.18.0.3、172.18.0.4(递增关系)。

因为我启动容器时指定的新创建的网络 mgr-net,所以是 172.18.0.0/24 网段。如果不指定新创建的网络,则默认应该是 172.17.0.0/24 网段,留神区别。

编辑三个容器下的 /etc/hosts 文件,退出所有节点的 hostname 配置:

172.18.0.2 mgr1
172.18.0.3 mgr2
172.18.0.4 mgr3

揭示:docker 容器重启后,容器里的 /etc/hosts 文件内容会重置,所以倡议用映射 volumes 的形式挂进来。

在宿主机上编辑好一个文件 /data/docker/hosts:

[root@greatsql]# cat /data/docker/hosts

127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4

::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6

172.18.0.2 mgr1
172.18.0.3 mgr2
172.18.0.4 mgr3

在创立 docker 容器时映射挂载到容器的 /etc/hosts 文件:

[root@greatsql]# docker run -d \
...
-v /data/docker/hosts:/etc/hosts \
...
greatsql/greatsql

也能够在创立容器时,间接用 –add-host 指定,例如:

[root@greatsql]# docker run -d \
...
--add-host "mgr1:172.18.0.2" --add-host "mgr2:172.18.0.3" --add-host "mgr3:172.18.0.4"\
...
greatsql/greatsql

3.3 初始化 MGR 集群

接下来筹备初始化 MGR 集群。

抉择第一个容器 mgr1 作为 PRIMARY 节点,设置该容器的 MGR 的疏导,而后启动 MGR 服务:

[root@greatsql]# docker exec -it mgr1 /bin/bash
[root@mgr1 ~]# mysql -S/data/GreatSQL/mysql.sock
...
#设置本节点为 MGR 疏导启动节点,【留神】其余节点无需执行本操作
SET GLOBAL group_replication_bootstrap_group=ON;

#启动 MGR 服务
START GROUP_REPLICATION;

#启动完 MGR 服务后,敞开疏导参数
SET GLOBAL group_replication_bootstrap_group=OFF;

因为在创立容器时曾经实现了创立账户及受权等操作,所以能够间接启动 MGR 服务。

如果在创立容器时未指定 -e MYSQL_INIT_MGR=1 选项,则还须要手动执行上面的命令创立账户,受权,并创立 MGR 复制通道:

SET SQL_LOG_BIN=0;
CREATE USER repl IDENTIFIED with mysql_native_password BY 'repl4MGR';
GRANT REPLICATION SLAVE, BACKUP_ADMIN ON *.* TO repl;
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl4MGR' FOR CHANNEL 'group_replication_recovery';

3.4 启动 MGR 服务

在另外的两个 docker 容器里,记住不要设置 group_replication_bootstrap_group=ON,间接启动 MGR 服务即可。

查看所有节点都启动后的 MGR 服务状态:

[root@GreatSQL][(none)]> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 63b55594-da80-11eb-94bf-0242ac120003 | mgr2        |        3306 | ONLINE       | SECONDARY   | 8.0.23         |
| group_replication_applier | 6d33eb83-da80-11eb-91ed-0242ac120004 | mgr3        |        3306 | ONLINE       | SECONDARY   | 8.0.23         |
| group_replication_applier | 7b1e33b1-da7f-11eb-8157-0242ac120002 | mgr1        |        3306 | ONLINE       | PRIMARY     | 8.0.23         |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+

在这个阶段,MGR 服务无奈启动的常见起因有:

  • 没有在 /etc/hosts 中正确设置各节点的 hostname,会提醒无奈连贯近程主机。
  • 利用 docker 创立的子网超过了 RFC 1918 定义的保留公有网络地址范畴(A 类:10.0.0.0~10.255.255.255,B 类:172.16.0.0~172.31.255.255,C 类:192.168.0.0~192.168.255.255)。
  • 除去在抉择作为 PRIMARY 节点上设置 group_replication_bootstrap_group=ON 外,其余节点上也设置了,会造成启动一个新的 PRIMARY 节点。
  • 各节点创立 MGR 账号后,会产生 BINLOG,因而要执行 SET SQL_LOG_BIN=0 或者创立账号后再执行 RESET MASTER,否则会提醒本地节点比近程节点的事务数更多,无奈退出集群。

上述几种场景我都遇到过,可能还有其余更多状况,欢送补充。

3.5 写入测试数据

这就构建结束了,能够尝试在 PRIMARY 节点 中创立库表并写入测试数据:

# 揭示:从这里开始要重新启动 binlog 记录
[root@GreatSQL][(none)]> SET SQL_LOG_BIN=1;
[root@GreatSQL][(none)]> create database mymgr;
[root@GreatSQL][(none)]> use mymgr;
[root@GreatSQL][(mymgr)]> create table t1(id int primary key);
[root@GreatSQL][(mymgr)]> insert into t1 select rand()*10240;
[root@GreatSQL][mymgr]>select * from t1;
+------+
| id   |
+------+
| 3786 |
+------+

4、利用 Docker-compose 创立 Docker 容器

如果感觉手工治理麻烦,也能够选用 docker-compose,它能够更不便的治理 docker 容器。

先用 yum 装置 docker-compose,并确认版本号:

[root@greatsql]# yum install -y docker-compose

[root@greatsql]# docker-compose --version
docker-compose version 1.18.0, build 8dd22a9

编辑 docker-compose 的配置文件,其实就是把创立 docker 容器的命令行参数固化到配置文件而已:

[root@greatsql]# mkdir -p /data/docker-compose
[root@greatsql]# vi /data/docker-compose/compose-mgr.yml
version: '3'

services:
  mgr1:
    image: greatsql/greatsql
    container_name: mgr1
    hostname: mgr1
    network_mode: bridge
    restart: unless-stopped
    environment:
      TZ: Asia/Shanghai
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
      MYSQL_INIT_MGR: 1
      MYSQL_MGR_LOCAL: '172.17.0.2:33061'
      MYSQL_MGR_SEEDS: '172.17.0.2:33061,172.17.0.3:33061,172.17.0.4:33061'
    extra_hosts:
      - "mgr1:172.17.0.2"
      - "mgr2:172.17.0.3"
      - "mgr3:172.17.0.4"
  mgr2:
    image: greatsql/greatsql
    container_name: mgr2
    hostname: mgr2
    network_mode: bridge
    restart: unless-stopped
    depends_on:
      - "mgr1"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
      MYSQL_INIT_MGR: 1
      MYSQL_MGR_LOCAL: '172.17.0.3:33061'
      MYSQL_MGR_SEEDS: '172.17.0.2:33061,172.17.0.3:33061,172.17.0.4:33061'
    extra_hosts:
      - "mgr1:172.17.0.2"
      - "mgr2:172.17.0.3"
      - "mgr3:172.17.0.4"
  mgr3:
    image: greatsql/greatsql
    container_name: mgr3
    hostname: mgr3
    network_mode: bridge
    restart: unless-stopped
    depends_on:
      - "mgr2"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
      MYSQL_INIT_MGR: 1
      MYSQL_MGR_LOCAL: '172.17.0.4:33061'
      MYSQL_MGR_SEEDS: '172.17.0.2:33061,172.17.0.3:33061,172.17.0.4:33061'
    extra_hosts:
      - "mgr1:172.17.0.2"
      - "mgr2:172.17.0.3"
      - "mgr3:172.17.0.4"

启动三个实例:

[root@greatsql]# docker-compose -f /data/docker-compose/compose-mgr.yml up -d
Name   Command   State   Ports
Creating mgr1 ... done
Creating mgr2 ... done
Creating mgr3 ... done
Creating mgr2 ...
Creating mgr3 ...

查看运行状态:

[root@greatsql]# docker-compose -f /data/docker-compose/compose-mgr.yml up -d
Name             Command              State               Ports
----------------------------------------------------------------------------
mgr1   /docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp, 33061/tcp
mgr2   /docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp, 33061/tcp
mgr3   /docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp, 33061/tcp

进入被选为 PRIMARY 节点的容器 mgr1,启动 MGR 服务:

[root@greatsql]# docker exec -it mgr1 bash
[root@mgr1 /]# mysql
...
[root@GreatSQL][(none)]> set global group_replication_bootstrap_group=ON;
[root@GreatSQL][(none)]> start group_replication;

进入其余 SECONDARY 节点的容器,间接启动 MGR 服务:

[root@greatsql]# docker exec -it mgr2 bash
[root@mgr2 /]# mysql
...
[root@GreatSQL][(none)]> start group_replication;
Query OK, 0 rows affected (2.76 sec)

#查看 MGR 服务状态
[root@GreatSQL][(none)]>select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | f0bd73d4-dbcb-11eb-99ba-0242ac110002 | mgr1        |        3306 | ONLINE       | PRIMARY     | 8.0.23         |
| group_replication_applier | f1010499-dbcb-11eb-9194-0242ac110003 | mgr2        |        3306 | ONLINE       | SECONDARY   | 8.0.23         |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+

依旧,持续启动 mgr3 节点,一个三节点的 MGR 集群就实现了。

GreatSQL-Docker 相干文档曾经公布到 https://gitee.com/GreatSQL/Gr…,欢送关注。

此外,GreatSQL Docker 镜像文件也已公布到 https://hub.docker.com/r/grea… 欢送下载体验。

程度无限,也请各位读者小孩儿帮忙看看哪些能够优化的中央,感激。

最初要特别感谢近期在折腾 docker、ansible 中提供帮忙的多位敌人,别离是谢恒忠、吕保成、Fan()、Coral、戴先森等(排名不分先后)。

Enjoy GreatSQL & Docker :)

文章举荐:

GreatSQL MGR FAQ
https://mp.weixin.qq.com/s/J6…

万答 #12,MGR 整个集群挂掉后,如何能力主动选主,不必手动干涉
https://mp.weixin.qq.com/s/07…

『2021 数据技术嘉年华·ON LINE』:《MySQL 高可用架构演进及实际》
https://mp.weixin.qq.com/s/u7…

一条 sql 语句慢在哪之抓包剖析
https://mp.weixin.qq.com/s/AY…

万答 #15,都有哪些状况可能导致 MGR 服务无奈启动
https://mp.weixin.qq.com/s/in…

技术分享 | 为什么 MGR 一致性模式不举荐 AFTER
https://mp.weixin.qq.com/s/rN…

对于 GreatSQL

GreatSQL 是由万里数据库保护的 MySQL 分支,专一于晋升 MGR 可靠性及性能,反对 InnoDB 并行查问个性,是实用于金融级利用的 MySQL 分支版本。

Gitee:
https://gitee.com/GreatSQL/Gr…

GitHub:
https://github.com/GreatSQL/G…

Bilibili:
https://space.bilibili.com/13…

微信 &QQ 群:
可搜寻增加 GreatSQL 社区助手微信好友,发送验证信息“加群”退出 GreatSQL/MGR 交换微信群

QQ 群:533341697
微信小助手:wanlidbc

本文由博客一文多发平台 OpenWrite 公布!

退出移动版