Docker 部署MySQL 之 PXC 集群部署【单机多节点】

418

特别注意:鄙人认为本篇适合做入门测试/学习之用,如需高可用方案,请参考多机多节点方案

近期正突击学习数据库知识
想着对 PXC 集群部署实际操作一番,提高技能点,为后续的升职加薪做充足的准备
于是,在此记录一下,
既能作为采坑笔记,又能帮助到后期有需要的道友,欢迎指摘 …

Percona XtraDB Cluster(简称 PXC 集群)

PXC 的优缺点

20210108161313553.png

PXC 最大的优势:强一致性、无同步延迟

常见MySQL集群方案

mysql 集群方案介绍,建议使用 pxc,因为弱一致性会有问题,比如说a节点数据库显示我购买成功,b 节点数据库显示没有成功,这就麻烦了,pxc 方案是在全部节点都写入成功之后才会告诉你成功,是可读可写双向同步的,但是 replication 是单向的,不同节点的数据库之间都会开放端口进行通讯,如果从防火墙的这个端口关闭,pxc 就不会同步成功,也不会返给你成功了。

image.png

Replication

  • 速度快,但仅能保证弱一致性,适用于保存价值不高的数据,比如日志、帖子、新闻等。
  • 采用master-slave结构,在master写入会同步到slave,能从slave读出;但在slave写入无法同步到master
  • 采用异步复制,master写入成功就向客户端返回成功,但是同步slave可能失败,会造成无法从slave读出的结果。

PXC (Percona XtraDB Cluster)

  • 速度慢,但能保证强一致性,适用于保存价值较高的数据,比如订单、客户、支付等。
  • 数据同步是双向的,在任一节点写入数据,都会同步到其他所有节点,在任何节点上都能同时读写。
  • 采用同步复制,向任一节点写入数据,只有所有节点都同步成功后,才会向客户端返回成功。事务在所有节点要么同时提交,要么不提交。

前期准备

部署前建议关闭 SELINUXMySQL 数据库服务停止

安全增强型 Linux(Security-Enhanced Linux)SELinux 主要由美国国家安全局开发

  • 一种方法【荐】,永久关闭 Selinux:
    vi /etc/selinux/configSELINUX 属性值设置成 disabled,然后 reboot 重启

  • 另一种方法,或者执行命令 Linux 临时关闭 Selinux: setenforce 0

安装 docker,请参阅Docker全家桶简介

搭建 PXC 集群

下载 PXC 镜像 (可以指定版本)

Docker 仓库中的 PXC 官方镜像:https://hub.docker.com/r/percona/percona-xtradb-cluster

因为我所使用的 MySQL 版本为 5.7.32,此处对应选择的 PXC 版本就是 5.7

docker pull percona/percona-xtradb-cluster:5.7

输出如下指令:

[root@test mysql]# docker pull percona/percona-xtradb-cluster:5.7
Trying to pull repository docker.io/percona/percona-xtradb-cluster ...
5.7: Pulling from docker.io/percona/percona-xtradb-cluster
75f829a71a1c: Already exists
cf0efe55f10d: Already exists
e632c0ccd2fb: Already exists
4c86e21499a1: Already exists
32a8cd67d865: Already exists
3672a73f6188: Already exists
6c6c92c55055: Already exists
cd786bd32ef1: Pull complete
8236bd03304c: Pull complete
bd59b303b228: Pull complete
c574c241c2a3: Pull complete
030daf9905bb: Pull complete
Digest: sha256:d95cfa86d2dca1a2c62c05e53050fd569512bf4b78d867b0e5f8f234d7f3999a
Status: Downloaded newer image for docker.io/percona/percona-xtradb-cluster:5.7
[root@test mysql]# docker images
REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
docker.io/percona/percona-xtradb-cluster   5.7                 3a0dc027d8ac        2 months ago        442 MB

创建 Docker 网络

docker network create --subnet=172.20.0.0/16  pxc-network-mT

这里的IP地址可以更换为自己公司的网段地址,无强制要求

  • 查看网段
docker network inspect pxc-network-mT
  • 所有网段
docker network ls
  • 删除网段
docker network rm pxc-network-mT

20210108174246530.png

创建数据卷 (可选)

使用 Docker 时,业务数据应保存在宿主机中,采用目录映射,这样可以使数据与容器独立。
但是容器中的 PXC 无法直接使用映射目录,解决办法是采用 Docker 卷 来映射
当使用docker-compose 方式启动时,可以无需先行创建数据卷。

  • 本文以最常用的三个节点作为配置,所以就可以创建三个数据卷
[root@localhost ~]# docker volume create vMZ1
vMZ1
[root@localhost ~]# docker volume create vMZ2
vMZ2
[root@localhost ~]# docker volume create vMZ3
vMZ3

【拓展】: 删除数据卷命令为: docker volume rm vMZ1 (最后一项为数据卷名称,可自定义)

  • 查看数据卷
[root@localhost download]# docker inspect vMZ1
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/vMZ1/_data", # 这里是在宿主机的保存位置
        "Name": "vMZ1",
        "Options": {},
        "Scope": "local"
    }
]

创建节点(PXC 容器)

注意:在这一步之前,要把已有的 MySQL 数据库停止服务 !

[root@localhost ~]# service mysqld status
 SUCCESS! MySQL running (1992)
[root@localhost ~]# service mysqld stop
Shutting down MySQL.. SUCCESS!

以下两种创建方式二选一

docker 命令行启动

  • 创建第一个节点

执行以下命令:

docker run -di --name=node1 --net=pxc-network-mT -p 9000:3306 -v vMZ1:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=cluster-mT -e XTRABACKUP_PASSWORD=mT123456 --ip 172.20.0.2 pxc

image.png

因为后续节点的添加需要关联到第一个节点,
所以,此时需要等待数据库启动完成 【自动执行,正常情况下会发现 MYSQL 服务启动了!】

查看日志

docker logs node1 

如果出现下面的输出,证明启动成功;
"2021-01-08T10:00:17.143767Z 0 [Note] InnoDB: Buffer pool(s) load completed at 210108 10:00:17"

image.png

如果发现启动有误,建议先将容器停止,不然 mysqld 服务各种报错。停止删除命令:docker stop node1 && docker rm node1

此时,可以通过 Navicat 等数据库连接工具测试是否能够连接 【前提:9000 端口开放】

image.png

也可以同过命令 :docker ps,查看已创建的节点

  • 加入第二个/第三个节点

只有主节点可以访问了,才能创建从节点

加入第二个节点,执行命令:

docker run -di --name=node2 --net=pxc-network-mT -p 9001:3306 -v vMZ2:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=cluster-mT -e XTRABACKUP_PASSWORD=mT123456 -e CLUSTER_JOIN=node1 --ip 172.20.0.3 pxc

需要注意是: 第二个节点开始需要增加 -e CLUSTER_JOIN=node1 参数
表示与 node1 节点同步,否则 node2容器会自动关闭。
当 PXC 集群中存在两个节点以上之后就没有主节点的概念了。集群中最后一个退出的节点就会变为主节点

加入第三个节点,执行命令:

docker run -di --name=node3 --net=pxc-network-mT -p 9002:3306 -v vMZ3:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=cluster-mT -e XTRABACKUP_PASSWORD=mT123456 -e CLUSTER_JOIN=node1 --ip 172.20.0.4 pxc

查看挂载情况

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                   NAMES
db0a01e25a4d        pxc                 "/entrypoint.sh my..."   5 seconds ago       Up 4 seconds        4567-4568/tcp, 0.0.0.0:9002->3306/tcp   node3
501d6b015853        pxc                 "/entrypoint.sh my..."   6 minutes ago       Up 6 minutes        4567-4568/tcp, 0.0.0.0:9001->3306/tcp   node2
079cfbecc5b0        pxc                 "/entrypoint.sh my..."   27 minutes ago      Up 27 minutes       4567-4568/tcp, 0.0.0.0:9000->3306/tcp   node1
[root@localhost ~]#

进入 node1 节点

docker exec -it node1 /usr/bin/mysql -uroot -pmT123456

查看状态

mysql> show status like 'wsrep%';

docker-compose 启动

当使用docker-compose 方式启动时,可以无需先行创建数据卷。

  • 创建 docker-compose.yml 文件
version: '3'
services:
  mysql01:
    container_name: node1
    image: percona/percona-xtradb-cluster:5.7
    ports:
      - "9000:3306"
    environment:
      MYSQL_ROOT_PASSWORD: "mT123456"
      XTRABACKUP_PASSWORD: "mT123456"
      TZ: Asia/shanghai
      CLUSTER_NAME: "mysql-cluster"
    command:
      --default-time-zone=+8:00
    privileged: true
    volumes:
      - "./01:/var/lib/mysql"
    restart: always
    networks:
      - mysql
  mysql02:
    container_name: node2
    image: percona/percona-xtradb-cluster:5.7
    ports:
      - "9001:3306"
    environment:
      MYSQL_ROOT_PASSWORD: "mT123456"
      XTRABACKUP_PASSWORD: "mT123456"
      TZ: Asia/shanghai
      CLUSTER_NAME: "mysql-cluster"
      CLUSTER_JOIN: "node1"
    command:
      --default-time-zone=+8:00
    privileged: true
    volumes:
      - "./02:/var/lib/mysql"
    restart: always
    networks:
      - mysql
  mysql03:
    container_name: node3
    image: percona/percona-xtradb-cluster:5.7
    ports:
      - "9002:3306"
    environment:
      MYSQL_ROOT_PASSWORD: "mT123456"
      XTRABACKUP_PASSWORD: "mT123456"
      TZ: Asia/shanghai
      CLUSTER_NAME: "mysql-cluster"
      CLUSTER_JOIN: "node1"
    command:
      --default-time-zone=+8:00
    privileged: true
    volumes:
      - "./03:/var/lib/mysql"
    restart: always
    networks:
      - mysql

networks:
  mysql:
    driver: bridge
  • 执行启动命令,启动主节点
docker-compose up -d node1

待完全启动后,分别执行如下命令,启动第二第三节点

第二节点

docker-compose up -d node2

第三节点

docker-compose up -d node3

集群同步验证

最直接的方式就是操作数据库,进行数据比对

为了操作方便,我直接使用 Navicat 客户端,分别使用端口 900090019002 连接
然后,在节点 node2 上,创建数据库 test_pxc,以及表 test-pxc
随便更改数据,会发现,其他节点的数据也是同步变化的。

image.png

初步探索到这吧,后面再做多机部署的测试、整理 …

宕机操作

正常退出节点操作

如果是想停用某个节点 (非节点 node1),假设是node2节点,正确的命令为: docker stop node2,可通过命令查看:docker ps -a

待其他工作完成后,想加入,再执行命令:docker start node2 即可

image.png

对于节点的停止操作,分第一个节点和其他节点,是不同的!

如果 node1 节点不是最后一个离开集群

如果 node1 节点不是最后一个离开集群的,不能再以主节点的形式启动了。

此时,只运行 docker start node1 命令,过会会发现 node1没有启动
这时,需要通过 docker volume inspect vMZ1,进入数据卷目录(docker-compose模式下直接进入01文件夹),查看是否存在 grastate.dat 文件。

image.png

将 ·safe_to_bootstrap· 参数值修改为 1,保存退出,启动node1节点,然后再进入 node1 节点中查看数据,试着修改一下,看是否和其他节点数据同步。

我发现我这里时可以同步的,但根据网友经验多数是不会同步的。此时,可以 删除 node1容器 : docker stop node1docker rm node1,然后再以指定主节点形式加入集群,注意参数 -e CLUSTER_JOIN=node3 的指定(此时是node3未停止)。后面再检查数据是否能同步 !

如果其他以指定主节点形式的节点离开集群后

可以通过命令:docker start node2, 进入 PXC 集群创建的容器。
然后,通过 docker ps 查看是否进入成功。

最坏情况,节点再创建一遍

记不清之前的退出操作了,所以不确定哪个是最后退出。这时,试着将所有的节点都 docker stop node*,然后docker rm node*操作,然后,再从创建节点步骤开始,执行一遍,一般会成功。

后记

文章参考:点我跳转原文