PXC基于docker搭建mysql集群全过程

        之前用mysql自带的bin-log复制,总是因为各种冲突,同步就阻塞掉了,一旦阻塞掉了,不主动发现,同步就终止了。还需要想办法手动去处理。所以考虑重新搭建集群。发现PXC方案不错,可以上两台,对服务器数量要求低些。遇到了很多坑。尝试过程中,比如如下:

It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1 .

 Provider/Node (gcomm://) failed to establish connection with cluster (reason: 7)

真是一步一坎,

       踏过的坑有以下:

The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.

Can't create/write to file '/data/is_writable'

2023-08-15T00:48:52.645743Z 0 [ERROR] [MY-000000] [WSREP-SST] FATAL: PXC is receiving an SST from a node with a higher version.

failed to open gcomm backend connection: 131: No address to connect (FATAL)

2023-08-15T08:42:26.138544Z 0 [ERROR] [MY-000000] [WSREP] Provider/Node (gcomm://) failed to establish connection with cluster (reason: 7)

/entrypoint.sh: line 344: /var/lib/mysql//version_info: Permission denied

mysqld: Can't read dir of '/etc/my.cnf.d/' (OS errno 2 - No such file or directory)

        简述一下我对pxc这次调研的理解。pxc确实可以两台完成集群,只要有一台活着就行,按照官网资料,数据库一旦启动,就必须保障永远活着,不能全挂(不过对于资源和人力紧张的公司来说,这个要求有点过高了,所以调研全挂,如何保障数据库还能启动起来就是很有必要的)。经验证,一旦宕了一台,由于docker启动参数设定了加入某个节点,所以会启动不起来,需要删了,重新加入,后面说方法。

-----------------------------------------分割线放本人亲测过的集群方法-----------------------------

首先官网安装教程地址:Running Percona XtraDB Cluster in a Docker Container - Percona XtraDB Cluster

       不过官网说得比较简单了,毕竟是在一个机器做的demo,但是我们需要跨多个机器,甚至不同ip段,这样才稳定。

        本人用的linux是openSUSE,可能遇到问题会多些,也许ubantu会顺利。但我想,实现过程和逻辑应该是一致的。

      本人此次采用percona8,大量能搜到的是基于5.7的。

      好的,放步骤。

一、准备工作

0.准备三台机器,可以不同ip段的,我们姑且命名为机器P1,P2,P3。后面节点的名称也按照此命名。

1.创建证书存放的地方,percona集群要求必须安装证书,集群实现加密通讯

        这里官网说的没问题,我跟官网保持一致,便于说明问题,在root下创建两个目录
 

mkdir -m 777 -p ~/pxc-docker-test/config

mkdir -m 777 -p ~/pxc-docker-test/cert

        这里要声明一下,他这个docker权限比较小,必须要给权限777才行,本人尝试给775,报权限不足。

2.像官网一样,在config下面创建一个custom.cnf文件

[mysqld]
ssl-ca = /cert/ca.pem
ssl-cert = /cert/server-cert.pem
ssl-key = /cert/server-key.pem

[client]
ssl-ca = /cert/ca.pem
ssl-cert = /cert/client-cert.pem
ssl-key = /cert/client-key.pem

[sst]
encrypt = 4
ssl-ca = /cert/ca.pem
ssl-cert = /cert/server-cert.pem
ssl-key = /cert/server-key.pem

3.生成证书,以下是官网给出的例子

docker run --name pxc-cert --rm -v ~/pxc-docker-test/cert:/cert percona/percona-xtradb-cluster:8.0 mysql_ssl_rsa_setup -d /cert

 

        在这里就出问题了,命令跑了一下,发现证书并没有生成出来。日志输出看了下,也没有报错。

        经过分析发现,这个命令创建了一个pxc-cert容器,利用mysql自身的安全命令去生成证书,生成证书到我们自定义的目录,在容器退出时,删除容器。一切看起来完美,但是研究发现,该容器是由于封装,造成执行命令权限不够,其实mysql_ssl_rsa_setup并没有执行。

        本人最终分三次执行,先是执行了

docker run --name pxc-cert  -v ~/pxc-docker-test/cert:/cert -v /pxc:/cert
percona/percona-xtradb-cluster:8.0

docker exec -it --user root pxc-cert /bin/bash

mysql_ssl_rsa_setup -d /cert

        这个方式比较麻烦,就是因为该容器封装的权限没有给命令授权造成的。真是几乎什么命令都没有,所以第二个命令就是通过root进去,将文件生成出来,映射出去。

         后来发现其实这个8.0版本容器有很多问题,我最终拉取镜像的时不加版本,让其拉取最新的,发现得到了修正。

docker run --name pxc-cert --rm -v ~/pxc-docker-test/cert:/cert percona/percona-xtradb-cluster mysql_ssl_rsa_setup -d /cert

        哎,官网实在太不严肃了,就这个浪费我不少时间。

4.创建数据存放卷,与某个磁盘目录映射

        创建的卷跟某个磁盘目录关联,命令如下:

      

 docker volume create --driver local -o o=bind -o type=none -o device=/data/p1 p1

        数据一般放在一个单独的磁盘上,大家可以在三个服务器上分别定义 /data/p1,/data/p2,/data/p3目录,然后创建卷p1,p2,p3

        必须强调的是,数据存卷是必须要去创建的。这样一旦数据库宕机时候,方便重新挂载,如果用docker随机生成的卷目录,且不说可能不是挂在数据磁盘上,光是挂载就很头疼了。

二、搭建swarm集群,因为跨ip段,需要用到swarm建立内部虚拟网络

        利用swarm搭建虚拟网络集群,网上例子很多,此处不作详述,直接上命令,大家可以自行搜索网上资料学习。

1. 令某一台机器作为manager(如192.168.1.8)

localhost:~ # docker swarm init
Swarm initialized: current node (dt2zejjryeqj7g55xw07m8gbe) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-1n45o1zb96ju8ftt8vmgqix2dixx55ql14n57bbhdjwxhm0lgd-29aib4jbopcjocx33n4xdx776 192.168.1.8:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

2.在两台从机分别执行主节点生成的token加入命令,直接拷贝来用

docker swarm join --token SWMTKN-1-1n45o1zb96ju8ftt8vmgqix2dixx55ql14n57bbhdjwxhm0lgd-29aib4jbopcjocx33n4xdx776 192.168.1.8:2377

        注意,这个是manager生成的。执行完成,可以在manager机器上执行

docker node ls

        查看三个节点情况

3.创建虚拟网络pxc-net

docker network create -d overlay --attachable pxc-net

三、每台机器依次创建docker percona容器

docker run -d -e MYSQL_ROOT_PASSWORD=test1234# -e CLUSTER_NAME=pxc-cluster1 --privileged --name=p1 --net=pxc-network  -v ~/pxc-docker-test/cert:/cert  -v ~/pxc-docker-test/config:/etc/percona-xtradb-cluster.conf.d -v p1:/var/lib/mysql -v /opt/pxc:/pxc -p 3306:3306 -p 33060:33060  pxc 


docker run -d -e MYSQL_ROOT_PASSWORD=test1234# -e CLUSTER_NAME=pxc-cluster1 --privileged --name=p2 -e CLUSTER_JOIN=p1  --net=pxc-network  -v ~/pxc-docker-test/cert:/cert  -v ~/pxc-docker-test/config:/etc/percona-xtradb-cluster.conf.d -v p2:/var/lib/mysql -v /opt/pxc:/pxc -p 3306:3306 -p 33060:33060  pxc

docker run -d -e MYSQL_ROOT_PASSWORD=test1234# -e CLUSTER_NAME=pxc-cluster1 --privileged --name=p3 -e CLUSTER_JOIN=p1  --net=pxc-network  -v ~/pxc-docker-test/cert:/cert  -v ~/pxc-docker-test/config:/etc/percona-xtradb-cluster.conf.d -v p3:/var/lib/mysql -v /opt/pxc:/pxc -p 3306:3306 -p 33060:33060  pxc

        这里与官网不一样的地方是多了两个目录映射,-v /p3:/var/lib/mysql -v /opt/pxc:/pxc pxc,一个是存储数据位置,一个是预留的映射,万一有想抢救的东西,可以扔到这里来。p1节点没有join参数,因为他他是主节点。顺便加了端口映射,便于外部访问数据库。

        至此,当用命令  docker logs -f p1,可以看到如下的信息,说明集群已经成功。

 members(3):
        0: 08da169e-3bd2-11ee-9183-03611c27ba2c, 7d8078357c4b
        1: 700b2820-3b4f-11ee-ba0c-e6b61b7caa20, 858765ba928a
        2: da69b5a0-3be9-11ee-9344-774c271ae19a, 50f3164c103b

四、测试数据同步

可以在任意一台机器执行命令

docker exec -it p2 /usr/bin/mysql -uroot -ptest1234#

        随便在网上找了几张表和创建数据的实例。

create database demo
use demo
CREATE TABLE tb_emp1
(
    id      INT(11),
    name   VARCHAR(25),
    deptId  INT(11),
    salary  FLOAT
);

CREATE TABLE tb_emp8
(
    id      INT(11) PRIMARY KEY AUTO_INCREMENT,
    name   VARCHAR(25) NOT NULL,
    deptId  INT(11),
    salary  FLOAT
);

INSERT INTO tb_emp8 (name,salary) VALUES('Lucy',1000), ('Lura',1200),('Kevin',1500);

        发现三个节点果然同步过来,感觉相当不错。

        好吧,现在要开始测试集群的能力好不好了。

四、对集群的测试结果

1.关闭从节点

        由于集群时,p2,p3节点指定加入p1,任意关系一台,重启,轻松无压力,迅速起来,该期间添加的数据,也可以同步到启动的机器中。

2.关闭主节点

        将p1关闭,发现无法启动。报

[ERROR] WSREP: It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1 .
 

        网上有文章说,找到grastate.dat文件,将 safe_to_bootstrap 从1改成0即可。

        我需要指出的是,这是完全错误的。safe_to_bootstrap 是用来标识是否是主节点,它已经宕机了,自然不再是主节点。

        如果改成了0,去启动容器,虽然容器成功启动了,但是其实,他已经脱离了集群,跟其他两台互相访问不到。

        目前能够验证成功的做法是,删除此项docker,在原有的启动参数增加加入p2或者p3的参数,即可正常启动,此时,p2或p3就成了主节点,查看该服务器grastate.dat 会发现,他的 safe_to_bootstrap是1,其他是0.

        需要指出的是,笔者曾经尝试不删除docker容器,修改原有参数,在containers目录中找到了config.v2.json,企图增加-e CLUSTER_JOIN=p2参数,并按照网上说的,关闭docker服务,再重启,结果并没有成功,虽然参数修改成功了,后来深入研究发现,percona容器将mysql的配置卸在一个node.cnf的文件夹中,该文件在容器初次创建时生成,指定了加入集群的机器名字,笔者尝试将其映射出来,结果没有成功。

        所以最终只能删除p1节点容器,重新创建,这时候大家就看到数据目录映射的好处了。

docker run -d -e MYSQL_ROOT_PASSWORD=test1234# -e CLUSTER_NAME=pxc-cluster1  -e CLUSTER_JOIN=p2 --privileged --name=p1 --net=pxc-network  -v ~/pxc-docker-test/cert:/cert  -v ~/pxc-docker-test/config:/etc/percona-xtradb-cluster.conf.d -v /p1:/var/lib/mysql -v /opt/pxc:/pxc  pxc 

        此命令只多了join p2参数

3.三台节点全部关闭

        全部关闭了以后,都起不来了。其实不难分析,因为p1指向了要连接p2,p2和p3启动时指向了要连接p1,好嘛,在这里卡bug呢。结果肯定都起不来。而且我要说的是,纵然当时p1没有指向任何节点,如果p1不是最后一个关闭的话,p1是起不来的,p1起不来,p2,p3也就起不来,只有恰好p1一直是主节点,并且是最后关闭的,那么先启动p1,再启动p2,p3是没有问题的。但是现实是残酷的,怎么可能按照我们的医院,按顺序关闭,怎么能不保证p1不先挂了呢。

        那怎么办。办法当然有!

解决方案如下:

1)首先寻找上文提到的grastate.dat文件,就在我们映射的数据目录下,如/p1,查看哪台机器该文件safe_to_bootstrap参数是1,说明他是最后关闭的,如果这样还不敢肯定他就是最后一台,还可以看看该文件的另一个参数,seqno,谁的大,也能说明谁将优先启动,其他的作为从节点加入进来。

 cat grastate.dat 
# GALERA saved state
version: 2.1
uuid:    f343f968-3bde-11ee-8641-aa02dcbe5335
seqno:   -1
safe_to_bootstrap: 0

2)删除已经存在的三个容器id,准备重建

3)执行本文大标题三示意的命令,重建docker.

        需要注意,第一个为主的节点不加join参数,也不一定是p1,以实际为主,其他join参数也要改成第一个启动的节点名字。这样的话,就可以起来了。这时候,大家就能更加感受到映射目录的好处。

        这里还需要强调的是,一定要注意挂载数据目录,尤其是主节点,加入主节点时忘记挂载目录,从节点即使挂载了,由于加入到主节点,你会惊喜的发现,啥都没了,你要从0开始。。。。这意味着,你把从节点目录的东西都删除了。幸运的是,主节点的目录还在,但万一你又不小心给他搞没了呢,一切皆有可能,所以挂载前,不放把映射目录压缩个包备份一下。。。。

4.反思一种极端情况

        万一,因为断电,不可抗力等,数据库全线崩盘,发现重做docker也起不起来了怎么办。这不要坑死了!

        我想有两个解决方案。

        一个是两地三中心,数据库庞大且重要,就要弄他十个八个,按照笔者redis集群的经验,数量达到一定量级之后,基本上确实没啥压力,不过percona这种全量集群方式,效率倒是个需要重视的问题。

         还有一个就是要备份喽,冷备份和热备份都用上。我还没测。等后面用上,再单开一个备份的帖子。

五、备份及恢复

      1.备份:  创建一个备份目录backup,执行以下命令

docker run --rm --network pxc-network -v /backup:/backup -v p2:/var/lib/mysql percona/percona-xtrabackup:latest xtrabackup --backup --target-dir=/backup --user=root --password=test1234# --host=192.168.1.8 --port=3306 --skip-log 

需要指出的是:其中p2:/var/lib/mysql ,p2可以是卷,也可以换成映射mysql的目录。查一些资料中没有指定ip、端口号,经笔者测试,如果不指定ip和端口号,由于mysql运行在docker中,会报出如下错误:

2023-08-18T06:11:19.934905-00:00 0 [ERROR] [MY-011825] [Xtrabackup] Failed to connect to MySQL server: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'

以上的命令可以指定数据库 加参数 --database XXX

       2.恢复

       笔者模拟恢复过程如下:

       1)新建了一个mysql数据库,初始化成功后将其关停,并删除数据目录。

       2)将刚才备份好的所有文件全部拷贝到新数据库映射目录下

      3)启动数据库,发现数据已经恢复进来。

六、一些tip

1.数据库表要设定主键,否则无法同步。

2.经测试,两个节点并发插入没有问题,如果是id自增长,每个节点会根据集群数量跳号,各用各的号,这个设计很nice

3.客户端连接慢,在上面文章提到的custom.cnf 【mysqld】下面加上

skip-name-resolve #Don’t resolve hostnames

重启服务即可。

4.外部访问授权:

use mysql;
select user,host from user;
update root的host为%
update user set host '%' where user ='root';

grant all PRIVILEGES on *.* to root@'%' WITH GRANT OPTION;
ALTER user 'root'@'%' IDENTIFIED BY '密码' PASSWORD EXPIRE NEVER;
ALTER user 'root'@'localhost' IDENTIFIED BY '密码' PASSWORD EXPIRE NEVER;
alter user'root'@'%' IDENTIFIED BY 'test1234#'; 
alter user 'root'@'localhost' IDENTIFIED BY 'test1234#';

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是创建MySQL 8的PXC集群的步骤: 1.安装DockerDocker Compose 在安装Docker之前,需要先卸载旧版本的Docker。然后,按照相应的操作系统的指引安装最新版本的DockerDocker Compose。 2.创建Dockerfile 创建Dockerfile,以便Docker能够构建MySQL 8的PXC镜像。下面是一个示例Dockerfile: ``` FROM mysql:8.0 RUN apt-get update && apt-get install -y wget gnupg2 RUN wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb RUN dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb RUN apt-get update && apt-get install -y percona-xtradb-cluster-57 COPY my.cnf /etc/mysql/my.cnf CMD ["mysqld"] ``` 3.创建docker-compose.yml文件 在docker-compose.yml中定义PXC集群的服务。下面是一个示例docker-compose.yml文件: ``` version: '3' services: db1: image: mysql-pxc hostname: db1 ports: - "3306:3306" volumes: - /data/mysql/db1:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root - CLUSTER_NAME=mycluster - CLUSTER_JOIN=db1,db2,db3 db2: image: mysql-pxc hostname: db2 volumes: - /data/mysql/db2:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root - CLUSTER_NAME=mycluster - CLUSTER_JOIN=db1,db2,db3 db3: image: mysql-pxc hostname: db3 volumes: - /data/mysql/db3:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root - CLUSTER_NAME=mycluster - CLUSTER_JOIN=db1,db2,db3 ``` 4.构建和启动PXC集群 使用以下命令构建和启动PXC集群: ``` docker-compose up --build -d ``` 5.验证PXC集群 使用以下命令验证PXC集群是否正常工作: ``` docker exec -it pxc_db1 mysql -uroot -proot -e "SHOW STATUS LIKE 'wsrep_cluster_size'" ``` 如果输出结果是3,那么就表示PXC集群已经成功创建。 以上就是创建MySQL 8的PXC集群的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值