了解 MySQL 集群之前,先看看单节点数据库的弊病
- 大型互联网程序用户群体庞大,所以架构需要特殊设计。
- 单节点数据库无法满足大并发时性能上的要求。
- 单节点的数据库没有冗余设计,无法满足高可用。
- 单节点 MySQL无法承载巨大的业务量,数据库负载巨大
常见 MySQL 集群方案
- Repliaction 集群方案
- PXC 集群方案( Percona XtraDB Cluster )
-
-
------------------------------------------------------------------
1 安装PXC镜像
1 | docker pull percona/percona-xtradb-cluster:5.7.21 |
2 为PXC镜像改名
1 | docker tag percona/percona-xtradb-cluster:5.7.21 pxc |
3 创建net1网段
1 | docker network create --subnet=172.18.0.0/16 net1 |
4 创建5个数据卷
1 2 3 4 5 | docker volume create --name v1 docker volume create --name v2 docker volume create --name v3 docker volume create --name v4 docker volume create --name v5 |
5 创建备份数据卷(用于热备份数据)
1 | docker volume create --name backup |
6 创建5节点的PXC集群
注意,每个MySQL容器创建之后,因为要执行PXC的初始化和加入集群等工作,耐心等待1分钟左右再用客户端连接MySQL。另外,必须第1个MySQL节点启动成功,用MySQL客户端能连接上之后,再去创建其他MySQL节点。
创建第1个MySQL节点
1 | docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql -v backup:/data --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc |
创建第2个MySQL节点
1 | docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v2:/var/lib/mysql -v backup:/data --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc |
创建第3个MySQL节点
1 | docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v3:/var/lib/mysql --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc |
创建第4个MySQL节点
1 | docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v4:/var/lib/mysql --privileged --name=node4 --net=net1 --ip 172.18.0.5 pxc |
创建第5个MySQL节点
1 | docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v5:/var/lib/mysql -v backup:/data --privileged --name=node5 --net=net1 --ip 172.18.0.6 pxc |
查看容器运行状态
1 | docker container ls |
------------------------ 暂停PXC集群的办法
vi /etc/sysctl.conf
#文件中添加net.ipv4.ip_forward=1这个配置
systemctl restart network
-----------------------热备份数据
冷备份
- 冷备份是关闭数据库时候的备份方式,通常做法是拷贝数据文件
- 是简单安全的一种备份方式,不能在数据库运行时备份。
- 大型网站无法做到关闭业务备份数据,所以冷备份不是最佳选择
热备份
- 热备份是在系统运行状态下备份数据
MySQL常见的热备份有LVM和XtraBackup两种方案
- LVM:linux的分区备份命令,可以备份任何数据库;但是会对数据库加锁,只能读取;而且命令复杂
- XtraBackup:不需要锁表,而且免费
XtraBackup
XtraBackup是一款基于InnoDB的在线热备工具,具有开源免费,支持在线热备,占用磁盘空间小,能够非常快速地备份与恢复mysql数据库
- 备份过程中不锁表,快速可靠
- 备份过程中不会打断正在执行地事务
- 备份数据经过压缩,占用磁盘空间小
全量备份和增量备份
- 全量备份:备份全部数据。备份过程时间长,占用空间大。第一次备份要使用全量备份
- 增量备份: 只备份变化的那部分数据。备份的时间短,占用空间小。第二次以后使用增量备份
PXC全量备份
备份要在某个PXC节点的容器内进行,但应该把备份数据保存到宿主机内。所以采用目录映射技术。先新建Docker卷:
1 | docker volume create backup |
挑选一个PXC节点node1,将其容器停止并删除,然后重新创建一个增加了backup目录映射的node1容器
1 2 3 4 5 6 | docker stop node1 docker rm node1 # 数据库数据保存在Docker卷v1中,不会丢失 # 参数改变: # 1. -e CLUSTER_JOIN=node2;原来其他节点是通过node1加入集群的,现在node1重新创建,需要选择一个其他节点加入集群 # 2. -v backup:/data;将Docker卷backup映射到容器的/data目录 docker run -d -u root -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node2 -v v1:/var/lib/mysql -v backup:/data --network=net1 --ip 172.18.0.2 --name=node1 pxc |
在node1容器中安装 percona-xtrabackup-24
1 2 3 | docker exec -it node1 bash apt- get update apt- get install percona-xtrabackup-24 |
之后便可以执行如下命令进行全量备份,备份后的数据会保存在 /data/backup/full 目录下:
1 2 3 4 | mkdir /data/backup mkdir /data/backup/full #不建议,已过时 innobackupex --backup -u root -p abc123456 --target-dir=/data/backup/full xtrabackup --backup -uroot -pabc123456 --target-dir=/data/backup/full |
官方文档已经不推荐使用 innobackupex,而推荐使用 xtrabackup 命令
-------------------------PXC全量还原
数据库可以热备份,但是不能热还原,否则会造成业务数据和还原数据的冲突。
对于PXC集群为了避免还原过程中各节点数据同步冲突的问题,我们要先解散原来的集群,删除节点。然后新建节点空白数据库,执行还原,最后再建立起其他集群节点。
还原前还要将热备份保存的未提交的事务回滚,还原之后重启MySQL
1 停止并删除PXC集群所有节点
1 2 3 | docker stop node1 node2 node3 node4 node5 docker rm node1 node2 node3 node4 node5 docker volume rm v1 v2 v3 v4 v5 |
2 按照之前的步骤重新创建node1容器,并进入容器,执行冷还原
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # 创建卷 docker volume create v1 # 创建容器 docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql -v backup:/data --name=node1 --network=net1 --ip 172.18.0.2 pxc # 以root身份进入容器 docker exec -it -uroot node1 bash # 删除数据 rm -rf /var/lib/mysql/* # 准备阶段 xtrabackup --prepare --target-dir=/data/backup/full/ # 执行冷还原 xtrabackup --copy-back --target-dir=/data/backup/full/ # 更改还原后的数据库文件属主 chown -R mysql:mysql / var /lib/mysql # 退出容器后,重启容器 docker stop node1 docker start node1 |