基于Docker搭建Percona XtraDB Cluster数据库集群

本文实验的环境参数

  • 阿里云ECS Centos7.5
  • Docker version 18.06.0-ce
  • percona/percona-xtradb-cluster:5.7

Percona XtraDB Cluster的镜像下载地址:https://hub.docker.com/r/percona/percona-xtradb-cluster/

怎么使用Docke和下载镜像,请查看Docker的官方文档https://docs.docker.com/

接下来搭建三个容器节点

1、创建外部不可访问的Docker内部网络,使用端口映射开放外部访问

docker network create pxc-network

2、创建容器

docker volume create v1
docker volume create v2
docker volume create v3

3、创建第一个节点(因为初始化集群,所以需要等待一会,在创建第二个节点)

docker run -d 
-p 3306:3306 
-e MYSQL_ROOT_PASSWORD=abc123456 
-e CLUSTER_NAME=PXC 
-e XTRABACKUP_PASSWORD=abc123456 
-v v1:/var/lib/mysql 
--privileged 
--name=node1 
--net=pxc-network 
percona/percona-xtradb-cluster:5.7

4、创建第二个节点并加入集群

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 
--privileged 
--name=node2 
--net=pxc-network 
percona/percona-xtradb-cluster:5.7

5、创建第三个节点并加入集群

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=pxc-network 
percona/percona-xtradb-cluster:5.7

6、使用Navicat等客户端工具访问上面上个节点的数据库,地址是宿主机的地址,端口是每个节点映射的端口,然后创建数据库测试PXC运行情况。

mysql-物理备份-Percona xtrabackup

xtrabackup是percona公司开发的一个用于mysql物理热备的备份工具。

软件安装后一共有4个可执行文件:

  • innobackupex:perl脚本,用来备份非innodb表,同时会调用xtrabackup来备份innodb表,会和mysql server进行交互。如:加读锁(FTWRL),获取位点(show slave status)等。即封装了xtrabackup

  • xbcrypt:用来解密

  • xbstream:类似tar,一种支持并发写的流文件格式。和xbcrypt都在备份和解压会用到

  • xtrabackup:c/c++编译的二进制,用来备份innodb表,和mysql server没有交互

原理

通信方式:xtrabackup和innobackupex之间的交互和协调是通过控制文件的创建和删除来实现的。

主要文件:

    xtrabackup_suspended_1
    xtrabackup_suspended_2
    xtrabackup_log_copied

例:看看备份时xtrabackup_suspended_2是怎么协调2个工具进程的:

  1. innobackupex在启动xtrabackup进程后,会一直等xtrabackup备份完innodb文件,方式就是等待xtrabackup_suspended_2被创建出

  2. xtrabackup备份完innodb数据后,就在指定目录下创建出xtrabackup_suspended_2,然后等到这个文件被innobackupex删除,

  3. innobackupex 检测到文件 xtrabackup_suspended_2 被创建出来后,就继续往下走;

  4. innobackupex 在备份完非 InnoDB 表后,删除 xtrabackup_suspended_2 这个文件,这样就通知 xtrabackup 可以继续了,然后等 xtrabackup_log_copied 被创建;

  5. xtrabackup 检测到 xtrabackup_suspended_2 文件删除后,就可以继续往下了。

未分类

备份过程图

未分类

说明:

  1. innobackupex 在启动后,会先 fork 一个进程,启动 xtrabackup进程,然后就等待 xtrabackup 备份完 ibd 数据文件;

  2. xtrabackup 在备份 InnoDB 相关数据时,是有2种线程的,1种是 redo 拷贝线程,负责拷贝 redo 文件,1种是 ibd 拷贝线程,负责拷贝 ibd 文件;redo 拷贝线程只有一个,在 ibd 拷贝线程之前启动,在 ibd 线程结束后结束。xtrabackup 进程开始执行后,先启动 redo 拷贝线程,从最新的 checkpoint 点开始顺序拷贝 redo 日志;然后再启动 ibd 数据拷贝线程,在 xtrabackup 拷贝 ibd 过程中,innobackupex 进程一直处于等待状态(等待文件被创建)。

  3. xtrabackup 拷贝完成idb后,通知 innobackupex(通过创建文件),同时自己进入等待(redo 线程仍然继续拷贝);

  4. innobackupex 收到 xtrabackup 通知后,执行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位点,然后开始备份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷贝非 InnoDB 文件过程中,因为数据库处于全局只读状态,如果在业务的主库备份的话,要特别小心,非 InnoDB 表(主要是MyISAM)比较多的话整库只读时间就会比较长,这个影响一定要评估到。

  5. 当 innobackupex 拷贝完所有非 InnoDB 表文件后,通知 xtrabackup(通过删文件) ,同时自己进入等待(等待另一个文件被创建);

  6. xtrabackup 收到 innobackupex 备份完非 InnoDB 通知后,就停止 redo 拷贝线程,然后通知 innobackupex redo log 拷贝完成(通过创建文件);

  7. innobackupex 收到 redo 备份完成通知后,就开始解锁,执行 UNLOCK TABLES;

  8. 最后 innobackupex 和 xtrabackup 进程各自完成收尾工作,如资源的释放、写备份元数据信息等,innobackupex 等待 xtrabackup 子进程结束后退出。

在备份进程中都是直接通过操作系统读取数据文件的,只在执行SQL命令时和数据库有交互,基本不会影响数据库的运行,在备份非innodb时会有一段时间只读,对备份innodb表时完全没有影响。

备份innodb文件和非innodb都是通过拷贝文件,但实现的方式不一样,innodb是以page粒度(xtrabackup),在读取每个page时会检验checksum值,保证数据块是一致的;非innodb是cp或者tar(innobackupex),由于对文件做了FTWRL,磁盘上的文件也是完整的,备份的数据也是完整的。

Percona监控工具初探

Percona在2016年4月发布了一个监控套件,可以同时对多个MySQL、MongoDB实例进行监控

参考资料:
1. https://www.percona.com/blog/2016/04/18/percona-monitoring-and-management/
2. https://www.percona.com/doc/percona-monitoring-and-management/index.html
3. https://www.percona.com/doc/percona-monitoring-and-management/install.html
安装过程描述的非常详尽,参考此文档足以

环境

  • 操作系统版本CentOS 6.7

  • MySQL版本为 MySQL 5.7

1. 安装

未分类

1.1 PMM Server

负责将收集到的数据存储、聚合和展现
假定安装在192.168.100.1上

1)

docker percona/pmm-server:1.0.6

2)

docker create 
   -v /opt/prometheus/data 
   -v /opt/consul-data 
   -v /var/lib/mysql 
   -v /var/lib/grafana 
   --name pmm-data 
   percona/pmm-server:1.0.6 /bin/true

3)

$ docker run -d 
   -p 80:80 
   --volumes-from pmm-data 
   --name pmm-server 
   --restart always 
   percona/pmm-server:1.0.6

到此,docker已经启动,可以访问

未分类

其它:

进入docker能够发现

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Nov22 ?        00:00:00 /bin/bash /opt/entrypoint.sh
root        13     1  0 Nov22 ?        00:00:28 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/supervisor
mysql       16    13  0 Nov22 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe
pmm         17    13  0 Nov22 ?        00:05:23 /opt/consul agent -server -data-dir=/opt/consul-data -bootstrap -c
grafana     18    13  0 Nov22 ?        00:01:28 /usr/sbin/grafana-server --homepath=/usr/share/grafana --config=/e
root        19    13  0 Nov22 ?        00:00:00 nginx: master process nginx
root        20    13  0 Nov22 ?        00:00:00 /usr/sbin/cron -f
pmm         24    13  0 Nov22 ?        00:00:00 bash -c sleep 5 && /usr/local/percona/qan-api/start
pmm         28    13 10 Nov22 ?        02:11:57 /opt/prometheus/prometheus -config.file=/opt/prometheus/prometheus
pmm         40    13  0 Nov22 ?        00:00:00 bash -c sleep 7 && /usr/local/orchestrator/orchestrator http
root        50    13  2 Nov22 ?        00:36:27 /opt/node_exporter/node_exporter -web.listen-address=localhost:910
www-data   105    19  0 Nov22 ?        00:00:04 nginx: worker process
www-data   106    19  0 Nov22 ?        00:00:04 nginx: worker process
www-data   107    19  0 Nov22 ?        00:00:05 nginx: worker process
www-data   108    19  0 Nov22 ?        00:00:03 nginx: worker process
mysql      427    16  0 Nov22 ?        00:06:55 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-
pmm        458    24  0 Nov22 ?        00:00:00 bash /usr/local/percona/qan-api/start
pmm        471   458  0 Nov22 ?        00:03:10 /usr/local/percona/qan-api/bin/percona-qan-api -importPath github.
pmm        480   471  0 Nov22 ?        00:00:00 perl /usr/local/percona/qan-api/src/github.com/percona/qan-api/ser
pmm        499    40  0 Nov22 ?        00:03:44 /usr/local/orchestrator/orchestrator http

依照我的推断,从client端收集到的监控数据存储在MysQL中,然后经过聚合以后,在grafana中进行展现,因此为防止收集到监控数据丢失,可以在docker启动时,用-v参数把/var/lib/mysql,/var/lib/grafana 两个目录挂到宿主机上

1.2 PMM Client

负责收集MySQL的状态数据,并发给PMM Server
假定安装在192.168.200.1上

1) 安装percona仓库

sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm

2)安装client包

sudo yum install pmm-client

3)配置监控

sudo pmm-admin add mysql --user root --password xxxx --host 127.0.0.1 --port 3306

看到这里大家可能会想可以按host和port进行配置,pmm-client 是否无须部署到MySQL对应的机器上,其实这种说法是对的

pmm-client收的监控数据来源有这么几块
a. MySQL所在机器的系统指标
b. MySQL的performance_schema库
c. slow-log(慢查询日志)

所以如果我们想收集a和c中的指标的话,最好还是将pmm-client部署在MySQL所在机器

4)查看配置后的结果

sudo pmm-admin list
pmm-admin 1.0.6

PMM Server      | 192.168.100.1:80
Client Name     | wx-test-social18
Client Address  | 192.168.200.1
Service manager | unix-systemv

---------------- ----------------- ------------ -------- ----------------------------- ------------------------
SERVICE TYPE     NAME              CLIENT PORT  RUNNING  DATA SOURCE                   OPTIONS
---------------- ----------------- ------------ -------- ----------------------------- ------------------------
linux:metrics    wx-test-social18  42000        YES      -
mysql:queries    wx-test-social18  42001        YES      root:***@tcp(127.0.0.1:3306)  query_source=perfschema
mysql:metrics    wx-test-social18  42002        YES      root:***@tcp(127.0.0.1:3306)

2. 交互界面

2.1 访问http://192.168.100.1/qan/

可以查看Query的分析结果

未分类

2.2 访问http://192.168.100.1/graph/

部分系统指标

未分类

MySQL的指标数据

未分类

单表的统计情况

未分类

percona-toolkit 基本使用

运行环境:

Master:10.168.1.216
Slave:10.168.1.217

一、pt-heartbeat

监控mysql复制延迟

1.1、创建一个后台进程定期更新主上的test库的heartbeat表()默认是1s,可以–interval指定,执行后会成一个heartbeat表,ismarthome库为我监控的同步库

pt-heartbeat -D ismarthome --update --user=root --password=123456 -h10.168.1.216 --create-table –daemonize

1.2、监控复制在slave上的落后程度(会一直监控)

pt-heartbeat -D ismarthome --monitor --user=root --password=daqi-123456 -h10.168.1.217

1.3、监控复制在slave上的落后程度(监控一次退出)

pt-heartbeat -D ismarthome --check --user=root --password=daqi-123456 -h10.168.1.217

二、 pt-slave-find

查找和打印mysql所有从服务器复制层级关系

2.1、查找主服务器的mysql有所有从的层级关系

pt-slave-find --user=root --password=123456--host=10.168.1.216

三、pt-slave-restart

监视mysql复制错误,并尝试重启mysql复制当复制停止的时候

3.1、监视从,跳过1个错误

pt-slave-restart --user=root --password=daqi-123456 --host=10.168.1.217 --skip-count=1

3.2、监视从,跳过错误代码为1062的错误

pt-slave-restart --user=root --password=daqi-123456 --host=10.168.1.217 --error-numbers=1062

四、pt-table-checksum

检查数据是否一致(在主库执行)

4.1、比较test数据库同步是否一致,结果显示所有的表

pt-table-checksum  --nocheck-replication-filters --databases=testDb --replicate=testDb.checksums --create-replicate-table  --host=10.168.1.216  --port 3306  -uroot -p123456

参数说明:第一次运行的时候需要添加–create-replicate-table参数,如果不加这个就需要手工运行添加表结构的SQL,表结构SQL如下:

CREATE TABLE checksums (
   db             char(64)     NOT NULL,
   tbl            char(64)     NOT NULL,
   chunk          int          NOT NULL,
   chunk_time     float            NULL,
   chunk_index    varchar(200)     NULL,
   lower_boundary text             NULL,
   upper_boundary text             NULL,
   this_crc       char(40)     NOT NULL,
   this_cnt       int          NOT NULL,
   master_crc     char(40)         NULL,
   master_cnt     int              NULL,
   ts             timestamp    NOT NULL,
   PRIMARY KEY (db, tbl, chunk),
   INDEX ts_db_tbl (ts, db, tbl)
) ENGINE=InnoDB
  • –nocheck-replication-filters :不检查复制过滤器,建议启用。后面可以用–databases来指定需要检查的数据库。
  • –no-check-binlog-format :不检查复制的binlog模式,要是binlog模式是ROW,则会报错。

  • –replicate-check-only :只显示不同步的信息。(注意:要谨慎使用,此参数不会生成新的checksums数据,只会根据checksums表已经有的数据来显示。)

  • –replicate= :把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。
  • –databases= :指定需要被检查的数据库,多个则用逗号隔开。
  • –tables= :指定需要被检查的表,多个用逗号隔开
  • h=127.0.0.1 :Master的地址
  • u=root :用户名
  • p=123456 :密码
  • P=3306 :端口

运行结果行显示的结果参数说明:

  • TS :完成检查的时间。
  • ERRORS :检查时候发生错误和警告的数量。
  • DIFFS :0表示一致,1表示不一致。当指定–no– – replicate-check时,会一直为0,当指定–replicate-check-only会显示不同的信息。
  • ROWS :表的行数。
  • CHUNKS :被划分到表中的块的数目。
  • SKIPPED :由于错误或警告或过大,则跳过块的数目。
  • TIME :执行的时间。
  • TABLE :被检查的表名。

备注:

(pt-table-checksum 其工作原理是通过计算每个表的散列值 并将计算过程在服务器上重放 从而拿到主从各自的散列值做比较,但是pt-table-checksum 不是直接计算整个表的散列值,而是分块计算避免服务器长时间延时 因此在计算散列过程重放时是基与statement 不能基于row)

五、pt-table-sync

高效同步mysql表的数据
原理:总是在主上执行数据的更改,再同步到从上,不会直接更改成从的数据,在主上执行更改是基于主上现在的数据,不会更改主上的数据。注意使用之前先备份你的数据,避免造成数据的丢失.执行execute之前最好先换成–print或–dry-run查看一下会变更哪些数据。

  • –print :打印,但不执行命令。
  • –execute :执行命令。

5.1、同步Master(10.168.1.216)上a表数据到Slave(10.168.1.217),在执行之前可以用–execute参数换成–print来查看会变更什么东西,命令里有2个ip,第一次出现的是M的地址,第2次是Slave的地址

查看:pt-table-sync –print –user=root –password=123456 h=10.168.1.216,D=testDb,t=aaa h=192.168.3.92

同步:pt-table-sync –execute –user=root –password=123456 h=10.168.1.216,D=testDb,t=aaa h=192.168.3.92

5.2、同步Master(10.168.1.216)上数据到Slave(10.168.1.217)

pt-table-sync --execute --sync-to-master --user=root --password=123456  h=10.168.1.217 --database testDb

5.3、只同步指定的a表

pt-table-sync --execute --sync-to-master --user=root --password=123456  h=10.168.1.217,D=testDb,t=a

5.4、根据pt-table-checksum的结果进行数据同步

pt-table-sync --execute --replicate testDb.checksums --user=root --password=123456 h=10.168.1.216

5.5、根据pt-table-checksum使从的数据和主的数据一致

pt-table-sync --execute --replicate test.checksums --user=root --password=123456  --sync-to-master h=10.168.1.217,D=testDb,t=a

Percona XtraDB Cluster 集群环境建立与验证指南

Percona XtraDB Cluster 是MySQL数据库的一种集群方案。并且与 MySQL Server 社区版本、Percona Server 和 MariaDB 兼容。

一、在Ubuntu上安装Percona XtraDB Cluster

实验环境:

假设有3台计算机设备安装了ubuntu系统,将被用作3个节点:

Node       Host        IP

Node1      pxc1        172.16.24.209
Node2      pxc2        172.16.24.208
Node3      pxc3        172.16.24.207

前置条件:

(1) 确保以下端口没被防火墙屏蔽或被其他进程占用:

  • 3306
  • 4444
  • 4567
  • 4568

(2) 卸载 apparmor

sudo apt-get remove apparmor

安装步骤:

在每一台设备上执行下列命令:

wget https://repo.percona.com/apt/percona-release_0.1-4.$(lsb_release -sc)_all.deb
sudo dpkg -i percona-release_0.1-4.$(lsb_release -sc)_all.deb
sudo apt update
sudo apt install percona-xtradb-cluster-full-57
passord:frank

至此,percona-xtradb-cluster已经安装,登录 MySQL.

mysql -u root -p

(输入密码 “frank”)。

添加用户

mysql> CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 'passw0rd';
mysql> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'sstuser'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> quit
sudo service mysql stop   

二、配置节点

1. 初始化集群

以第1台设备作为第1个集群节点。在 /etc/mysql/my.cnf 添加如下配置:

[mysqld]
wsrep_provider=/usr/lib/libgalera_smm.so
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://
wsrep_node_name=pxc1
wsrep_node_address=172.16.24.209
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2

完成修改之后,执行:

sudo /etc/init.d/mysql bootstrap-pxc

数据库将以自举模式启动。至此,集群初始化工作已经完成。登录MySQL,执行如下命令,查看初始化结果:

mysql> show status like 'wsrep%';
+----------------------------------+--------------------------------------+
| Variable_name                    | Value                                |
+----------------------------------+--------------------------------------+
| wsrep_local_state_uuid          | 0d718de1-a19c-11e7-81e3-127c64915155 |
| wsrep_protocol_version          | 7                                    |
| wsrep_last_committed            | 4                                    |
...
| wsrep_local_state_comment        | Synced                              |
...
| wsrep_cluster_conf_id            | 1                                    |
| wsrep_cluster_size              | 1                                    |
| wsrep_cluster_state_uuid        | 0d718de1-a19c-11e7-81e3-127c64915155 |
| wsrep_cluster_status            | Primary                              |
| wsrep_connected                  | ON                                  |
| wsrep_local_bf_aborts            | 0                                    |
| wsrep_local_index                | 0                                    |
| wsrep_provider_name              | Galera                              |
| wsrep_provider_vendor            | Codership Oy <info@codership.com>    |
| wsrep_provider_version          | 3.22(r8678538)                      |
| wsrep_ready                      | ON                                  |
+----------------------------------+--------------------------------------+
67 rows in set (0.00 sec)

2. 添加节点

添加第2台设备,修改其配置文件 /etc/mysql/my.cnf ,添加如下语句:

[mysqld]
wsrep_provider=/usr/lib/libgalera_smm.so
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://172.16.24.209,172.16.24.208,172.16.24.207
wsrep_node_name=pxc2
wsrep_node_address=172.16.24.208
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2

退出重启即可。重启后也登录MySQL,执行“show status like ‘wsrep%’;”,查看添加结果。

添加第3台设备,修改其配置文件 /etc/mysql/my.cnf ,添加如下语句:

[mysqld]
wsrep_provider=/usr/lib/libgalera_smm.so
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://172.16.24.209,172.16.24.208,172.16.24.207
wsrep_node_name=pxc3
wsrep_node_address=172.16.24.207
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2

退出重启即可。重启后也登录MySQL,执行“show status like ‘wsrep%’;”,查看添加结果。

使第一台设备工作在正常模式。修改其配置文件 /etc/mysql/my.cnf ,添加如下语句:

[mysqld]
wsrep_provider=/usr/lib/libgalera_smm.so
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://172.16.24.209,172.16.24.208,172.16.24.207
wsrep_node_name=pxc1
wsrep_node_address=172.16.24.209
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2

重启。

三、验证写集复制功能(Write-Set Replication)

1. Create a new database on the second node:

mysql> CREATE DATABASE testDB1;
Query OK, 1 row affected (0.00 sec)

2. Create a table on the third node:

mysql> USE testDB1
Database changed
mysql> CREATE TABLE example (node_id INT PRIMARY KEY, node_name VARCHAR(30));
Query OK, 0 rows affected (0.01 sec)

3. Insert records on the first node:

mysql> INSERT INTO testDB1.example VALUES (1, 'percona1');
Query OK, 1 row affected (0.01 sec)

4. Retrieve rows from that table on the second node:

mysql> SELECT * FROM testDB1.example;
+---------+-----------+
| node_id | node_name |
+---------+-----------+
|      1 | percona1  |
+---------+-----------+
1 row in set (0.00 sec)