• PXC集群的概述及搭建


    目录

    PXC集群的概述及搭建

    PXC集群的简介

    Percona XtraDB Cluster(下文简称PXC集群)提供了MySQL高可用的一种实现方法。PXC集群以节点组成(推荐至少3节点,便于故障恢复,后面会讨论两节点的情况),每个节点都是基于常规的 MySQL/Percona Server,意味着你可以从集群中分离出某节点单独使用。集群中每个节点都包含完整的数据。

    PXC集群主要由两部分组成:

    Percona Server with XtraDB和Write Set Replication patches(使用了Galera library,一个通用的用于事务型应用的同步、多主复制插件)。

    PXC的特性和优点:

    ​ 1、同步复制
    ​ 2、支持多主复制
    ​ 3、支持并行复制
    ​ 4、作为高可用方案,相比其他方案其结构和实施相对简单明了

    PXC的局限和劣势:

    1) 版本(5.6.20)的复制只支持InnoDB引擎,其他存储引擎的更改不复制。然而,DDL(Data Definition Language) 语句在statement级别被复制,并且,对mysql.*表的更改会基于此被复制。例如CREATE USER...语句会被复制,但是 INSERT INTO mysql.user...语句则不会。(也可以通过wsrep_replicate_myisam参数开启myisam引擎的 复制,但这是一个实验性的参数)。
    2)由于PXC集群内部一致性控制的机制,事务有可能被终止,原因如下:集群允许在两个节点上通知执行操作同一行的两个事务,但是只有一个能执行成功,另一个 会被终止,同时集群会给被终止的客户端返回死锁错误(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)).

    3)写入效率取决于节点中最弱的一台,因为PXC集群采用的是强一致性原则,一个更改操作在所有节点都成功才算执行成功

    4)所有表都要有主键;

    5)不支持LOCK TABLE等显式锁操作;

    6)锁冲突、死锁问题相对更多;

    7)不支持XA;

    8)集群吞吐量/性能取决于短板;

    9)新加入节点采用SST时代价高;

    10)存在写扩大问题;

    11)如果并发事务量很大的话,建议采用InfiniBand网络,降低网络延迟;

    事实上,采用PXC的主要目的是解决数据的一致性问题,高可用是顺带实现的。因为PXC存在写扩大以及短板效应,并发效率会有较大损失,类似semi sync replication机制。

    PXC原理描述

    分布式系统的CAP理论:

    C:一致性,所有的节点数据一致

    A:可用性,一个或者多个节点失效,不影响服务请求

    P:分区容忍性,节点间的连接失效,仍然可以处理请求

    其实,任何一个分布式系统,需要满足这三个中的两个。

    PXC会使用大概是4个端口号

    3306:数据库对外服务的端口号

    4444:请求SST SST: 指数据一个镜象传输 xtrabackup , rsync ,mysqldump

    4567: 组成员之间进行沟通的一个端口号

    4568: 传输IST用的。相对于SST来说的一个增量。

    一些名词介绍:

    WS:write set 写数据集

    IST: Incremental State Transfer 增量同步

    SST:State Snapshot Transfer 全量同步

    PXC环境所涉及的端口:

    mysql实例端口

    10Regular MySQL port, default 3306.

    #pxc cluster相互通讯的端口

    2)Port for group communication, default 4567. It can be changed by the option:

    wsrep_provider_options ="gmcast.listen_addr=tcp://0.0.0.0:4010; "

    #用于SST传送的端口

    3)Port for State Transfer, default 4444. It can be changed by the option:

    wsrep_sst_receive_address=10.11.12.205:5555

    #用于IST传送的端口

    4)Port for Incremental State Transfer, default port for group communication + 1 (4568). It can be changed by the option:

    wsrep_provider_options = "ist.recv_addr=10.11.12.206:7777; "

    PXC的架构示意图

    数据读写示意图

    下面看传统复制流程

    异步复制

    半同步复制,超过10秒的阀值会退化为异步

    PXC原理图

    从上图可以看出:

    当client端执行dml操作时,将操作发给server,server的native进程处理请求,client端执行commit,server将复制写数据集发给group(cluster),cluster

    中每个动作对应一个GTID,其它server接收到并通过验证(合并数据)后,执行appyl_cb动作和commit_cb动作,若验证没通过,则会退出处理;当前server节点验证通

    过后,执行commit_cb,并返回,若没通过,执行rollback_cb。

    只要当前节点执行了commit_cb和其它节点验证通过后就可返回。

    3306:数据库对外服务的端口号

    4444:请求SST,在新节点加入时起作用

    4567:组成员之间沟通的端口

    4568:传输IST,节点下线,重启加入时起作用

    SST:全量同步

    IST:增量同步

    问题:如果主节点写入过大,apply_cb时间跟不上,怎么处理?

    Wsrep_slave_threads参数配置成cpu的个数相等或是1.5倍。

    用户发起Commit,在收到Ok之前,集群每次发起一个动作,都会有一个唯一的编号 ,也就是PXC独有的Global Trx Id。
    动作发起者是commit_cb,其它节点多了一个动作: apply_cb

    上面的这些动作,是通过那个端号交互的?
    4567,4568端口,IST只是在节点下线,重启加入那一个时间有用
    4444端口,只会在新节点加入进来时起作用

    PXC结构里面,如果主节点写入过大,apply_cb 时间会不会跟不上,那么wsrep_slave_threads参数 解决apply_cb跟不上问题 配置成和CPU的个数相等或是1.5倍
    当前节点commit_cb 后就可以返回了,推过去之后,验证通过就行了可以返回客户端了,cb也就是commit block 提交数据块.

    PXC启动和关闭过程

    State Snapshot Transfer(SST),每个节点都有一份独立的数据,当用mysql bootstrap-pxc启动第一个节点,在第一个节点上把帐号初始化,其它节点启动后加入进来。集群中有哪些节点是由wsrep_cluster_address = gcomm://xxxx,,xxxx,xxx参数决定。第一个节点把自己备份一下(snapshot)传给加入的新节点,第三个节点的死活是由前两个节点投票决定。

    状态机变化阶段:

    1)OPEN: 节点启动成功,尝试连接到集群,如果失败则根据配置退出或创建新的集群

    2)PRIMARY: 节点处于集群PC中,尝试从集群中选取donor进行数据同步

    3)JOINER: 节点处于等待接收/接收数据文件状态,数据传输完成后在本地加载数据

    4)JOINED: 节点完成数据同步工作,尝试保持和集群进度一致

    5)SYNCED:节点正常提供服务:数据的读写,集群数据的同步,新加入节点的sst请求

    6)DONOR(贡献数据者):节点处于为新节点准备或传输集群全量数据状态,对客户端不可用。

    状态机变化因素:

    1)新节点加入集群

    2)节点故障恢复

    3)节点同步失效

    传输SST有几种方法:

    1)mysqldump

    2)xtrabackup

    3)rsync

    比如有三个节点:node1、node2、node3

    当node3停机重启后,通过IST来同步增量数据,来完成保证与node1和node2的数据一致,IST的实现是由wsrep_provider_options="gcache.size=1G"参数决定,

    一般设置为1G大,参数大小是由什么决定的,根据停机时间,若停机一小时,需要确认1小时内产生多大的binlog来算出参数大小。

    假设这三个节点都关闭了,会发生什么呢?

    全部传SST,因为gcache数据没了

    全部关闭需要采用滚动关闭方式:

    1)关闭node1,修复完后,启动加回来;

    2)关闭node2,修复完后,启动加回来;

    3)......,直到最后一个节点

    4)原则要保持Group里最少一个成员活着

    数据库关闭之后,最会保存一个last Txid,所以启动时,先要启动最后一个关闭的节点,启动顺序和关闭顺序刚好相反。

    wsrep_recover=on参数在启动时加入,用于从log中分析gtid。

    怎样避免关闭和启动时数据丢失?

    1)所有的节点中最少有一个在线,进行滚动重启;

    2)利用主从的概念,把一个从节点转化成PXC里的节点

    PXC要注意的问题

    1)脑裂:任何命令执行出现unkown command ,表示出现脑裂,集群两节点间4567端口连不通,无法提供对外服务。

    SET GLOBAL wsrep_provider_options="pc.ignore_sb=true";

    2)并发写:三个节点的自增起始值为1、2、3,步长都为3,解决了insert问题,但update同时对一行操作就会有问题,出现:

    Error: 1213 SQLSTATE: 40001,所以更新和写入在一个节点上操作。

    3)DDL:引起全局锁,采用:pt-online-schema-change

    4)MyISAM引擎不能被复制,只支持innodb

    5)pxc结构里面必须有主键,如果没有主建,有可能会造成集中每个节点的Data page里的数据不一样

    6)不支持表级锁,不支持lock /unlock tables

    7)pxc里只能把slow log ,query log 放到File里

    8)不支持XA事务

    9)性能由集群中性能最差的节点决定

    特别说明

    在实际使用时,我们知道服务的部署时根据需要后来增加的,所以相信在需要用到PXC做高可用时,已经在服务器上安装了Mysql,并跑了业务。这时候我们会发现存在错误,大致如下

    大致意思时PID问题。其实percona自身就是mysql,你要原来的mysql干嘛,所以这时候应该杀死原来的Mysql,可能你又要问了那原来跑在Mysql的服务怎么办?备份还原就可以了。特此说明,以供道友参考,本人在此就出现了很大的困惑,最后才相通问题的解决方案,所以特别加冰了。

    在Centos部署基于Mysql高可用方案操作过程

    官方配置说明:

    https://www.percona.com/doc/percona-xtradb-cluster/5.5/howtos/centos_howto.html

    环境描述

    [root@db02 ~]# uname -r

    2.6.32-696.el6.x86_64

    [root@db02 ~]# uname -m

    x86_64

    [root@db02 ~]# cat /etc/redhat-release

    CentOS release 6.10 (Final)

    db02 10.0.0.52 percona1
    db05 10.0.0.55 percona2
    db08 10.0.0.58 percona3

    三个节点上的iptables最好关闭(否则就要开放3306、4444、4567、4568端口的访问)、关闭selinux

    三个节点都要执行以下操作

    yum -y groupinstall Base Compatibility libraries Debugging Tools Dial-up Networking suppport Hardware monitoring utilities Performance Tools Development tools

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

    yum install Percona-XtraDB-Cluster-55 -y

    注:可以选择源码或者yum,在此使用yum安装。

    数据库配置

    选择一个node作为名义上的master,下面就以db02为master,只需要修改mysql的配置文件--/etc/my.cnf

    [root@percona1 ~]# cat /etc/my.cnf

    [mysqld]

    datadir=/var/lib/mysql

    user=mysql

    Path to Galera library

    wsrep_provider=/usr/lib64/libgalera_smm.so

    Cluster connection URL contains the IPs of node#1, node#2 and node#3

    wsrep_cluster_address=gcomm://10.0.0.52,10.0.0.55,10.0.0.56

    In order for Galera to work correctly binlog format should be ROW

    binlog_format=ROW

    MyISAM storage engine has only experimental support

    default_storage_engine=InnoDB

    This changes how InnoDB autoincrement locks are managed and is a requirement for Galera

    innodb_autoinc_lock_mode=2

    Node #1 address

    wsrep_node_address=10.0.0.52

    SST method

    wsrep_sst_method=xtrabackup-v2

    Cluster name

    wsrep_cluster_name=my_centos_cluster

    Authentication for SST method

    wsrep_sst_auth="sstuser:s3cret"

    配置文件各项配置意义

    wsrep_provider:指定Galera库的路径

    wsrep_cluster_name:Galera集群的名称

    wsrep_cluster_address:Galera集群中各节点地址。地址使用组通信协议gcomm://(group communication)

    wsrep_node_name:本节点在Galera集群中的名称

    wsrep_node_address:本节点在Galera集群中的通信地址

    wsrep_sst_method:state_snapshot_transfer(SST)使用的传输方法,可用方法有mysqldump、rsync和xtrabackup,前两者在传输时都需要对Donor加全局只读锁(FLUSH TABLES WITH READ LOCK),xtrabackup则不需要(它使用percona自己提供的backup lock)。强烈建议采用xtrabackup

    wsrep_sst_auth:在SST传输时需要用到的认证凭据,格式为:"用户:密码"

    pxc_strict_mode:是否限制PXC启用正在试用阶段的功能,ENFORCING是默认值,表示不启用

    binlog_format:二进制日志的格式。Galera只支持row格式的二进制日志

    default_storage_engine:指定默认存储引擎。Galera的复制功能只支持InnoDB

    innodb_autoinc_lock_mode:只能设置为2,设置为0或1时会无法正确处理死锁问题

    启动数据库(三个节点都要操作):

    db02的启动方式:

    etc/init.d/mysql bootstrap-pxc

    .....................................................................

    如果是centos7,则启动命令如下:

    systemctl start mysql@bootstrap.service

    .....................................................................

    若是重启的话,就先kill,然后删除pid文件后再执行上面的启动命令。

    配置数据库(三个节点都要操作)

    mysql> show status like 'wsrep%';

    +----------------------------+--------------------------------------+

    | Variable_name | Value |

    +----------------------------+--------------------------------------+

    | wsrep_local_state_uuid | a7f5cbaf-a48b-11e8-b84f-a2501fa64600 |

    | wsrep_protocol_version | 4 |

    | wsrep_last_committed | 0 |

    | wsrep_replicated | 0 |

    | wsrep_replicated_bytes | 0 |

    | wsrep_received | 2 |

    | wsrep_received_bytes | 129 |

    | wsrep_local_commits | 0 |

    | wsrep_local_cert_failures | 0 |

    | wsrep_local_replays | 0 |

    | wsrep_local_send_queue | 0 |

    | wsrep_local_send_queue_avg | 0.000000 |

    | wsrep_local_recv_queue | 0 |

    | wsrep_local_recv_queue_avg | 0.000000 |

    | wsrep_flow_control_paused | 0.000000 |

    | wsrep_flow_control_sent | 0 |

    | wsrep_flow_control_recv | 0 |

    | 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_causal_reads | 0 |

    | wsrep_incoming_addresses | 10.0.0.52:3306 |

    | wsrep_cluster_conf_id | 1 |

    | wsrep_cluster_size | 1 |

    | wsrep_cluster_state_uuid | a7f5cbaf-a48b-11e8-b84f-a2501fa64600 |

    | 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 | 2.12(r318911d) |

    | wsrep_ready | ON |

    | wsrep_thread_count | 2 |

    +----------------------------+--------------------------------------+

    数据库用户名密码的设置

    mysql> UPDATE mysql.user SET password=PASSWORD("Passw0rd") where user='root';

    创建、授权、同步账号

    mysql> CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 's3cret';

    mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON . TO 'sstuser'@'localhost';

    mysql> FLUSH PRIVILEGES;

    ................注意下面几个察看命令...............

    mysql> SHOW VARIABLES LIKE 'wsrep_cluster_address';

    如果配置了指向集群地址,上面那个参数值,应该是你指定集群的IP地址

    此参数查看是否开启

    mysql> show status like 'wsrep_ready';

    查看集群的成员数

    mysql> show status like 'wsrep_cluster_size';

    这个查看wsrep的相关参数

    mysql> show status like 'wsrep%';

    4)那么db05和db08只需要配置my.cnf文件中的wsrep_node_address这个参数,将其修改为自己的ip地址即可。
    注:

    在此因为篇幅原因不在给出db05,db08的配置,如有需要请评论说出,本人会及时回复

    node2和node3的启动方式:

    [root@percona2 ~]# /etc/init.d/mysql start

    注意事项

    -> 除了名义上的master之外,其它的node节点只需要启动mysql即可。

    -> 节点的数据库的登陆和master节点的用户名密码一致,自动同步。所以其它的节点数据库用户名密码无须重新设置。

    也就是说,如上设置,只需要在名义上的master节点(如上的node1)上设置权限,其它的节点配置好/etc/my.cnf后,只需要启动mysql就行,权限会自动同步过来。

    如上的node2,node3节点,登陆mysql的权限是和node1一样的(即是用node1设置的权限登陆)

    如果上面的node2、node3启动mysql失败,比如/var/lib/mysql下的err日志报错如下:

    [ERROR]WSREP: gcs/src/gcs_group.cpp:long int gcs_group_handle_join_msg(gcs_

    解决办法:

    -> 查看节点上的iptables防火墙是否关闭;检查到名义上的master节点上的4567端口是否连通(telnet)

    -> selinux是否关闭

    -> 删除名义上的master节点上的grastate.dat后,重启名义上的master节点的数据库;当然当前节点上的grastate.dat也删除并重启数据库
    测试

    在任意一个node上,进行添加,删除,修改操作,都会同步到其他的服务器,是现在主主的模式,当然前提是表引擎必须是innodb,因为galera目前只支持innodb的表。

    mysql> show status like 'wsrep%';

    在db08上创建一个库

    create database zisefeizhu;

    然在在db02和db05上查看,会发现自动同步过来

    show databases;

    在db02上的zisefeizhu库下创建表,插入数据

    mysql> use zisefeizhu;

    Database changed

    mysql> create table test(

    -> id int(5));
    

    Query OK, 0 rows affected (0.11 sec)

    mysql> insert into test values(1);

    Query OK, 1 row affected (0.01 sec)

    mysql> insert into test values(2);

    Query OK, 1 row affected (0.02 sec)

    同样,在其它的节点上查看,也是能自动同步过来

    mysql> select * from zisefeizhu.test;

    新增节点加入Galera集群

    1.新节点加入Galera集群

    新节点加入集群时,需要从当前集群中选择一个Donor节点来同步数据,也就是所谓的state_snapshot_tranfer(SST)过程。SST同步数据的方式由选项wsrep_sst_method决定,一般选择的是xtrabackup。

    必须注意,新节点加入Galera时,会删除新节点上所有已有数据,再通过xtrabackup(假设使用的是该方式)从Donor处完整备份所有数据进行恢复。所以,如果数据量很大,新节点加入过程会很慢。而且,在一个新节点成为Synced状态之前,不要同时加入其它新节点,否则很容易将集群压垮。

    如果是这种情况,可以考虑使用wsrep_sst_method=rsync来做增量同步,既然是增量同步,最好保证新节点上已经有一部分数据基础,否则和全量同步没什么区别,且这样会对Donor节点加上全局read only锁。

    2.旧节点加入Galera集群

    如果旧节点加入Galera集群,说明这个节点在之前已经在Galera集群中呆过,有一部分数据基础,缺少的只是它离开集群时的数据。这时加入集群时,会采用IST(incremental snapshot transfer)传输机制,即使用增量传输。

    但注意,这部分增量传输的数据源是Donor上缓存在GCache文件中的,这个文件有大小限制,如果缺失的数据范围超过已缓存的内容,则自动转为SST传输。如果旧节点上的数据和Donor上的数据不匹配(例如这个节点离组后人为修改了一点数据),则自动转为SST传输。

    关于GCache以及Galera是如何判断数据状态的,本文不展开描述,可参见https://severalnines.com/blog/understanding-gcache-galera

  • 相关阅读:
    kubernetes排错系列:(一)、机房搬迁导致的节点NotReady
    kubernetes学习:CKA考试认证(二)
    kubernetes学习:CKA考试题
    kubernetes学习:CKA考试认证
    Pycharm中连接数据库乱码问题解决
    Matplotlib——中级
    Numpy
    Matplotlib——初级
    Matplotlib中中文不显示问题
    CentOS系统安装
  • 原文地址:https://www.cnblogs.com/peng-zone/p/11676678.html
Copyright © 2020-2023  润新知