专业的定制型网站建设,wordpress 基础知识,龙泉驿最新消息,做网站如何网站考虑优化一、PXC 介绍1.1 PXC 简介PXC 是一套 MySQL 高可用集群解决方案#xff0c;与传统的基于主从复制模式的集群架构相比 PXC 最突出特点就是解决了诟病已久的数据复制延迟问题#xff0c;基本上可以达到实时同步。而且节点与节点之间#xff0c;他们相互的关系是对等的。PXC 最…一、PXC 介绍1.1 PXC 简介PXC 是一套 MySQL 高可用集群解决方案与传统的基于主从复制模式的集群架构相比 PXC 最突出特点就是解决了诟病已久的数据复制延迟问题基本上可以达到实时同步。而且节点与节点之间他们相互的关系是对等的。PXC 最关注的是数据的一致性对待事物的行为时要么在所有节点上执行要么都不执行它的实现机制决定了它对待一致性的行为非常严格这也能非常完美的保证 MySQL 集群的数据一致性1.2 PXC特性和优点完全兼容 MySQL。同步复制事务要么在所有节点提交或不提交。多主复制可以在任意节点进行写操作。在从服务器上并行应用事件真正意义上的并行复制。节点自动配置数据一致性不再是异步复制。故障切换因为支持多点写入所以在出现数据库故障时可以很容易的进行故障切换。自动节点克隆在新增节点或停机维护时增量数据或基础数据不需要人工手动备份提供galera cluster会自动拉取在线节点数据集群最终会变为一致PXC最大的优势强一致性、无同步延迟1.3 PXC的局限和劣势复制只支持InnoDB 引擎其他存储引擎的更改不复制写入效率取决于节点中最慢的一台1.4 PXC与Replication的区别ReplicationPXC数据同步是单向的master负责写然后异步复制给slave如果slave写入数据不会复制给master。数据同步时双向的任何一个mysql节点写入数据都会同步到集群中其它的节点。异步复制从和主无法保证数据的一致性同步复制事务在所有集群节点要么同时提交要么同时不提交1.5 PXC 常用端口3306数据库对外服务的端口号。4444请求SST的端口。4567组成员之间进行沟通的一个端口号4568用于传输IST。名词解释SST(State Snapshot Transfer): 全量传输IST(Incremental state Transfer):增量传输二、实践2.1 搭建 PXC 集群与 MySQL 不同的是 PXC 官方提供了 Docker 镜像所以我们可以很方便的搭建 PXC 集群。1)下载 Docker 镜像docker pull percona/percona-xtradb-cluster:5.7重命名镜像名称docker tag percona/percona-xtradb-cluster:5.7 pxc:5.73)删除原始镜像docker rmi percona/percona-xtradb-cluster:5.7创建 Docker 网络用于 PXC 集群独立使用docker network create pxc-network创建数据卷用于之后挂载docker volume create --name v1docker volume create --name v2docker volume create --name v3注PXC容器只支持数据卷挂载方式不支持目录挂载创建第一个节点docker run -di --namepn1 --netpxc-network -p 9000:3306 -v v1:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD123456 -e CLUSTER_NAMEcluster1 -e XTRABACKUP_PASSWORD123456 pxc:5.7因为后续节点的添加需要关联到第一个节点所以需要等待数据库启动完成。通过 docker logs pn1 查看日志如果出现下面的输出证明启动成功:2019-09-04T06:27:30.085880Z 0 [Note] InnoDB: Buffer pool(s) load completed at 190904 6:27:30注CLUSTER_NAME 名称不要用关键字PXC否则无法启动。加入第二个节点docker run -di --namepn2 --netpxc-network -p 9001:3306 -v v2:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD123456 -e CLUSTER_NAMEcluster1 -e XTRABACKUP_PASSWORD123456 -e CLUSTER_JOINpn1 pxc:5.7需要注意是第二个节点开始需要增加 e CLUSTER_JOINpn1 参数表示与 pn1 节点同步,否则 pn1 容器会自动关闭。当 PXC集群中存在两个节点以上之后就没有主节点的概念了。集群中最后一个退出的节点就会变为主节点在 /var/lib/mysql/grastate.dat 文件中属性 safe_to_bootstrap 的值 会从 0 被设置为 1 表示该节点是主节点。8)加入第三个节点docker run -di --namepn3 --netpxc-network -p 9002:3306 -v v3:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD123456 -e CLUSTER_NAMEcluster1 -e XTRABACKUP_PASSWORD123456 -e CLUSTER_JOINpn2 pxc:5.7可以看到我们这次我们 CLUSTER_JOIN 的是 pn2 容器可以证明我们刚刚说的 当 PXC 集群存在两个节点以上之后就没有主节点的概念了 这个说法是正确的。9)进入 pn1 节点docker exec -it pn1 /usr/bin/mysql -uroot -p123456查看状态mysql show status like wsrep%;-----------------------------------------------------------------------------------| Variable_name | Value |-----------------------------------------------------------------------------------| wsrep_local_state_uuid | 068dd5e8-cedd-11e9-904d-466e75bd8fe1 || wsrep_protocol_version | 9 || wsrep_last_applied | 16 || wsrep_last_committed | 16 || wsrep_replicated | 0 || wsrep_replicated_bytes | 0 || wsrep_repl_keys | 0 || wsrep_repl_keys_bytes | 0 || wsrep_repl_data_bytes | 0 || wsrep_repl_other_bytes | 0 || wsrep_received | 10 || wsrep_received_bytes | 800 || wsrep_local_commits | 0 || wsrep_local_cert_failures | 0 || wsrep_local_replays | 0 || wsrep_local_send_queue | 0 || wsrep_local_send_queue_max | 1 || wsrep_local_send_queue_min | 0 || wsrep_local_send_queue_avg | 0.000000 || wsrep_local_recv_queue | 0 || wsrep_local_recv_queue_max | 2 || wsrep_local_recv_queue_min | 0 || wsrep_local_recv_queue_avg | 0.100000 || wsrep_local_cached_downto | 0 || wsrep_flow_control_paused_ns | 0 || wsrep_flow_control_paused | 0.000000 || wsrep_flow_control_sent | 0 || wsrep_flow_control_recv | 0 || wsrep_flow_control_interval | [ 173, 173 ] || wsrep_flow_control_interval_low | 173 || wsrep_flow_control_interval_high | 173 || wsrep_flow_control_status | OFF || wsrep_cert_deps_distance | 0.000000 || wsrep_apply_oooe | 0.000000 || wsrep_apply_oool | 0.000000 || wsrep_apply_window | 0.000000 || wsrep_commit_oooe | 0.000000 || wsrep_commit_oool | 0.000000 || wsrep_commit_window | 0.000000 || wsrep_local_state | 4 || wsrep_local_state_comment | Synced || wsrep_cert_index_size | 0 || wsrep_cert_bucket_count | 22 || wsrep_gcache_pool_size | 1592 || wsrep_causal_reads | 0 || wsrep_cert_interval | 0.000000 || wsrep_open_transactions | 0 || wsrep_open_connections | 0 || wsrep_ist_receive_status | || wsrep_ist_receive_seqno_start | 0 || wsrep_ist_receive_seqno_current | 0 || wsrep_ist_receive_seqno_end | 0 || wsrep_incoming_addresses | 172.19.0.2:3306,172.19.0.3:3306,172.19.0.4:3306|| wsrep_cluster_weight | 3 || wsrep_desync_count | 0 || wsrep_evs_delayed | || wsrep_evs_evict_list | || wsrep_evs_repl_latency | 0/0/0/0/0 || wsrep_evs_state | OPERATIONAL || wsrep_gcomm_uuid | 11ed51e2-cedd-11e9-b362-af453a7ac074 || wsrep_cluster_conf_id | 3 || wsrep_cluster_size | 3 || wsrep_cluster_state_uuid | 068dd5e8-cedd-11e9-904d-466e75bd8fe1 || 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 || wsrep_provider_version | 3.37(rff05089) || wsrep_ready | ON |-----------------------------------------------------------------------------------71 rows in set (0.06 sec)可以看到 wsrep_incoming_addresses 的值就是我们三个容器的IP地址| wsrep_incoming_addresses | 172.19.0.2:3306,172.19.0.3:3306,172.19.0.4:3306 |集群完整性检查属性含义wsrep_cluster_state_uuid在集群所有节点的值应该是相同的,有不同值的节点,说明其没有连接入集群.wsrep_cluster_conf_id正常情况下所有节点上该值是一样的.如果值不同,说明该节点被临时”分区”了.当节点之间网络连接恢复 的时候应该会恢复一样的值.wsrep_cluster_size如果这个值跟预期的节点数一致,则所有的集群节点已经连接.wsrep_cluster_status集群组成的状态.如果不为”Primary”,说明出现”分区”或是”split-brain”脑裂状况.节点状态检查属性含义wsrep_ready该值为 ON,则说明可以接受 SQL 负载.如果为 Off,则需要检查 wsrep_connectedwsrep_connected如果该值为 Off,且 wsrep_ready 的值也为 Off,则说明该节点没有连接到集群.(可能是 wsrep_cluster_address 或 wsrep_cluster_name 等配置错造成的.具体错误需要查看错误日志)wsrep_local_state_comment如果 wsrep_connected 为 On,但 wsrep_ready 为 OFF,则可以从该项查看原因复制健康检查:属性含义wsrep_flow_control_paused表示复制停止了多长时间.即表明集群因为 Slave 延迟而慢的程度.值为 0~1,越靠近 0 越好,值为 1 表示 复制完全停止.可优化 wsrep_slave_threads 的值来改善wsrep_cert_deps_distance有多少事务可以并行应用处理.wsrep_slave_threads 设置的值不应该高出该值太多wsrep_flow_control_sent表示该节点已经停止复制了多少次*wsrep_local_recv_queue_avg表示 slave 事务队列的平均长度.slave 瓶颈的预兆. 最慢的节点的 wsrep_flow_control_sent 和 wsrep_local_recv_queue_avg 这两个值最高.这两个值较低的话,相对更好检测慢网络问题属性含义wsrep_local_send_queue_avg网络瓶颈的预兆.如果这个值比较高的话,可能存在网络瓶颈冲突或死锁的数目:属性含义wsrep_last_committed最后提交的事务数目wsrep_local_cert_failures 和 wsrep_local_bf_aborts回滚,检测到的冲突数目2.2 集群同步验证在节点一上创建数据库 testmysql create database test;Query OK, 1 row affected (0.02 sec)节点二上查看mysql show databases;--------------------| Database |--------------------| information_schema || mysql || performance_schema || sys || test |--------------------5 rows in set (0.00 sec)在节点二上创建表mysql use test;Database changedmysql create table sys_user(id int ,name varchar(30));Query OK, 0 rows affected (0.11 sec)4)在节点三上查看表结构mysql use test;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql show tables;----------------| Tables_in_test |----------------| sys_user |----------------1 row in set (0.00 sec)在节点三上插入数据mysql insert into sys_user values(1,a);ERROR 1105 (HY000): Percona-XtraDB-Cluster prohibits use of DML command on a table (test.sys_user) without an explicit primary key with pxc_strict_mode ENFORCING or MASTER看到没有显示的主键就无法插入数据我们修改下表结构:alter table sys_user add primary key (id);插入数据mysql insert into sys_user values(1,a);Query OK, 1 row affected (0.05 sec)6)在节点一查看表数据mysql select * from sys_user;----------| id | name |----------| 1 | a |----------1 row in set (0.00 sec)可以看到三个节点数据正常同步并且都可读可写。2.3 新增数据库节点操作当数据库不够用时我们通常需要增加数据库节点来分担压力我们来演示一下新增节点的操作。创建数据卷docker volume create --name v42)新增容器docker run -di --namepn4 --netpxc-network -p 9003:3306 -v v4:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD123456 -e CLUSTER_NAMEcluster1 -e XTRABACKUP_PASSWORD123456 -e CLUSTER_JOINpn3 pxc:5.7要注意的是这次 CLUSTER_JOIN 连的是 pn3。进入节点4查看数据mysql show databases;--------------------| Database |--------------------| information_schema || mysql || performance_schema || sys || test |--------------------5 rows in set (0.00 sec)mysql use test;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql show tables;----------------| Tables_in_test |----------------| sys_user |----------------1 row in set (0.00 sec)mysql select * from sys_user;----------| id | name |----------| 1 | a |----------1 row in set (0.00 sec)可以看到之前的数据也自动同步过来了。2.4 宕机操作将节点pn4容器关闭造成宕机现象docker stop pn4在节点 pn2 上做查看集群状态mysql show status like wsrep%;......| wsrep_local_state | 4 || wsrep_local_state_comment | Synced || wsrep_cert_index_size | 3 |......| wsrep_incoming_addresses | 172.19.0.4:3306,172.19.0.3:3306,172.19.0.2:3306 |可以看到集群应该有4个节点但是现在只有3个正常连接。3)在节点 pn2 上做修改操作mysql update sys_user set nameb where id1;Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0将节点 pn4 容器启动[rootVM_0_15_centos ~]# docker start pn4进入容器 pn4 查看修改操作是否同步docker exec -it pn4 /usr/bin/mysql -uroot -p123456mysql use test;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql select * from sys_user;----------| id | name |----------| 1 | b |----------1 row in set (0.00 sec)可以看到节点正常加入集群并且数据也同步了。pn4 是以指定主节点形式进入 PXC 集群创建的容器那么 pn1直接以自身为主节点启动的容器会怎么样呢我们来演示一下关闭 pn1 节点docker stop pn1在 pn2 节点上插入一条数据mysql insert into sys_user values(2,c);Query OK, 1 row affected (0.01 sec)启动 pn1节点docker start pn1等待一分钟查看容器启动列表docker ps -a发现 pn1 节点并没有启动CONTAINER ID IMAGE ...... STATUS NAMESfa123563e787 pxc:5.7 ...... Exited (1) About a minute ago pn1查看下错误日志docker logs pn1异常信息如下2019-09-04T07:21:56.412918Z 0 [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 .2019-09-04T07:21:56.412922Z 0 [ERROR] WSREP: Provider/Node (gcomm://) failed to establish connection with cluster (reason: 7)2019-09-04T07:21:56.412929Z 0 [ERROR] Aborting翻译成中文2019-09-04T072156.412918Z 0 [错误] WSREP从此节点引导群集可能不安全。 它不是离开群集的最后一个可能不包含所有更新。 要使用此节点强制群集引导请手动编辑grastate.dat文件并将safe_to_bootstrap设置为1。2019-09-04T072156.412922Z 0 [错误] WSREP提供者/节点(gcomm//)无法与群集建立连接(原因7)2019-09-04T072156.412929Z 0 [错误]中止错误提示很明显了因为 pn1 节点不是最后一个离开集群的不能再以主节点的形式启动了,如果要以主节点的形式启动必须调整 grastate.dat文件中的 safe_to_bootstrap 参数为 1。但是要注意的是因为集群中其他节点并没有关闭这样启动的容器跟之前的集群就没有关系了数据也不会同步我们来验证下看看查看数据卷存放的路径docker volume inspect v1[{CreatedAt: 2019-09-05T09:22:2208:00,Driver: local,Labels: {},Mountpoint: /var/lib/docker/volumes/v1/_data,Name: v1,Options: {},Scope: local}]进入数据卷目录查看是否存在 grastate.dat文件[rootVM_0_15_centos ~]# cd /var/lib/docker/volumes/v1/_data[rootVM_0_15_centos _data]# lltotal 323444-rw-r----- 1 1001 1001 56 Sep 5 08:34 auto.cnf-rw------- 1 1001 1001 1680 Sep 5 08:34 ca-key.pem-rw-r--r-- 1 1001 1001 1120 Sep 5 08:34 ca.pem-rw-r--r-- 1 1001 1001 1120 Sep 5 08:34 client-cert.pem-rw------- 1 1001 1001 1676 Sep 5 08:34 client-key.pem-rw-r----- 1 1001 1001 2 Sep 5 08:34 fa123563e787.pid-rw-r----- 1 1001 1001 134219048 Sep 5 09:22 galera.cache-rw-r----- 1 1001 1001 113 Sep 5 09:21 grastate.dat-rw-r----- 1 1001 1001 1300 Sep 5 08:34 ib_buffer_pool-rw-r----- 1 1001 1001 79691776 Sep 5 09:15 ibdata1-rw-r----- 1 1001 1001 50331648 Sep 5 09:15 ib_logfile0-rw-r----- 1 1001 1001 50331648 Sep 5 08:34 ib_logfile1-rw-r----- 1 1001 1001 12582912 Sep 5 08:38 ibtmp1-rw-r----- 1 1001 1001 34751 Sep 5 08:38 innobackup.backup.logdrwxr-x--- 2 1001 1001 4096 Sep 5 08:34 mysqldrwxr-x--- 2 1001 1001 4096 Sep 5 08:34 performance_schema-rw------- 1 1001 1001 1676 Sep 5 08:34 private_key.pem-rw-r--r-- 1 1001 1001 452 Sep 5 08:34 public_key.pem-rw-r--r-- 1 1001 1001 1120 Sep 5 08:34 server-cert.pem-rw------- 1 1001 1001 1676 Sep 5 08:34 server-key.pemdrwxr-x--- 2 1001 1001 12288 Sep 5 08:34 sysdrwxr-x--- 2 1001 1001 4096 Sep 5 09:07 test-rw-r--r-- 1 1001 1001 143 Sep 5 09:22 version_info-rw-r----- 1 1001 1001 3932160 Sep 5 09:15 xb_doublewrite编辑文件vim grastate.dat将 safe_to_bootstrap 参数值修改为1保存退出# GALERA saved stateversion: 2.1uuid: 068dd5e8-cedd-11e9-904d-466e75bd8fe1seqno: 20safe_to_bootstrap: 1重启 pn1 容器docker start pn1进入容器查看数据docker exec -it pn1 /usr/bin/mysql -uroot -p123456mysql use test;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql select * from sys_user;----------| id | name |----------| 1 | b |----------1 row in set (0.01 sec)发现数据并没有同步那么要怎么将 pn1 节点加入到集群中呢我们可以直接将 pn1 容器删除以加入节点的形式重新创建容器并且因为我们之前已经将容器的数据挂载到数据卷了所以数据也不会存在丢失的风险我们来操作下删除 pn1容器docker stop pn1docker rm pn1以从节点方式加入集群docker run -di --namepn1 --netpxc-network -p 9000:3306 -v v1:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD123456 -e CLUSTER_NAMEcluster1 -e XTRABACKUP_PASSWORD123456 -e CLUSTER_JOINpn2 pxc:5.7等待容器初始化完毕3)进入容器查看数据是否同步docker exec -it pn1 /usr/bin/mysql -uroot -p123456mysql use test;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql select * from sys_user;----------| id | name |----------| 1 | b || 2 | c |----------2 rows in set (0.00 sec)发现数据已经同步了。