# 1、PXC 集群安装

## 一、安装 PXC 镜像

PXC集群比较特殊，需要安装在 linux 或 Docker 之上。这里使用 Docker进行安装！

Docker的镜像仓库中包含了 PXC数据库的官方镜像，

地址：<https://hub.docker.com/r/percona/percona-xtradb-cluster/>

安装PXC镜像有两种方式：

* 下载镜像方式：`docker pull percona/percona-xtradb-cluster`
* 导入本地镜像方式：`docker load < 路径/pxc.tar.gz`

> 由于pxc的镜像名很长，可以使用以下方式
>
> ```
> $ docker images
> $ docker tag docker.io/percona/percona-xtradb-cluster pxc
> $ docker rmi docker.io/percona/percona-xtradb-cluster
> ```

## 二、创建内部网络

> 出于安全考虑，创建出来的 PXC集群不要直接对接Docker以外的网络，因此要给PXC集群实例创建 Docker内部网络。Docker内部网段外部无法直接访问，我们可通过 docker端口映射技术将端口对外开发。

处于安全考虑，需要给PXC集群实例创建 Docker内部网络( 内部默认网段为 172.17.0.XX )：

* `docker network create 网络名` - 创建docker网络
* `docker network inspect 网络名` -  查看docker某网络详细信息
* `docker network rm 网络名` - 删除docker网络

示例

```
docker network create –subnet=172.18.0.0/24 net1
docker network inspect net1 
docker network rm net1
```

## 三、创建 Docker卷 <a href="#san-chuang-jian-docker-juan" id="san-chuang-jian-docker-juan"></a>

一旦创建出docker容器，尽量不要在容器里保存业务数据，将业务数据存储到我们的宿主机上，通常我们通过 docker的目录映射机制（把宿主机上的一个目录映射到容器内），由于业务数据都在宿主机上，即使docker容器出现故障，删除故障 docker容器，重启启动一个新的容器，把业务数据目录映射到新的容器内即可。

但是PXC集群技术比较特殊，如果为PXC集群使用了docker的目录映射技术，PXC会闪退，因此要采用另外一种目录映射技术，即使用 docker卷。

> docker卷的常用操作：
>
> * `docker volume create –name v1`
> * docker inspect v1 - 查看卷的信息，知道卷在哪。
> * `docker volume rm v1`

创建的卷v1 是可以直接在宿主机上看到目录的。将这个卷再映射给容器，此时启动容器，这样PXC容器启动就能将数据映射到卷中，我们通过宿主机也能看到映射出来的数据。

## 四、创建PXC容器 <a href="#si-chuang-jian-pxc-rong-qi" id="si-chuang-jian-pxc-rong-qi"></a>

只需要向PXC镜像传入运行参数就能创建出PXC容器。

> 创建PXC 命令如下：
>
> docker run -d -p 3306:3306\
> -v v1:/var/lib/mysql\
> -e MYSQL\_ROOT\_PASSWORD=abc123456\
> -e CLUSTER\_NAME=PXC\
> -e XTRABACKUP\_PASSWORD=abc123456\
> –privileged –name=node1 –net=net1 –ip 172.18.0.2 pxc\
> 命令解释：\
> -d 代表后台运行\
> -v 表示 v1卷映射到docker的mysql中，mysql路径为 /var/lib/mysql\
> MYSQL\_ROOT\_PASSWORD=abc123456 表示mysql 的密码，用户名默认为root\
> CLUSTER\_NAME=PXC 表示集群的名字\
> XTRABACKUP\_PASSWORD=abc123456 集群之间同步的密码\
> –privileged 为权限\
> –name ：给创建出来的容器起一个名字\
> –net ： 容器分到的内部网段\
> –ip : 容器分到的 ip地址\
> pxc 为镜像名

## 五、实战

**假设我们要创建3个数据库的集群**

内部网

```
$ docker network create –subnet=172.18.0.0/24 net1
```

docker卷

```
$ docker volume create --name v1
$ docker volume create --name v2
$ docker volume create --name v3
```

启动容器

```
/** 
* 集群中数据库端口映射不一样、docker卷不一样、
* 集群中各个容器名不一样、ip地址不一样
* 注意修改这四个地方和 创建其他容器时添加：-e CLUSTER_JOIN=node1。
*/
$ docker run -d -p 3306:3306 -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc
// 多了一个加入集群的命令
$ docker run -d -p 3307:3306 -v v2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc 

$ docker run -d -p 3308:3306 -v v3:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc
```

**切记：**

容器的创建是很快的，但是数据库创建比较慢（2分钟以上），**一定要确保第一个容器的mysql 初始化好了在创建其他容器**，其他容器需要集群到第一个容器的mysql上。可以通过mysql客户端连接来判断是否初始化好了。

数据库客户端连接时，主机为公网ip，端口为映射到宿主机上的端口，用户名root，密码为在 run容器时所指定的那个。

此时通过 `docker ps -a` 查看后台运行的容器即可。

**查看日志：**

```
docker logs -f [Container Id]
```

或者

```
docker logs -f [Container Name]
```
