【注意】:
鄙人认为本篇适合做入门测试/学习之用,选择的"单机多节点配置"
建议移步: “多机多节点部署” ——【CentOS7.9 下 MySQL 之 PXC 集群部署【Docker+多机多节点】
PXC
集群部署实际操作一番,提高技能点,为后续的升职加薪做充足的准备
于是,在此记录一下,
既能作为采坑笔记,又能帮助到后期有需要的道友,欢迎指摘 …【注】:Percona XtraDB Cluster(简称 PXC 集群)
PXC
最大的优势:强一致性、无同步延迟, 推荐阅读:【Docker 部署 Mysql集群】
MySQL
常见集群方案 【Replication vs
PXC】CentOS版本: CentOS Linux release 7.9.2009 (Core)
MySQL 版本: 5.7.32
PXC 版本 : percona/percona-xtradb-cluster:5.7
其实,一开始,鄙人也是计划直接操作多机部署经验,基本百度出来的都是这一类的,只好先摸索一番吧 …
前期准备
3306: # mysql 实例端口
4567: # PXC cluster 相互通讯的端口
4444: # 用于 SST(State Snapshot Transfer): 全量传输
4568: # 用于 IST(Incremental state Transfer):增量传输传送
以鄙人使用宝塔面板操作为例,注意以上端口的开启:
安全增强型
Linux(Security-Enhanced Linux)SELinux
主要由美国国家安全局开发
【荐】
,永久关闭 Selinux:
"vi /etc/selinux/config"
把 "SELINUX"
属性值设置成 disabled
,然后 reboot
重启"setenforce 0"
"docker"
"docker"
,需要先执行命令:yum install -y docker
【拓展】:
docker
版本: docker -v
判断 docker
是否安装成功:docker
docker
的启动与关闭:service docker start
、service docker stop
搭建 PXC 集群
查看所有 镜像命令:
docker image ls
Docker 仓库中的 PXC 官方镜像:
https://hub.docker.com/r/percona/percona-xtradb-cluster
MySQL
版本为 5.7.32,此处对应选择的 PXC 版本就是 5.7docker 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
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
使用
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"
}
]
注意:在这一步之前,要把 MySQL 数据库停止服务 !
[root@localhost ~]# service mysqld status
SUCCESS! MySQL running (1992)
[root@localhost ~]# service mysqld stop
Shutting down MySQL.. SUCCESS!
【附录 - 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
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 ~]#
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 "
集群同步验证
最直接的方式就是操作数据库,进行数据比对
"9000、9001、9002"
连接
然后,在节点 node2 上,创建数据库 test_pxc
,以及表 test-pxc
随便更改数据,会发现,其他节点的数据也是同步变化的初步探索到这吧,后面再做多机部署的测试、整理 …
宕机操作
docker stop node2
可通过命令查看:docker ps -a
docker start node2
即可对于节点的停止操作,分第一个节点和其他节点,是不同的!
如果 【node1】 节点不是最后一个离开集群的,不能再以主节点的形式启动了
"docker start node1"
命令,过会会发现 【node1】没有启动
这时,需要通过 "docker volume inspect vMZ1"
,进入数据卷目录,查看是否存在 grastate.dat
文件"safe_to_bootstrap"
参数值修改为 1
,保存退出
然后再进入 【node1】节点中查看数据
试着修改一下,看是否和其他节点数据同步docker stop node1
、docker rm node1
然后再以指定主节点形式加入集群,注意参数 "-e CLUSTER_JOIN=node3"
的指定(此时是【node3】未停止)docker start node2
, 进入 PXC 集群创建的容器
然后,通过 docker ps
查看是否进入成功stop
,然后rm
操作
然后,再从创建节点步骤开始,执行一遍,发现又成功了!附录
命令 | 说明 |
---|---|
-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 | 来自哪个镜像创建 |
docker volume ls
docker volume create ${name}
docker volume rm ${name}
docker volume inspect ${name}
报错排查及解决
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
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 ~]#
transport: x509: certificate has expired or is not yet valid
[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
$ 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 system prune