CentOS7 下 MySQL 之 PXC 集群部署【Docker+单机多节点】
背景
【注意】:
鄙人认为本篇适合做入门测试/学习之用,选择的"单机多节点配置"
建议移步: “多机多节点部署” ——
【CentOS7.9 下 MySQL 之 PXC 集群部署【Docker+多机多节点】
- 近期正突击学习数据库知识
想着对
PXC
集群部署实际操作一番,提高技能点,为后续的升职加薪做充足的准备 于是,在此记录一下, 既能作为采坑笔记,又能帮助到后期有需要的道友,欢迎指摘 …
【注】:Percona XtraDB Cluster(简称 PXC 集群)
- PXC的优缺点
PXC
最大的优势:强一致性、无同步延迟, 推荐阅读:【Docker 部署 Mysql集群】
-
MySQL
常见集群方案 【Replicationvs
PXC】
- 环境
CentOS版本: CentOS Linux release 7.9.2009 (Core)
MySQL 版本: 5.7.32
PXC 版本 : percona/percona-xtradb-cluster:5.7
其实,一开始,鄙人也是计划直接操作多机部署经验,基本百度出来的都是这一类的,只好先摸索一番吧 …
前期准备
1). 开启四个 PXC 环境所涉及的端口:
3306: # mysql 实例端口
4567: # PXC cluster 相互通讯的端口
4444: # 用于 SST(State Snapshot Transfer): 全量传输
4568: # 用于 IST(Incremental state Transfer):增量传输传送
以鄙人使用宝塔面板操作为例,注意以上端口的开启:
2). 部署前建议关闭 SELINUX、将 MySQL 数据库服务停止
安全增强型
Linux(Security-Enhanced Linux)SELinux
主要由美国国家安全局开发
- 一种方法
【荐】
,永久关闭 Selinux:"vi /etc/selinux/config"
把"SELINUX"
属性值设置成disabled
,然后reboot
重启 - 另一种方法,或者执行命令 Linux 临时关闭 Selinux:
"setenforce 0"
3). 安装 "docker"
- 因为,PXC 官方提供了 Docker 镜像,所以我们可以很方便的搭建 PXC 集群
所以,如果没有安装
"docker"
,需要先执行命令:
yum install -y docker
【拓展】:
- 查看
docker
版本:docker -v
判断docker
是否安装成功:docker
docker
的启动与关闭:service docker start
、service docker stop
- docker 虚拟机管理命令
搭建 PXC 集群
查看所有 镜像命令:
docker image ls
1). 下载 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
此时如果报错,建议执行 :
"systemctl restart docker.service"
— 参考文章: 【Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?】
[root@localhost download]# 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@localhost download]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/percona/percona-xtradb-cluster 5.7 3a0dc027d8ac 2 months ago 442 MB
- 重命名镜像名称 (名称太长,重命名一下)
docker tag percona/percona-xtradb-cluster:5.7 pxc
- 删除原始镜像
docker rmi percona/percona-xtradb-cluster:5.7
【拓展】:
- 镜像查看命令:
docker images
2). 创建 Docker
网络,
- 出于安全考虑,给
PXC
集群创建Docker
内部网络,用于PXC
集群独立使用
docker network create --subnet=172.20.0.0/16 pxc-network-mT
【拓展】:
- 查看网段:
docker network inspect pxc-network-mT
所有网段:docker network ls
删除网段:docker network rm pxc-network-mT
3). 创建数据卷 (用于之后挂载)
使用
Docker
时,业务数据应保存在宿主机中,采用目录映射,这样可以使数据与容器独立。 但是容器中的 PXC 无法直接使用映射目录,解决办法是采用Docker 卷
来映射
- 本文以最常用的三个节点作为配置,所以就可以创建三个数据卷
[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"
}
]
4). 创建节点(PXC 容器)
注意:在这一步之前,要把 MySQL 数据库停止服务 !
[root@localhost ~]# service mysqld status
SUCCESS! MySQL running (1992)
[root@localhost ~]# service mysqld stop
Shutting down MySQL.. SUCCESS!
A. 创建第一个节点
- 执行命令(对于参数释义,请移步
【附录 - a】
):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 rm node1
停止节点运行:docker stop node1
查看所有节点:docker ps
- 此时,可以通过 Navicat 等数据库连接工具测试是否能够连接 【前提:9000 端口开放】
- 也可以同过命令 :
docker ps
,查看已创建的节点
B. 加入第二个/第三个…节点
只有主节点可以访问了,才能创建从节点
- 加入第二个节点,执行命令:
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%';
可以看到
"wsrep_incoming_addresses"
的值就是我们三个容器的IP地址" wsrep_incoming_addresses | db0a01e25a4d:3306,501d6b015853:3306,079cfbecc5b0:3306 "
5). 集群同步验证
最直接的方式就是操作数据库,进行数据比对
- 为了操作方便,我直接使用 Navicat 客户端,分别使用端口
"9000、9001、9002"
连接 然后,在节点 node2 上,创建数据库test_pxc
,以及表test-pxc
随便更改数据,会发现,其他节点的数据也是同步变化的
初步探索到这吧,后面再做多机部署的测试、整理 …
宕机操作
● 正常退出节点操作
- 如果是想停用某个节点 (【非节点【node1】)
正确的命令为:
docker stop node2
可通过命令查看:docker ps -a
- 待其他工作完成后,想加入,再执行命令:
docker start node2
即可
对于节点的停止操作,分第一个节点和其他节点,是不同的!
▶. 如果 【node1】 节点不是最后一个离开集群
如果 【node1】 节点不是最后一个离开集群的,不能再以主节点的形式启动了
- 此时,只运行
"docker start node1"
命令,过会会发现 【node1】没有启动 这时,需要通过"docker volume inspect vMZ1"
,进入数据卷目录,查看是否存在grastate.dat
文件
- 将
"safe_to_bootstrap"
参数值修改为1
,保存退出 然后再进入 【node1】节点中查看数据 试着修改一下,看是否和其他节点数据同步 - 我发现我这里时可以同步的
但根据网友经验多数是不会同步的
此时,可以 删除 【node1】容器 :
docker stop node1
、docker rm node1
然后再以指定主节点形式加入集群,注意参数"-e CLUSTER_JOIN=node3"
的指定(此时是【node3】未停止) - 后面再检查数据是否能同步 !
▶. 如果其他以指定主节点形式的节点离开集群后
- 可以通过命令:
docker start node2
, 进入 PXC 集群创建的容器 然后,通过docker ps
查看是否进入成功
▶. 最坏情况,节点再创建一遍
- 记不清之前的退出操作了,所以不确定哪个是最后退出
这时,我试着将所有的节点都
stop
,然后rm
操作 然后,再从创建节点步骤开始,执行一遍,发现又成功了!
附录
a. 创建节点参数解释
- 文档 —— 【Docker run 命令】
命令 | 说明 |
---|---|
-d | 代表创建的容器在后台运行 |
–name=node1 | 容器名称 |
–net=pxc-network-mT | 加入到 pxc-network-mT 的虚拟网络 |
-p 9000:3306 | 端口映射 宿主机端口:容器端口 |
-v vMZ1:/var/lib/mysql | 数据卷挂载在 “vMZ1” 数据卷。可以理解为虚拟的磁盘,容器在保存数据的时候往 /var/lib/mysql 路径保存数据,其实就是把数据包存在数据卷上了 |
–privileged | 表示有读写权限 |
-e MYSQL_ROOT_PASSWORD=mT123456 | Mysql 的 root 密码 (跟原来数据库设定的 root 密码没关系) |
-e CLUSTER_NAME=cluster-mT | PXC 集群名称 (注意不要命为:PXC) |
-e XTRABACKUP_PASSWORD=mT123456 | PXC 集群之间数据同步的密码 |
-e CLUSTER_JOIN=node1 | 表示与 node1 节点同步 |
pxc | 来自哪个镜像创建 |
b. 数据卷操作指令
- 查看当前存在的数据卷
docker volume ls
- 创建一个的数据卷 ,name:数据卷名称
docker volume create ${name}
- 删除某个数据卷,name:数据卷名称
docker volume rm ${name}
- 查看某个数据卷,name:数据卷名称
docker volume inspect ${name}
c. 文章
- 推荐文章 —— 【MySQL之PXC集群搭建】
d. 报错排查及解决
▷. ERROR! MySQL server PID file could not be found!
- 基本就是 节点启动有警告、错误信息 建议,先退出节点,排查错误:基本上退出后,就不用报这个错咯 …
▷. Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
- 执行命令:
systemctl restart docker.service
▷. ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists
- 那就删除这个文件
▷. 【Docker:You cannot remove a running container】
- 第一个节点启动,报错
2021-01-07T12:09:53.283195Z 0 [Note] Event Scheduler: Loaded 0 events
2021-01-07T12:09:53.283401Z 0 [Note] mysqld: ready for connections.
Version: '5.7.31-34-57' socket: '/tmp/mysql.sock' port: 3306 Percona XtraDB Cluster (GPL), Release rel34, Revision d76a6e8, WSREP version 31.45, wsrep_31.45
2021-01-07T12:09:53.285952Z 2 [Note] WSREP: Initialized wsrep sidno 2
2021-01-07T12:09:53.285963Z 2 [Note] WSREP: Auto Increment Offset/Increment re-align with cluster membership change (Offset: 1 -> 1) (Increment: 1 -> 1)
2021-01-07T12:09:53.285973Z 2 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification.
2021-01-07T12:09:53.286017Z 2 [Note] WSREP: Assign initial position for certification: 18, protocol version: 4
2021-01-07T12:09:53.286056Z 0 [Note] WSREP: Service thread queue flushed.
2021-01-07T12:09:53.286093Z 2 [Note] WSREP: GCache history reset: 23f2c29d-50b6-11eb-9f32-1eec49f8ecb5:0 -> 23f2c29d-50b6-11eb-9f32-1eec49f8ecb5:18
2021-01-07T12:09:53.288361Z 2 [Note] WSREP: Synchronized with group, ready for connections
2021-01-07T12:09:53.288374Z 2 [Note] WSREP: Setting wsrep_ready to true
2021-01-07T12:09:53.288377Z 2 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification.
如果发现启动有误,建议先将容器停止,不然 MySQL 服务各种报错
[root@localhost ~]# docker stop pn-mT1
pn-mT1
[root@localhost ~]# docker rm pn-mT1
pn-mT1
[root@localhost ~]#
- 此时,会注意到 MySQL 服务自动停止
▷. transport: x509: certificate has expired or is not yet valid
- 服务器间的时间不同步,参考文章:【CentOS7 时间与网络时间同步】
[root@localhost ~]# yum -y install ntp ntpdate
[root@localhost ~]# ntpdate 0.asia.pool.ntp.org
[root@localhost ~]# hwclock --systohc
[root@localhost ~]# date
2021年 01月 08日 星期五 09:54:23 CST
e. docker 部分删除命令 (慎用)
- 删除所有未被 tag 标记和未被容器使用的镜像:
$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
- 删除所有未被容器使用的镜像:
$ docker image prune -a
- 删除所有停止运行的容器:
$ docker container prune
- 删除所有未被挂载的卷:
$ docker volume prune
删除所有网络:
$ docker network prune
- 删除 docker 所有资源:
$ docker system prune
相关文章
- 直接在代码里面对list集合进行分页
- .NET Framework 4.5新特性详解
- 大数据的简要介绍
- 大数据的由来
- 高斯混合模型的自然梯度变量推理
- timing-wheel 仿Kafka实现的时间轮算法
- 使用Navicat软件连接自建数据库(Linux系统)
- 那一天,我被Redis主从架构支配的恐惧
- Redis 深入了解键的过期时间
- C#使用委托调用实现用户端等待闪屏
- 基于流计算 Oceanus 和 Elasticsearch Service 构建百亿级实时监控系统
- GRAND | 转录调控网络预测数据库
- JFreeChart API中文文档
- 临床相关突变查询数据库
- TIGER | 人类胰岛基因变化查询数据库
- 视频边缘计算网关EasyNVR在视频整体监控解决方案中的应用分析
- Apache Arrow - 大数据在数据湖后的下一个风向标
- 常见的电商数据指标体系
- AKShare-艺人数据-艺人流量价值
- MySQL中多表联合查询与子查询的这些区别,你可能不知道!