Docker 部署MySQL 之 PXC 集群部署【单机多节点】
特别注意:鄙人认为本篇适合做入门测试/学习之用,如需高可用方案,请参考多机多节点方案
近期正突击学习数据库知识
想着对 PXC
集群部署实际操作一番,提高技能点,为后续的升职加薪做充足的准备
于是,在此记录一下,
既能作为采坑笔记,又能帮助到后期有需要的道友,欢迎指摘 …
Percona XtraDB Cluster
(简称 PXC 集群)
PXC
的优缺点
PXC
最大的优势:强一致性、无同步延迟
常见MySQL集群方案
mysql
集群方案介绍,建议使用 pxc
,因为弱一致性会有问题,比如说a节点数据库显示我购买成功,b 节点数据库显示没有成功,这就麻烦了,pxc 方案是在全部节点都写入成功之后才会告诉你成功,是可读可写双向同步的,但是 replication
是单向的,不同节点的数据库之间都会开放端口进行通讯,如果从防火墙的这个端口关闭,pxc
就不会同步成功,也不会返给你成功了。
Replication
- 速度快,但仅能保证弱一致性,适用于保存价值不高的数据,比如日志、帖子、新闻等。
- 采用
master-slave
结构,在master
写入会同步到slave
,能从slave
读出;但在slave
写入无法同步到master
。 - 采用异步复制,
master
写入成功就向客户端返回成功,但是同步slave
可能失败,会造成无法从slave
读出的结果。
PXC (Percona XtraDB Cluster)
- 速度慢,但能保证强一致性,适用于保存价值较高的数据,比如订单、客户、支付等。
- 数据同步是双向的,在任一节点写入数据,都会同步到其他所有节点,在任何节点上都能同时读写。
- 采用同步复制,向任一节点写入数据,只有所有节点都同步成功后,才会向客户端返回成功。事务在所有节点要么同时提交,要么不提交。
前期准备
部署前建议关闭 SELINUX
、MySQL
数据库服务停止
安全增强型
Linux(Security-Enhanced Linux)SELinux
主要由美国国家安全局开发
-
一种方法【荐】,永久关闭 Selinux:
vi /etc/selinux/config
把SELINUX
属性值设置成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
创建数据卷 (可选)
使用
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
因为后续节点的添加需要关联到第一个节点,
所以,此时需要等待数据库启动完成 【自动执行,正常情况下会发现MYSQL
服务启动了!】
查看日志
docker logs node1
如果出现下面的输出,证明启动成功;
"2021-01-08T10:00:17.143767Z 0 [Note] InnoDB: Buffer pool(s) load completed at 210108 10:00:17"
如果发现启动有误,建议先将容器停止,不然
mysqld
服务各种报错。停止删除命令:docker stop node1 && docker rm node1
此时,可以通过 Navicat 等数据库连接工具测试是否能够连接 【前提:9000
端口开放】
也可以同过命令 :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
客户端,分别使用端口 9000
、9001
、9002
连接
然后,在节点 node2
上,创建数据库 test_pxc
,以及表 test-pxc
随便更改数据,会发现,其他节点的数据也是同步变化的。
初步探索到这吧,后面再做多机部署的测试、整理 …
宕机操作
正常退出节点操作
如果是想停用某个节点 (非节点 node1
),假设是node2
节点,正确的命令为: docker stop node2
,可通过命令查看:docker ps -a
。
待其他工作完成后,想加入,再执行命令:docker start node2
即可
对于节点的停止操作,分第一个节点和其他节点,是不同的!
如果 node1
节点不是最后一个离开集群
如果
node1
节点不是最后一个离开集群的,不能再以主节点的形式启动了。
此时,只运行 docker start node1
命令,过会会发现 node1
没有启动
这时,需要通过 docker volume inspect vMZ1
,进入数据卷目录(docker-compose
模式下直接进入01
文件夹),查看是否存在 grastate.dat
文件。
将 ·safe_to_bootstrap· 参数值修改为 1,保存退出,启动node1
节点,然后再进入 node1
节点中查看数据,试着修改一下,看是否和其他节点数据同步。
我发现我这里时可以同步的,但根据网友经验多数是不会同步的。此时,可以 删除 node1
容器 : docker stop node1
、docker rm node1
,然后再以指定主节点形式加入集群,注意参数 -e CLUSTER_JOIN=node3
的指定(此时是node3
未停止)。后面再检查数据是否能同步 !
如果其他以指定主节点形式的节点离开集群后
可以通过命令:docker start node2
, 进入 PXC
集群创建的容器。
然后,通过 docker ps
查看是否进入成功。
最坏情况,节点再创建一遍
记不清之前的退出操作了,所以不确定哪个是最后退出。这时,试着将所有的节点都 docker stop node*
,然后docker rm node*
操作,然后,再从创建节点步骤开始,执行一遍,一般会成功。
后记
文章参考:点我跳转原文