专职DBA-MySQL集群高可用方案-PXC

专职DBA-MySQL集群高可用方案-PXC

1.Percona Xtradb Cluster 介绍
Percona XtraDB Cluster 简称:PXC,是针对MySQL用户的高可用性和扩展性解决方案,基于Percona Server。
其包括了Write Set REPlication补丁,使用Galera库,这是一个针对事务性应用程序的同步多主机复制插件。
Percona XtraDB Cluster 特点:
    同步复制(真正的同步),事务可以在所有节点上提交(多点写入)。
    多主机复制,你可以写到任何节点。每个节点是一个完整的copy。
    任何query可以在本地完成。
    Percona XtraDB Cluster 完全兼容MySQL或Percona Server,包括:
        数据兼容。Percona XtraDB Cluster 可在由MySQL或Percona Server创建的数据库上使用。
        应用程序兼容。如果要使用Percona XtraDB Cluster,你的应用程序基本不需要作任何更改。


2.PXC和Replication的区别
    Let’s take look into the well known CAP theorem for Distributed systems. Characteristics of Distributed systems:
    C - Consistency (all your data is consistent on all nodes),
    A - Availability (your system is AVAILABLE to handle requests in case of failure of one or several nodes ),
    P - Partitioning tolerance (in case of inter-node connection failure, each node is still available to handle requests).
    CAP theorem says that each Distributed system can have only two out of these three.
    MySQL replication has: Availability and Partitioning tolerance.(这个p 是指从库上可以不完全同步)
    Percona XtraDB Cluster has: Consistency and Availability.
基于以上可以看出来Replication 并不能真正保证数据一致性,但PXC
提供了强的数据一致性,但牺牲的分区特性。


3.PXC安装环境需求
------------------------------------------
节点        bond0            bond1
------------------------------------------
db01        10.0.0.11        192.168.10.11
------------------------------------------
db02        10.0.0.12        192.168.10.12
------------------------------------------
db03        10.0.0.13        192.168.10.13
------------------------------------------

4.基本架构图:

专职DBA-MySQL集群高可用方案-PXC

5.PXC安装基本步骤:
下载PXC二进制安装包ssl101是Red Hat Enterprise Linux的:
# wget https://www.percona.com/downloads/Percona-XtraDB-Cluster-LATEST/Percona-XtraDB-Cluster-5.7.25-31.35/binary/tarball/Percona-XtraDB-Cluster-5.7.25-rel28-31.35.1.Linux.x86_64.ssl101.tar.gz
# wget https://www.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.14/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.14-1.el7.x86_64.rpm

[root@db01 ~]# ls -lh
total 223M
-rw-r--r-- 1 root root 7.6M Apr 30 13:01 percona-xtrabackup-24-2.4.14-1.el7.x86_64.rpm
-rw-r--r-- 1 root root 216M Jul 27 00:34 Percona-XtraDB-Cluster-5.7.25-rel28-31.35.1.Linux.x86_64.ssl101.tar.gz

安装依赖包:
[root@db01 ~]# yum -y install perl perl-devel perl-IO-Socket-SSL perl-Digest perl-Digest-MD5 perl-DBD-MySQL perl-Time-HiRes libaio libaio-devel libev socat

安装Percona-Xtrabackup
[root@db01 ~]# yum -y localinstall percona-xtrabackup-24-2.4.14-1.el7.x86_64.rpm


PXC-MySQL数据库安装
参考(专职DBA-品悟MySQL专业环境安装)
安装之后先不要初始化数据库
my.cnf配置文件参考(PXC大多是独占服务器,配置文件可以放在/etc/my.cnf)
周老师还是喜欢把配置文件放在老地方/data/mysql/3306/my.cnf
[root@db01 ~]# cat /etc/my.cnf
[mysqld]
# for mysql global
user                     = mysql
basedir                  = /usr/local/mysql
datadir                  = /data/mysql/3306/data
tmpdir                   = /data/mysql/3306/tmp
pid_file                 = /data/mysql/3306/3306.pid
socket                   = /data/mysql/3306/mysql.sock
port                     = 3306
server_id                = 113306  #每个节点的server_id不能一样
character-set-server     = utf8

# for binlog
binlog_format            = row  #日志格式必须为ROW
log_bin                  = /data/mysql/3306/logs/mysql-bin

# for error log
log_error                = /data/mysql/3306/error.log

# general log
general_log              = off
general_log_file         = /data/mysql/3306/general.log

# for slow query log
slow_query_log           = on
slow_query_log_file      = /data/mysql/3306/slow.log
long_query_time          = 1.000000

# for gtid
gtid_mode                = on
enforce_gtid_consistency = on

# for replication
# for innodb

# percona xtradb cluster
default_storage_engine         = InnoDB
innodb_locks_unsafe_for_binlog = 1
innodb_autoinc_lock_mode       = 2
wsrep_cluster_name             = pxc_mysql  #cluster的名字
wsrep_cluster_address          = gcomm://10.0.0.11,10.0.0.12,10.0.0.13  #cluster中的节点ip
wsrep_node_address             = 10.0.0.11  #cluster当前节点的ip,每个节点当前节点ip不能一样
wsrep_provider                 = /usr/local/mysql/lib/libgalera_smm.so
wsrep_sst_method               = xtrabackup-v2
wsrep_sst_auth                 = sst:123

[mysql]
#character-set-client    = utf8
#prompt                  ="\\u@\\h [\\d]> \"
#prompt                  ="mysql [\\d]> \"
#prompt                  ="Master [\\d]> \"
#prompt                  ="Slave [\\d]> \"


第一个节点初始化
[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf --initialize-insecure

启动
[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf --wsrep-new-cluster &
[1] 27427
说明,使用--wsrep-new-cluster启动,让他忽略参数:wsrep_cluster_address
让他知道他是集群中的第一个节点,在启动中不用去找其它节点。

[root@db01 ~]# ss -tunlp | grep mysql
tcp    LISTEN     0      128       *:4567                  *:*                   users:(("mysqld",pid=27427,fd=11))
tcp    LISTEN     0      80       :::3306                 :::*                   users:(("mysqld",pid=27427,fd=33))

设置密码
[root@db01 ~]# mysqladmin -S /data/mysql/3306/mysql.sock -p password 123

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p
Enter password:

创建一个可以做SST的账号:
mysql> create user 'sst'@'localhost' identified by '123';
Query OK, 0 rows affected (0.01 sec)

mysql> grant reload,lock tables,process,replication client on *.* to 'sst'@'localhost';
Query OK, 0 rows affected (0.01 sec)


其他节点启动,这里我直接克隆虚拟机了
克隆好的虚拟机,需要修改:ip地址、主机名、删除auto.cnf
在配置文件需要修改两处:
[mysqld]
server_id          = xx3306
wsrep_node_address = 本机IP

关机克隆db02和db03
[root@db01 ~]# mysqladmin -S /data/mysql/3306/mysql.sock -p shutdown
Enter password:





启动第一个节点
[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf --wsrep-new-cluster &
[1] 6733
[root@db01 ~]# netstat -tunlp|grep mysql
tcp        0      0 0.0.0.0:4567            0.0.0.0:*               LISTEN      6733/mysqld
tcp6       0      0 :::3306                 :::*                    LISTEN      6733/mysqld


其他节点可以不用初始化,直接启动
[root@db02 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &
[1] 6713
[root@db03 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &
[1] 6731


启动完毕确认
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p
Enter password:

mysql> show global status like "%wsrep%";
+----------------------------------+----------------------------------------------+
| Variable_name                    | Value                                        |
+----------------------------------+----------------------------------------------+
| wsrep_local_state_uuid           | c3321380-b08b-11e9-bf9f-c7528f35ede2         |
| wsrep_protocol_version           | 9                                            |
| wsrep_last_applied               | 3                                            |
| wsrep_last_committed             | 3                                            |
| 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                   | 4                                            |
| wsrep_received_bytes             | 590                                          |
| 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.250000                                     |
| 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           | 1320                                         |
| 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         | 10.0.0.12:3306,10.0.0.13:3306,10.0.0.11: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                 | e4bf0102-b092-11e9-b61c-22610d7dfea6         |
| wsrep_cluster_conf_id            | 3                                            |
| wsrep_cluster_size               | 3                                            |
| wsrep_cluster_state_uuid         | c3321380-b08b-11e9-bf9f-c7528f35ede2         |
| wsrep_cluster_status             | Primary                                      |
| wsrep_connected                  | ON                                           |
| wsrep_local_bf_aborts            | 0                                            |
| wsrep_local_index                | 2                                            |
| wsrep_provider_name              | Galera                                       |
| wsrep_provider_vendor            | Codership Oy <info@codership.com>            |
| wsrep_provider_version           | 3.35(r)                                      |
| wsrep_ready                      | ON                                           |
+----------------------------------+----------------------------------------------+
71 rows in set (0.00 sec)

确认这四个参数值:
wsrep_local_state         | 4
wsrep_local_state_comment | Synced
wsrep_cluster_status      | Primary
wsrep_connected           | ON


6.PXC基本管理
(1).PXC关闭
# mysqladmin -S /data/mysql/3306/mysql.sock -p shutdown
# /etc/init.d/mysqld stop


(2).PXC启动
第一个启动的节点(如果集群节点全部关闭,第一个节点启动需要加参数--wsrep-new-cluster)
# mysqld --defaults-file=/data/mysql/3306/my.cnf --wsrep-new-cluster &
# /etc/init.d/mysqld bootstrap-pxc
    其他节点启动
    # mysqld --defaults-file=/data/mysql/3306/my.cnf &
    # /etc/init.d/mysqld start

集群节点不是都关闭启动方式如下
# mysqld --defaults-file=/data/mysql/3306/my.cnf &
# /etc/init.d/mysqld start


(3).新加入节点db04
[root@db04 ~]# grep "address" /data/mysql/3306/my.cnf
wsrep_cluster_address          = gcomm://10.0.0.11,10.0.0.12,10.0.0.13,10.0.0.14
wsrep_node_address             = 10.0.0.14


(4).思考
binlog_format配置成mixed,不支持,需要配置成row格式。
任何节点写入数据看能不能同步?
PXC架构中三个节点的binlog内容是不是一样?(观察三个节点binlog的内容变化)
PXC集群如果挂一个从库做备份,集群中哪个节点可以担任主库?


(5).报错处理
加载so文件加不到:
Installing MySQL system tables...
/usr/local/mysql/bin/mysqld: error while loading shared libraries:
libssl.so.6: cannot open shared object file: No such file or directory

可能的问题:
openssl没装:yum -y install openssl openssl-devel

如果提示已经安装,可以使用
# updatedb
# locate libssl.so  看看能不能找到
然后用ldd 查看还有那些依赖需安装
[root@db01 ~]# ldd /usr/local/mysql/bin/mysqld
        linux-vdso.so.1 =>  (0x00007ffc4d38e000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd287068000)
        libaio.so.1 => /lib64/libaio.so.1 (0x00007fd286e66000)
        libnuma.so.1 => /lib64/libnuma.so.1 (0x00007fd286c5a000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fd286a23000)
        libssl.so.10 => /lib64/libssl.so.10 (0x00007fd2867b1000)
        libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007fd286350000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fd28614c000)
        libz.so.1 => /lib64/libz.so.1 (0x00007fd285f36000)
        librt.so.1 => /lib64/librt.so.1 (0x00007fd285d2e000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fd285a27000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fd285725000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fd28550f000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fd285142000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd287284000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007fd284f3f000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fd284cf2000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fd284a09000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fd284805000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fd2845ea000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fd2843db000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fd2841d7000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fd283fbe000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fd283d97000)
        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fd283b35000)




安装中socat找不到
socat包没装上,可以把epel的源加入就可以安装。

启动报错,找不到my_print_defaults的。
可以更改/etc/my.cnf 在[mysqld]中添加
basedir=/usr/local/mysql/
如果还不行,可以通过在/etc/init.d/mysqld中找到basedir定义为:
basedir=/usr/local/mysql/


kill mysqld或是异常后PXC第一个节点起不来。
[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.
处理办法:
编辑datadir下:grastate.dat
[root@db01 ~]# cat /data/mysql/3306/data/grastate.dat
# GALERA saved state
version: 2.1
uuid:    c3321380-b08b-11e9-bf9f-c7528f35ede2
seqno:   -1
safe_to_bootstrap: 1  #把0改成1即可。


(6).参考
官方文档:http://www.percona.com/doc/percona-xtradb-cluster/5.7/


(7).测试PXC复制
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p
Enter password:

db01 [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

db01 [(none)]> create database app01;
Query OK, 1 row affected (0.04 sec)

db01 [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| app01              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

db01 [(none)]> use app01;
Database changed

db01 [app01]> create table t1(id int);
Query OK, 0 rows affected (0.05 sec)

db01 [app01]> show tables;
+-----------------+
| Tables_in_app01 |
+-----------------+
| t1              |
+-----------------+
1 row in set (0.00 sec)

[root@db02 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show tables from app01;"
Enter password: 
+-----------------+
| Tables_in_app01 |
+-----------------+
| t1              |
+-----------------+

[root@db03 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show tables from app01;"
Enter password: 
+-----------------+
| Tables_in_app01 |
+-----------------+
| t1              |
+-----------------+
#===============================================================================================================================================================================
更新丢失问题:
建议PXC还是单节点写入,避免更新丢失。
PXC也是存在节点延迟的。
PXC稳定的一逼,太牛逼太稳定了。
它的替代品就是MGR,MGR现在很火。
目前PXC比MGR稳定,MGR性能比PXC高。


PXC整体架构优点:
并行同步复制(一致性强)
多点写入
高性能(乐观锁控制)


PXC的复制不是基于binlog的复制,而是基于innodb引擎层来复制。
在PXC里面不能有长事务。


PXC的重要概念:
PXC数据复制流程
PXC启动流程new cluster|IST|SST
PXC数据冲突
PXC流控制
PXC脑裂


数据库启动
--wsrep-new-cluster
  当前是集群中的第一成员,不需要和其他成员协同。
SST(State Snapshot Transfer)
  mysqldump
  rsync
  Xtrabackup(多的比较多的是这个,推荐XBK)
IST
  pxc(xtrabackup)


三个节点不要全关掉
依次关掉,关一个,加入一个,再关另一个节点。


show global status like "%wsrep%";


集群节点数 3<= cluster size <=8
状态切换
传输
  SST:State Snapshot Transfer
  IST
脑裂

wsrep_local_state = 4
wsrep_local_state_comment = Synced
这两个表示可以对外提供服务

数据冲突
  数据可能会在提交步骤失败。
  原因:乐观锁控制,能不能执行,依赖于本地的数据判断,最终能不能提交需要集群中成员投票确认。


PXC流控制
  pxc性能由集群中最慢的节点决定(针对写性能)
  在pxc集群中,当某个节点不能跟上其他节点的写入能力时,这个节点会请求其他节点等待后面的写入,等它追上去。
  参数项(wsrep_provider_options)
    gcs.fc_limit(wsrep_local_recv_queue)
    gcs.fc_master_slave(no|yes)
    gcs.fc_factor
  动态项
    wsrep_flow_control_interval = (N,M)& wsrep_local_recv_queue

脑裂
  unkown command
  出现的原因:集群中只有两个成员时,两个节点忽然失去联系,自己也搞不清楚当前的集群状态。

PXC一致性读
  wsrep_dirty_reads 默认是off
    是否允许节点在和集群失去连接时允许有select操作

  wsrep_sync_wait 默认是0


PXC中运维注意事项
节点是不是工作OK
 show global status;
   wsrep_cluster_status=Primary
   wsrep_connected=on
   wsrep_ready=on
   wsrep_local_state=4


DDL操作
  没表级锁
  alter table 操作,会把整个集群全锁住,kill不掉的。
  解决办法:
      等待完成
      快速重启
  使用pt-online-schema-change操作


PXC复制延迟
  引发flow control
      wsrep_flow_control_sent
      wsrep_flow_control_recv
      wsrep_local_recv_queue
  调整
      wsrep_slave_threads
      wsrep_max_ws_size & wsrep_max_ws_rows

PXC一致性读
  wsrep_dirty_reads 默认是off
    是否允许节点在和集群失去连接时允许有select操作
  wsrep_sync_wait 默认是0

PXC集群重启
  建议滚动重启节点,不要一下全部停下来
      集群节点离线时间
          gcache.size(建议1-4G,要以考虑是一个小时形成的binlog量)
          gcache.dat
      mysqld --wsrep-recover
      如果机器掉电了,你是启不来的,你需要
          cat grastate.dat里面把safe_to_bootstrap:0,把0改成1

PXC监控要点
  报警级别
    节点是否正常
      show global status;
        wsrep_cluster_status=Primary
        wsrep_connected=on
        wsrep_ready=on
    wsrep_local_cert_failures & wsrep_local_bf_aborts 增长
    wsrep_flow_control_sent & wsrep_local_flow_control_recv
    wsrep_local_recv_queue > 0

存在性能问题
wsrep_local_recv_queue > 0 & wsrep_local_send_queue > 0
节点发送接收的事务量:wsrep_replicated & wsrep_received
节点发送接收的数据量:wsrep_replicated_bytes & wsrep_received_bytes
事务冲突次数:wsrep_local_failures & wsrep_local_bf_aborts


进阶技能
把一个利用主从复制,把从节点加入到pxc集群中

利用复制,把从节点加入pxc集群,减少SST传输
把pxc中一个节点转成一个复制节点
把现有复制结构迁移到pxc环境
集群之间复制

利用复制加入pxc
1.利用备份工具建一个从库
  mysqldump
  innobackupex
2.启动mysqld不加载Galera,追上主库
3.获取slave最后一个relay log或是binary log,推荐是最后一个relay log
4.利用mysqlbinlog获取最后一个事件的Xid
  mysqlbinlog -j realy-log-pos relay-bin.000003 | grep Xid
5.关闭mysqld,生产grastate.dat,从主节点copy过一个改一下seqno为当前的Xid就行。

PXC限制
  只支持innodb引擎
  没有表级锁(lock tables,unlock tables)
  最大事务操作限制
  乐观锁控制,事务尽量快速提交
  不支持XA事务
  集群最少节点数:3
  binlog_rows_query_log_events功能不支持
  每个表必须有主键
  不支持innodb表空间传出

 

上一篇:使用docker快速部署mysql pxc集群


下一篇:python 安装依赖的常用方法整理——pip方法、whl安装方法、源码包安装方法、easy_install安装