转 移动云基于MySQL Galera的PXC运维实战

 ##sample 1 : mysql 监控php

1.phpadmin  比较简单,适合上手python

 

2.mysql_web python 写的,mysql

https://github.com/ycg/mysql_web/ios

mysql monitor web - MySQL实时监控

安装环境:

  1. 基于python2.7.11开发的
  2. 安装MySQL数据库
  3. 安装python第三方包
    #更新setuptools wget http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz tar -zxvf setuptools-0.6c11.tar.gz cd setuptools-0.6c11 python setup.py build python setup.py install #更新pip wget https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9 tar -zxvf pip-9.0.1.tar.gz cd pip-9.0.1 python setup.py build python setup.py install #安装python包 pip install flask flask-login gevent threadpool pymysql DBUtils six packaging appdirs mysql-replication sqlparse paramiko
  1. 在setting.py设置MySQL_Host相关帐户信息
MySQL_Host = host_info.HoseInfo(host="192.168.11.128", port=3306, user="yangcg", password="yangcaogui", remark="Monitor")
  1. 导入sql/table.sql的SQL脚本
  2. 添加MySQL数据库用户
insert into host_infos (host, port, user, password, remark) values ("192.168.11.129", 3306, "yangcg", "yangcaogui", "Master"), ("192.168.11.130", 3306, "yangcg", "yangcaogui", "Slave");
  1. 添加系统登陆帐号
insert into mysql_web.mysql_web_user_info (user_name, user_password)values("yangcaogui", md5("123456"));
  1. 启动mysql web系统
    #前台启动: python mysql_web.py runserver #后台启动 nohup python mysql_web.py runserver &
  1. 若是要监控慢查询还要进行几步配置

支持的功能:

  1. mysql tps qps table_cache handler监控
  2. 支持对innodb各类status进行监控
  3. 支持对show engine innodb status分析
  4. 支持对复制进行监控
  5. 支持对表空间进行分析
  6. 支持对os基本监控
  7. 支持收集慢查询监控
  8. 支持对thread进行完整分析
  9. 支持实时的图表显示
  10. 支持对数据库用户帐号的查询
  11. 支持登陆验证,未登陆不容许查看其它任何界面
  12. 支持半同步复制的实时监控

完成的脚本:

  1. binlog_bk.py - 实现使用mysqlbinlog对binlog日志进行备份
  2. binlog_sync.py - 实现对binlog进行分析,能够把数据同步到另外一个实例中
  3. binlog_util.py - 基于mysql-replication的binlog分析,可生成回滚SQL,实现误操做的闪回
  4. binlog_util_new.py - 实现对binlog文件的分析,可生成回滚SQL
  5. bk_xtrabackup.py - 实现对xtrabackup的备份封装,能够增量和全备
  6. bk_recovery_xtrbackup.py - 是基于bk_xtrabackup.py实现的备份恢复,能够远程和本地恢复
  7. collect_mysql_status_log.sh - 实现对mysql指定时间段的日志收集,有助于排除问题
  8. mysql_auto_install.py - 实现mysql的远程自动安装
  9. mysql_replication_repair.py - 实现对slave出现1032和1062错误的自动修复功能
  10. mysql_slow_log.sh - 基于pt工具的慢查询收集脚本,须要和mysql_web一块儿使用
  11. bk_xtrabackup_remote.py - 支持远程备份,比较强大

联系方式

  1. QQ: 779647966
  2. Email: ycg166911@163.com

 

 

###########git

 

https://mp.weixin.qq.com/s/YTwdVRh_Uhtf3bn2MO2H_Qgithub

做者介绍web

刘书浩,“移动云”DBA,负责“移动云”业务系统的数据库运维、标准化等工做;擅长MySQL技术领域,熟悉MySQL复制结构、Cluster架构及运维优化;具备自动化运维经验,负责“移动云”数据库管理平台的搭建。算法

 

前言sql

 

在众多的MySQL开源软件中,Galera是很是有特点的,它的特色及优点是具备良好的并发性和一致性。Galera Cluster的主要用途是为MySQL提供一致性的集群化解决方案,以一个dlopenable通用复制库的形式提供给MySQL,并经过自身的Write-Set提供复制服务,实现MySQL的多线程并行复制。此外,它自带集群节点管理机制,能够主动监测集群节点状态,自动管理有问题的数据节点,同时也能够实现集群的多点写入和平滑扩容。它对待事务的行为时,要么在全部节点上执行,要么都不执行,这种实现机制决定了它对待一致性的行为很是严格,可以很是完美地保证MySQL集群的数据一致性。shell

 

目前,对Galera Cluster的封装有两个,虽然名称不一样,但实质都是同样的,使用的都是Galere群集。一个是MySQL的创始人Monty在本身全新的MariaDB上实现的MariaDB Cluster,一个是著名的MySQL服务和工具提供商Percona实现的Percona Xtradb Cluster,简称为PXC。

 

从2016年开始,我参与了“移动云”的MySQL数据库运维管理工做。“移动云”是一个不断发展壮大的云服务供应商,订单和用户数据很是重要,随着“移动云”在网用户数量的不断增加,对数据库的高可用性和数据一致性提出了更高的要求。通过长期研究,不断地试错,终于在Galera的基础上,实现了一套本身的MySQL运维方案,截止到如今,已经有至关数量的线上集群运行着通过标准化改造的PXC,在这个过程当中,咱们也积累了不少Galera的技术经验,但愿这些经验也能帮助其余Galera使用者解决疑难或规避问题。

 

PXC

 

Percona XtraDB Cluster是一个彻底开源的MySQL的高可用性解决方案。它将Percona Server和Percona XtraBackup与Galera库集成,以实现同步多主复制。集群由节点组成,其中每一个节点包含同一组数据同步的跨节点。推荐的配置是至少有3个节点。每一个节点都是常规的MySQL服务器实例(例如Percona Server)。能够将现有的MySQL服务器实例转换为节点,并使用此节点做为基础来运行集群。还能够从集群中分离任何节点,并将其用做常规的MySQL服务器实例。

 

 

集群为多主的模式,三个节点之间彻底是对等的,均可以做为主节点,用户可使用结构化查询语言(SQL)对数据进行修改和查询。该系统采用share nothing的架构,每一个节点均可以提供读写服务。任何节点的修改都会自动同步到全部节点,当有客户端在某个节点写入数据时,集群会将新数据自动同步到其它节点,具备严格的数据一致性。

 

High Availability

 

集群节点间经过同步复制进行数据同步,经过心跳实现异常节点的检测和剔除。配合上层的负载均衡,能够实现集群的高可用,单个节点宕机不会影响服务。在具备3个节点的基本设置中,将任何节点关闭,Percona XtraDB Cluster仍能够继续工做。在任什么时候间点,能够关闭任何节点以执行维护或更改配置。即便在计划外状况(如节点崩溃或它网络变得不可用),群集会继续工做,可在工做节点上运行查询。

 

 

若是在节点关闭时对数据进行了更改,则节点在加入时可使用两个选项加入集群:

 

一、State Snapshot Transfer(SST)是将全部数据从一个节点复制到另外一个节点的过程。当新节点加入群集并从现有节点接收全部数据时,一般使用SST。Percona XtraDB群集中有三种SST方法:

 

  • mysqldump

  • rsync

  • xtrabackup

 

mysqldump和rsync的缺点是,你的集群在数据存在时变成READ-ONLY 复制(SST应用FLUSH TABLES WITH READ LOCK命令)。

 

SST使用XtraBackup不须要READ LOCK命令整个同步过程当中,只要同步.FRM文件(同样按期备份)。

 

二、Incremental State Transfer(IST)是指仅将增量更改从一个节点复制到另外一个节点。即便在群集没有锁定为只读状态,SST在正常操做服务时可能会侵入和干扰。IST能够避免这样。若是1个节点在很短的时间出现故障,它只能获取发生在它失效时发生的那些更改。IST是在节点上使用高速缓存机制来实现的。每一个节点包含一个缓存,环形缓冲区(大小可配置)最后N个更改,而且节点间可以传输该高速缓存的一部分。显然,只有当转移所需的变化量小于N时IST才能完成。若是它超过N则加入节点必须执行SST。

 

可使用如下命令监视节点的当前状态:

 

SHOW STATUS LIKE 'wsrep_local_state_comment';

 

当节点处于Synced(6)状态时,它是集群的一部分并准备处理流量。

 

Multi-Master Replication

 

多主复制意味着能够写入任何节点并确保写入对集群中全部节点都是一致的。这与常规MySQL复制不一样,在常规MySQL复制中,您必须将写入应用于master以确保它被同步。

 

PXC同步复制原理

 

  • 事务在本地节点执行时采起乐观策略,成功广播到全部节点后再作冲突检测;

  • 检测出冲突是,本地事务优先被回滚;

  • 每一个节点独立、异步执行队列中的write set;

  • 事务在本地节点执行成功返回客户端后,其余节点保证该事务必定会被执行,所以有可能存在延时,即虚拟同步。

 

PXC的复制架构图(摘自官方文档)

 

对于多主复制,任何写入都在全部节点上提交或根本不提交。全部查询都在节点上本地执行,而且仅在COMMIT上有特殊处理。当COMMIT查询发出时,事务必须经过全部节点上的认证。若是它没有经过,你会收到ERROR做为响应。经过以后,事务在本地节点上应用。COMMIT的响应时间包括如下内容:

 

  • 网络往返时间;

  • 认证时间;

  • 本地申请。

 

注意:在远程节点上应用事务不会影响COMMIT的响应时间。

 

这种架构有两个重要的后果:

 

  • 能够并行使用几个应用程序。这实现了真正的并行复制。使用 wsrep_slave_threads 变量配置的线程从机能够有多个并行。

  • slave可能有一个小的时间段不一样步。这是由于master能够申请事件比slave更快。若是你从slave读取,能够读取还没有更改的数据。但能够经过设置 wsrep_causal_reads = ON 变量来更改。在这种状况下,在slave上读取将等待,直到事件被应用(会明显增长读取的响应时间)。Slave和Master之间的差距是这种复制被称为虚拟同步的缘由,而不是真正的同步复制。

 

因此若是运行写事务到两个不一样的节点,集群将使用乐观锁。事务在个别查询期间不会检查可能的锁冲突,而是在COMMIT阶段,可能会收到ERROR响应。

 

Flow Control

 

前面了解了PXC是虚拟同步,事务在本地节点提交成功时,其余节点保证执行该事务。在提交事务时,本地节点把事务复制到全部节点,以后各个节点独立、异步地进行certification test、事务插入待执行队列、执行事务。

 

然而因为不一样节点以前执行事务的速度不同,长时间运行后,慢节点的待执行队列可能会越积越长,最终致使事务丢失。PXC继承了Galera的flow control机制,做用是协调各个节点,保证全部节点执行事务的速度大于队列增加的速度。实现原理是,集群中同时只有一个节点能够广播消息,每一个节点都会得到广播消息的机会,当慢节点的执行队列超过必定长度后,它会广播一个FC_PAUSE消息,其余节点收到消息后会暂缓广播消息,知道该慢节点的执行队列长度减小到必定程度后,集群数据同步又开始恢复。

 

部署架构案例

 

PXC部署架构分本地存储和网络存储两种状况。其中,采用本地存储的架构,其架构图以下图:

 

 

采用网络存储的架构,其架构图以下:

 

 

介绍完PXC的原理和架构,下面看一下具体的平常运维工做。

 

数据库巡检

 

数据库巡检的内容一般涵盖主机硬件、操做系统和MySQL巡检项。其中,主机/os巡检主要包括:主机的硬件配置、CPU/内存/磁盘使用率以及磁盘的I/O使用状况;MySQL巡检项包括:数据库配置、用户权限、大表数据量、业务表主键和自增加状况、数据库的并发性、当前和历史链接状况统计、备份执行状况以及日志记录和慢SQL的分析优化等。

 

 

一、查看MySQL服务器配置信息及运行情况

 

经过show variables来查看mysql服务器配置信息,例如show variables like '%slow%';用于查看慢查询,show variables like 'max_connections';;用于查看最大链接数。

 

经过ps -ef | grep mysql查看mysql进程运行情况。

 

二、经过show status统计各类SQL的执行频率

 

经过show status能够查看服务器状态信息。show status能够根据须要显示session 级别的统计结果和global级别的统计结果。

 

1)如下几个参数对Myisam和Innodb存储引擎都计数:

 

  • Com_select 执行select 操做的次数,一次查询只累加1;

  • Com_insert 执行insert 操做的次数,对于批量插入的insert 操做,只累加一次;

  • Com_update 执行update 操做的次数;

  • Com_delete 执行delete 操做的次数。

 

2)如下几个参数是针对Innodb存储引擎计数的,累加的算法也略有不一样:

 

  • Innodb_rows_read 执行select 查询返回的行数;

  • Innodb_rows_inserted 执行insert 操做插入的行数;

  • Innodb_rows_updated 执行update 操做更新的行数;

  • Innodb_rows_deleted 执行delete 操做删除的行数。

 

经过以上几个参数,能够很容易的了解当前数据库的应用是以插入更新为主仍是以查询操做为主,以及各类类型的SQL大体的执行比例是多少。对于更新操做的计数,是对执行次数的计数,不论提交仍是回滚都会累加。

 

对于事务型的应用,经过Com_commit和Com_rollback能够了解事务提交和回滚的状况,对于回滚操做很是频繁的数据库,可能意味着应用编写存在问题。

 

3)如下几个参数便于咱们了解数据库的基本状况:

 

  • Connections 试图链接Mysql 服务器的次数;

  • Uptime 服务器工做时间;

  • Slow_queries 慢查询的次数。

 

三、经过show status判断系统瓶颈

 

1)QPS(每秒Query量)

 

QPS = Questions(or Queries) / seconds

mysql > show global status like 'Question%';

 

2)TPS(每秒事务量)

 

TPS = (Com_commit + Com_rollback) / seconds

mysql > show global status like 'Com_commit';

mysql > show global status like 'Com_rollback';

 

3)key Buffer 命中率

 

mysql>show global status like 'key%';

key_buffer_read_hits = (1-key_reads / key_read_requests) * 100%

key_buffer_write_hits = (1-key_writes / key_write_requests) * 100%

 

4)InnoDB Buffer命中率

 

mysql> show status like 'innodb_buffer_pool_read%';

innodb_buffer_read_hits = (1 - innodb_buffer_pool_reads /   

innodb_buffer_pool_read_requests) * 100%

 

5)Query Cache命中率

 

mysql> show status like 'Qcache%';

Query_cache_hits = (Qcahce_hits / (Qcache_hits + Qcache_inserts )) * 100%;

 

6)Table Cache状态量

 

mysql> show global status like 'open%';

 

比较open_tables与opend_tables值。

 

7)Thread Cache 命中率

 

mysql> show global status like 'Thread%';

mysql> show global status like 'Connections';

Thread_cache_hits = (1 - Threads_created / connections ) * 100%

 

建立用来处理链接的线程数。若是 Threads_created 较大,你可能要增长 thread_cache_size 值。缓存访问率的计算方法 Threads_created/Connections。

 

8)锁定状态

 

mysql> show global status like '%lock%';

 

Table_locks_waited/Table_locks_immediate 若是这个比值比较大的话,说明表锁形成的阻塞比较严重。

 

Innodb_row_lock_waits:innodb行锁,太大多是间隙锁形成的。

 

Table_locks_waited:不能当即得到的表的锁的次数。若是该值较高而且有性能问题,应首先优化查询,而后拆分表或使用复制。

 

9)Tmp Table 情况(临时表情况)

 

mysql >show status like 'Created_tmp%';

 

Created_tmp_disk_tables/Created_tmp_tables比值最好不要超过10%,若是Created_tmp_tables值比较大,多是排序子句过多或者是链接子句不够优化。

 

10)Binlog Cache 使用情况

 

mysql > show status like 'Binlog_cache%';

 

若是Binlog_cache_disk_use值不为0 ,可能须要调大 binlog_cache_size大小。

 

11)Innodb_log_waits

 

mysql > show status like 'innodb_log_waits';

 

Innodb_log_waits值不等于0的话,代表 innodb log buffer 由于空间不足而等待。

 

12)链接数大小——max_connections

 

mysql> show variables like 'max_connections';

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

| Variable_name   | Value |

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

| max_connections | 500   |

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

        mysql> show global status like 'max_used_connections';

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

| Variable_name        | Value |

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

| Max_used_connections | 498   |

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

 

设置的最大链接数是500,而响应的链接数是498 。

 

max_used_connections / max_connections * 100% = 99.6% (理想值 ≈ 85%)

 

13)Handler_read_rnd

 

mysql> show status like 'Handler_read_rnd';

 

若是 Handler_read_rnd 太大 ,则你写的 SQL 语句里不少查询都是要扫描整个表,而没有发挥键的做用。

 

14)Key_reads

 

mysql> show status like 'key_read%';

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

| Variable_name     | Value  |

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

| Key_read_requests  | 1190  |

| Key_reads         | 2     |

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

 

若是 Key_reads 太大,则应该把 my.cnf 中 key_buffer_size 变大,能够用 Key_reads/Key_read_requests计算出 cache 失败率。

 

15)Handler_read_rnd

 

mysql> show status like 'Handler_read_rnd';

 

根据固定位置读一行的请求数。若是正执行大量查询并须要对结果进行排序该值较高。可能使用了大量须要MySQL 扫描整个表的查询或链接没有正确使用键。

 

16)Handler_read_rnd_next

 

mysql>show status like 'Handler_read_rnd_next';

 

在数据文件中读下一行的请求数。若是你正进行大量的表扫描,该值较高。一般说明你的表索引不正确或写入的查询没有利用索引。

 

17)Select_full_join

 

mysql>show status like 'Select_full_join';

 

没有使用索引的联接的数量。若是该值不为 0, 你应仔细检查表的索引。

 

18)Select_range_check

 

mysql>show status like 'Select_range_check';

 

在每一行数据后对键值进行检查的不带键值的联接的数量。若是不为 0 ,你应仔细检查表的索引。

 

19)Sort_merge_passes

 

mysql>show status like 'Sort_merge_passes';

 

排序算法已经执行的合并的数量。若是这个变量值较大,应考虑增长 sort_buffer_size 系统变量的值。

 

20)Handler_read_first

 

mysql>show status like 'Handler_read_first';

 

索引中第一条被读的次数。若是较高,它代表服务器正执行大量全索引扫描。例如, SELECT col1 FROM foo ,假定col1 有索引。

 

21)Handler_read_key

 

mysql>show status like 'Handler_read_key';

 

根据键读一行的请求数。若是较高,说明查询和表的索引正确。

 

22)Handler_read_next

 

mysql>show status like 'Handler_read_next';

 

按照键顺序读下一行的请求数。若是你用范围约束或若是执行索引扫描来查询索引列,该值增长。

 

23) Handler_read_prev

 

mysql>show status like 'Handler_read_prev';

 

按照键顺序读前一行的请求数。该读方法主要用于优化 ORDER BY ... DESC 。

 

24)Handler_read_rnd

 

mysql>show status like 'Handler_read_rnd';

 

根据固定位置读一行的请求数。若是你正执行大量查询并须要对结果进行排序该值较高。你可能使用了大量须要MySQL 扫描整个表的查询或你的链接没有正确使用键。

 

四、打开相应的监控信息

 

1)error log

 

在配置文件my.cnf中进行配置,在运行过程当中不能改变。

 

2)打开慢查询

 

set global slow_query_log='ON';

 

3)设置慢查询的时间阈值

 

set global long_query_time = 0.1;

 

4)未使用索引的sql语句打开

 

set global log_queries_not_using_indexes='ON

 

早期咱们经过执行自动化脚原本输出巡检报告,巡检报告内容须要人工去检查和确认,执行巡检脚本主要包括如下步骤:

 

  • 首先是,在本地下载python3.5并安装,打开后进入python解析器;

  • 经过pip方式安装python依赖包;

  • 由于脚本中须要获取graphid,要登陆zabbix管理网站去获取;

  • 而后登陆堡垒机,配置端口转发策略;

  • 登陆每一套数据库,建立数据库巡检帐号;

  • 最后在本地执行巡检脚本,并最终合成word巡检报告。

 

 

虽然比手工执行巡检,要简化不少,而且能够按资源池批量执行巡检,但总的来讲过程仍是略繁琐。目前咱们在作的是采用平台化的方式,取代传统的脚本和工具巡检。经过搭建数据库管理平台,实现巡检管理,其中一键巡检功能用于数据库的例行巡检。可选择多台数据库批量执行巡检。巡检结果能在web页面上查看。并针对每一个数据库实例会生成一份标准格式的巡检报告,报告能够从web页面直接下载。

 

另外,平台也提供了快速巡检的功能,用于对一些常规项巡检进行快速排查,常规巡检项主要是DBA根据以往故障处理的经验,总结下来的一些经常使用的排查项目,例如:processlist当前链接状况核查,而且能够保留快照,数据库阻塞的状况核查、流控的状况检查、锁争用的核查以及一些临时表和询缓存等状况的检查,下图中的例子是对当前链接状况的排查,能够看到什么用户正链接数据库在执行哪些操做。

 

另外,做为对常规巡检项的补充,也提供了自定义巡检项的功能。能够执行一些临时的查询语句,而且结合了语义审核和转译的功能,可以保证sql语句的正确使用,查询结果能够从web页面上导出。下图中的例子是临时对数据库帐号的进行查询,并导出结果。

 

复制引擎监控管理

 

一、打开复制引擎的调试信息-wsrep_debug

 

在运行过程当中,能够经过set global wsrep_debug = 'ON';来动态地打开wsrep的调试信息(调试信息会输入到错误日志中),能够帮助复制引擎定位问题。

 

二、Galera集群监控

 

1)监控集群的一致性

 

mysql>show status like 'wsrep_cluster_state_uuid';

 

经过检查变量wsrep_cluster_state_uuid的值,确认此节点是否属于正确的集群。该变量的值在集群的各个节点中必须相同,若是某个节点出现不一样的值,说明此节点没有链接到集群中。

 

mysql>show status like 'wsrep_cluster_conf_id';

 

经过检查变量wsrep_cluster_conf_id的值,用于查看集群发生变化的总数,同时确认此节点是否属于主集群。该变量的值在集群的各个节点中必须相同,若是某个节点出现不一样的值,说明此节点脱离集群了,须要检查网络链接等将其恢复到一致的状态。

 

mysql>show status like 'wsrep_cluster_size';

 

经过检查变量wsrep_cluster_size的值,查看集群节点的总数。

 

mysql> show status like 'wsrep_cluster_status';

 

经过检查变量wsrep_cluster_status的值,查看节点的状态是否为Primary,若不为Primary,表示集群部分节点不可用,甚至多是集群出现了脑裂。

 

若是全部节点的状态都不为Primary,就须要重置仲裁,若是不能重置仲裁,就须要手动重启。

 

第一步,关闭全部节点

 

第二步,重启各个节点,重启过程当中能够参考wsrep_last_committed的值肯定主节点。

 

注:手动重启的缺点是会形成缓存丢失,从而不能作IST。

 

2)监控节点状态

 

mysql> show status like 'wsrep_ready';

 

经过检查变量wsrep_ready的值,查看该节点的状态是否能够正常使用SQL语句。若是为ON,表示正常,若为OFF,需进一步检查wsrep_connected的值。

 

mysql> show status like 'wsrep_connected';

 

若是此变量的值为OFF,说明该节点尚未加入到任何一个集群组件中,这极可能是由于配置文件问题,例如wsrep_cluster_address或者wsrep_cluster_name值设置错误,也能够经过查看错误日志进一步定位缘由。

 

若是节点链接没有问题,但wsrep_ready的值还为OFF,检查wsrep_local_state_comment的值。

 

mysql> show status like 'wsrep_local_state_comment';

 

当节点的状态为Primary时,wsrep_local_state_comment的值通常为Joining, Waiting for SST, Joined, Synced或者Donor,若是wsrep_ready为OFF,而且wsrep_local_state_comment的值为Joining, Waiting for SST, Joined其中一个,说明此节点正在执行同步。

 

当节点的状态不为Primary时,wsrep_local_state_comment的值应该为Initialized。任何其余状态都是短暂的或临时的。

 

3)检测复制的健康状态

 

mysql> show status like 'wsrep_flow_control_paused';

 

经过检查变量wsrep_flow_control_paused的值,能够确认有多少slave延迟在拖慢整个集群的,从而查看复制的健康状态。这个值越接近0.0越好,优化的方法主要经过增长配置文件中wsrep_slave_threads的值,或者将复制很慢的节点剔除出集群。wsrep_slave_threads取值能够参考wsrep_cert_deps_distance,wsrep_cert_deps_distance表示并发事务处理数的均值,wsrep_slave_threads的值不该该比wsrep_cert_deps_distance高不少。

 

4)检测网络慢的问题

 

mysql> show status like 'wsrep_local_send_queue_avg';

 

经过检查变量wsrep_local_send_queue_avg的值,能够检测网络状态。若是此变量的值偏高,说明网络链接多是瓶颈。形成此状况的缘由可能出如今物理层或操做系统层的配置上。

 

5)集群监控通知扩展

 

经过wsrep_notify_cmd参数调用命令脚本的二次扩展。

 

wsrep状态监控

 

mysql> show status like '%wsrep%';

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

| Variable_name                | Value                                |

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

| wsrep_local_state_uuid         | e8149a5c-636a-11e5-8b4b-67b16bb666a4   |

| wsrep_protocol_version         | 7                                    |

| wsrep_last_committed          | 526498                               |

| wsrep_replicated              | 526498                               |

| wsrep_replicated_bytes         | 238196578                            |

| wsrep_repl_keys              | 1926403                              |

| wsrep_repl_keys_bytes         | 27520685                             |

| wsrep_repl_data_bytes         | 176980021                            |

| wsrep_repl_other_bytes        | 0                                    |

| wsrep_received               | 7970                                 |

| wsrep_received_bytes          | 64791                                |

| wsrep_local_commits          | 526357                               |

| wsrep_local_cert_failures       | 0                                    |

| wsrep_local_replays           | 0                                    |

| wsrep_local_send_queue       | 0                                    |

| wsrep_local_send_queue_max   | 2                                    |

| wsrep_local_send_queue_min   | 0                                    |

| wsrep_local_send_queue_avg   | 0.000041                             |

| wsrep_local_recv_queue       | 0                                    |

| wsrep_local_recv_queue_max   | 4                                    |

| wsrep_local_recv_queue_min   | 0                                    |

| wsrep_local_recv_queue_avg   | 0.034504                              |

| wsrep_local_cached_downto    | 1                                    |

| wsrep_flow_control_paused_ns  | 22690449177                          |

| wsrep_flow_control_paused     | 0.000005                             |

| wsrep_flow_control_sent       | 0                                    |

| wsrep_flow_control_recv       | 371                                  |

| wsrep_cert_deps_distance      | 74.734609                            |

| wsrep_apply_oooe            | 0.000000                             |

| wsrep_apply_oool             | 0.000000                             |

| wsrep_apply_window          | 1.000000                             |

| wsrep_commit_oooe           | 0.000000                             |

| wsrep_commit_oool           | 0.000000                             |

| wsrep_commit_window        | 1.000000                             |

| wsrep_local_state             | 4                                    |

| wsrep_local_state_comment    | Synced                               |

| wsrep_cert_index_size        | 43                                   |

| wsrep_cert_bucket_count      | 126282                               |

| wsrep_gcache_pool_size       | 261431296                            |

| wsrep_causal_reads           | 0                                    |

| wsrep_cert_interval           | 0.000002                          |

| wsrep_incoming_addresses     | 10.130.7.5:3306,,10.130.7.4:3306      |

| wsrep_evs_delayed           |                                  |

| wsrep_evs_evict_list          |                                  |

| wsrep_evs_repl_latency       | 0/0/0/0/0                           |

| wsrep_evs_state             | OPERATIONAL                    |

| wsrep_gcomm_uuid          | e813b31f-636a-11e5-90c7-0f6d378e1dfb |

| wsrep_cluster_conf_id        | 5                                  |

| wsrep_cluster_size           | 3                                  |

| wsrep_cluster_state_uuid      | e8149a5c-636a-11e5-8b4b-67b16bb666a4 |

| 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.11(rXXXX)                       |

| wsrep_ready                | ON                                |

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

58 rows in set (0.12 sec)

 

wsrep相关参数含义介绍:

 

wsrep_local_state_uuid:存储于该节点的UUID状态

wsrep_protocol_version:wsrep协议使用的版本

wsrep_last_committed:最后提交事务的序列号

wsrep_replicated:发送到其余节点的writesets总数

wsrep_replicated_bytes:发送到其余节点的writesets总字节数

wsrep_repl_keys:复制keys总数

wsrep_repl_keys_bytes:复制keys总字节数

wsrep_repl_data_bytes:复制数据的总字节数

wsrep_repl_other_bytes:其余复制的总字节数

wsrep_received:从其余节点接收的writesets总数

wsrep_received_bytes:从其余节点接收的writesets总字节数

wsrep_local_commits:该节点提交的writesets总数

wsrep_local_cert_failures:认证测试中失败的writesets总数

wsrep_local_replays:因非对称锁粒度回放的事务数

wsrep_local_send_queue:当前发送队列的长度,表示等待被发送的writesets数

wsrep_local_send_queue_avg:网络瓶颈的预兆。若是这个值比较高的话,可能存在网络瓶

wsrep_local_recv_queue:当前接收队列的长度,表示等待被使用的writesets数

wsrep_local_recv_queue_avg:表示slave事务队列的平均长度,slave瓶颈的预兆

wsrep_local_cached_downto:gcache的最小序列号,这个变量能够用来判断是用IST,仍是SST。若是此值为0,表示gcache中没有writesets

wsrep_flow_control_paused_ns:表示复制中止了多长时间,以纳秒为单位

wsrep_flow_control_paused:表示复制中止了多长时间。即代表集群由于Slave延迟而慢的程度,值为0~1,越靠近0越好,值为1表示复制彻底中止。可优化wsrep_slave_threads的值来改善

wsrep_flow_control_sent:表示该节点已经中止复制了多少次

wsrep_flow_control_recv:表示该节点已经中止复制了多少次

wsrep_cert_deps_distance:有多少事务能够并行应用处理。wsrep_slave_threads设置的值不该该高出该值太多

wsrep_apply_oooe:并发执行效率,writesets应用于out-of-order的频率

wsrep_apply_oool:大序列值的writeset比小序列值的writeset多出的执行频率

wsrep_apply_window:同时使用的最高序列值和最小序列值间的平均差值

wsrep_commit_oooe:事务脱离队列的频率

wsrep_commit_window:同时提交的最大序列值和最小序列值间的平均差值

wsrep_local_state:galera状态值

1 - Joining (requesting/receiving State Transfer) –表示此节点正在加入集群

2 - Donor/Desynced –表示正在加入的节点是donor

3 - Joined –表示节点已经加入集群r

4 - Synced –表示节点已经和集群同步

wsrep_local_state_comment:galera状态,若是wsrep_connected为On,但wsrep_ready为OFF,则能够从该项查看缘由

wsrep_cert_index_size:certification索引的entries数量

wsrep_cert_bucket_count:哈希表中certification索引的cells数

wsrep_gcache_pool_size:page pool或者为gcache动态分配的字节数

wsrep_causal_reads:writesets处理数

wsrep_incoming_addresses:以逗号分隔显示集群中的节点地址

wsrep_evs_repl_latency:提供集群节点间通讯复制延迟信息

wsrep_evs_delayed:被剔除出集群的UUID

wsrep_evs_evict_list:有延迟的节点列表

wsrep_evs_state:EVS协议状态

wsrep_gcomm_uuid:galera的view_id,不一样于集群的uuid,在gvwstate.dat能够查看到

wsrep_cluster_conf_id:集群成员发生变化的数目,正常状况下全部节点上该值是同样的。若是值不一样,说明该节点被临时"分区"了。当节点之间网络链接恢复的时候应该会恢复同样的值

wsrep_cluster_size:集群中的节点数目,若是这个值跟预期的节点数一致,则全部的集群节点已经链接

wsrep_cluster_state_uuid:集群的UUID值,在集群全部节点的值应该是相同的,有不一样值的节点,说明其没有链接入集群

wsrep_cluster_status:集群节点的状态。若是不为"Primary",说明出现"分区"或是"split-brain"情况,可能的取值为:Primary、Non-Primary、Disconnected

wsrep_connected:节点是否链接到集群,若是该值为Off,且wsrep_ready的值也为Off,则说明该节点没有链接到集群。(多是wsrep_cluster_address或wsrep_cluster_name等配置错形成的。具体错误须要查看错误日志)

wsrep_local_bf_aborts:被其余节点上的事务终止的正在执行的本地事务数

wsrep_local_index:集群节点索引

wsrep_provider_name:wsrep程序提供者

wsrep_provider_vendor:wsrep供应商

wsrep_provider_version:wsrep程序提供者的版本

wsrep_ready:节点是否能够提供查询。该值为ON,则说明能够接受SQL负载。若是为Off,则须要检查wsrep_connected

▲ 框内下拉可查看完整内容

 

PXC备份管理

 

对于咱们来讲,数据库的备份和恢复是很平常的工做。由于平时不免会遇到服务器宕机、磁盘损坏等状况,在这种状况下,要保证数据不丢失或者最小程度的丢失,平时进行有效的备份就显得很是重要了。

 

所以对于DBA来讲,备份工具的使用、备份策略的选择以及备份系统的完善都是须要特别关注的,另外,像备份文件校验一般是比较容易忽视的问题,出现故障时发现备份文件不可用,会形成很严重损失。

 

咱们平时经常使用的备份工具是mysqldump、Percona Xtrabackup,分别用于逻辑备份和物理备份,其实大多数DBA的备份/恢复体系都是围绕这两个工具展开的。

 

早期咱们经过在数据库本地,按期执行脚本的方式进行备份,策略是:每周日凌晨2点执行一次全量备份,周一到周六天天凌晨2点执行增量备份,在本地存储空间充足的状况下,要求至少要求保留1个月的备份数据,备份恢复测试是经过在备份恢复测试机上面执行‘测试脚本’,每周六分时段从各个数据库拉取备份文件到本机进行恢复测试,并经过日志记录恢复操做是否成功。

 

 

那当面对成百上千个MySQL实例的维护,以上备份恢复方式会有哪些问题呢?咱们具体来看一下。

 

一、首先是对本地存储空间需求较大,而且占用服务器系统总线,内存,CPU,磁盘IO资源,使得备份对线上业务有必定的影响。

 

在现网环境中,因为本地磁盘空间有限,一般本地仅保留一个月左右的备份数据,对于更早的数据如无特殊需求,到后期会自动删除,对于较重要的数据要保留更久要经过远程备份实现,不过在远程备份时,备份传输引起的网卡流量会对线上业务形成影响,须要考虑到网卡的能力。这时能够考虑使用双网卡,一块用于备份,一块用来提供线上服务。若是没有这个条件,要经过在备份时限速来达到目的。

 

二、其次是,集中化管理缺失,备份节点较多,备份方式多样化,备份完成状况、占用空间大小、完成时间以及校验结果等内容的记录和呈现也不够直观,缺乏图形化界面。突发故障或变动前的临时备份依然靠手工执行,存在效率低和安全性差的问题。

 

三、集群备份节点选择问题。备份或多或少对线上业务都有影响,建议备份任务在slave或只读节点上执行, 那么当集群发生主备切换,若是备份节点没有动态进行切换,致使在写库上进行备份,使线上业务受备份操做影响。

 

为了解决上述问题,咱们仍是采用平台化的方式,经过开发来实现集中化管理,包括:备份执行与恢复管理、历史备份查看以及备份策略修改和管理等功能。

 

另外想要提一下的是容灾,容灾是指在备份的基础上创建一个异地的数据系统,这个系统是本地关键应用数据的一个实时复制。

 

 

在灾难发生时,能够支持自动和手工灾备切换功能,保正业务的连续性。

 

PXC常见故障排查和处理方法

 

节点宕机

 

当集群中出现读写服务节点宕机的状况时,应该按以下所述步骤进行处理,以对外提供服务。

 

1)读写服务节点宕机

 

 

① 查看集群各节点状态:ps –ef | grep rdb

结果:读写节点(RW3)进程不存在,其余节点服务正常

 

② 查看error log日志,检查宕机缘由

 

③ 重启RW3

 

④ 启动完成后,确认RW3状态是否正常

 

2)某两个读写服务节点宕机

 

 

① 查看集群各节点状态:ps –ef | grep rdb

结果:读写节点(RW二、RW3)进程不存在,RW1节点服务正常

 

② 查看error log日志,检查宕机缘由

 

③ 此时,RW1读写服务节点正常工做,重启RW2和RW3

 

④ 启动完成后,确认RW2和RW3状态是否正常

 

3)读写服务节点都宕机

 

 

① 查看集群各节点状态:ps –ef | grep rdb

结果:读写节点(RW一、RW二、RW3)进程均不存在,此时集群没法提供正常服务

 

② 查看error log日志,发现最后宕机的是RW3

 

③ 关闭集群:kill -15 PID

 

④ 从新启动最后宕掉的读写服务节点RW3

 

⑤ RW3状态恢复正常后,根据实际负载状况判断是否继续启动RW2和RW1,预判若是可能作SST,因为作donor的节点没法提供服务,服务恢复时间比较长,能够先不起后面的节点,暂时只让RW3提供服务,闲时再启动其余节点,这种状况下要注意限制数据库的链接数。启动RW2节点

 

⑥ 待数据同步结束,RW2状态恢复正常后,启动RW1节点

 

⑦ 检查各个节点的状态,是否能正常提供服务

 

节点无响应

 

当集群中出现任一读写节点无响应时,应该按以下所述步骤进行处理,以对外提供服务。

 

1)负载高

 

主要查看如下几项:CPU使用率,内存使用率,操做系统IO,网络IO,网络链接数等。对应的命令和工具为:SystemTap,LatencyTOP,vmstat, sar, iostat, top, tcpdump等。经过观察这些指标,咱们就能够定位系统的性能问题。具体检查顺序可参看下述步骤:

 

① 先看CPU使用率,若是CPU使用率不高,但系统的Throughput和Latency上不去,这说明应用程序并无忙于计算,而是忙于别的一些事,好比IO。(另外,CPU的利用率还要看内核态的和用户态的,内核态的上去了,整个系统的性能就下来了。而对于多核CPU来讲,CPU 0 是至关关键的,若是CPU 0的负载高,那么会影响其它核的性能,由于CPU各核间是须要有调度的,这靠CPU0完成)。

 

② 查看一下IO大不大,IO和CPU通常是反着来的,CPU利用率高则IO不大,IO大则CPU利用率就低。关于IO,咱们要看三个事,一个是磁盘文件IO,一个是驱动程序的IO(如:网卡),一个是内存换页率。这三个事都会影响系统性能。

 

③ 查看一下网络带宽使用状况,在Linux下,你可使用iftop, iptraf, ntop, tcpdump这些命令来查看,或是用Wireshark来查看。

 

④若是CPU不高,IO不高,内存使用不高,网络带宽使用不高,可是系统的性能上不去。这说明你的程序有问题,好比,你的程序被阻塞了。多是由于等哪一个锁,多是由于等某个资源,或者是在切换上下文。

 

经过了解操做系统的性能,咱们才知道性能的问题,好比:带宽不够,内存不够,TCP缓冲区不够等等,不少时候,不须要调整程序的,只须要调整一下硬件或操做系统的配置就能够了。

 

注:OS经常使用查看命令

cpu –  vmstat、top、sar

内存–  ipcs、free

io –  iostat、sar

网络–  tcpdump、netstat –i、sar

 

预防措施:

 

  • 合理调整数据库的参数;

  • 应用上线前进行测试,优化后上线。防止应用大批量处理sql,insert、select等语句;

  • 监控系统资源负荷状况;

  • 限制报表并发查询数量,参照业务吞吐量。

 

处理方法:

 

① 排查执行时间较长的sql语句,步骤以下:

在各节点执行show full processlist;将执行时间较长的sql语句及执行该语句的线程ID(show full processlist显示结果中的列Id值)记录下来;

 

② 针对记录下来的sql语句,与应用相关人员确认是否可以终止;

 

说明:对于发现执行时间较长且仍在执行的select语句,为了下降风险,在必要状况下能够直接终止;对于涉及数据更新的语句,须要根据实际状况进行相关处理(好比记录下 SQL语句以便后续分析);

 

③ 终止执行时间较长且已获得终止确认的sql语句,kill QUERY ID或者KILL ID(执行sql语句的线程ID);

 

④ 确认集群是否正常响应。

 

2)链接满

 

当链接数满时,用户链接不上数据库,当前正在接受读写的节点达到最大链接值会没法链接数据库,按照如下方法处理:

 

根据历史统计信息修改max_connections。

 

方法一:

 

① 第max_connections+1链接只能由拥有super privileges用户登陆,当链接数满时,拥有super_priv的用户登录数据库修改max_ connections值:

 

set GLOBAL max_connections=XXXX;修改完成后实时生效,无需重启数据库。

 

② 进入配置文件my.cnf,设置max_connections值,该值与步骤一的值相同。

 

方法二:

 

进入配置文件my.cnf,设置max_connections值,并重启该节点服务。

 

3)有锁表状况

 

预防措施:

 

① 监控锁等待数量,暂设置10个报警;

② 避免业务忙时进行批量更新操做。

当出现有锁表状况而致使数据库响应慢的状况时,应该按以下所述步骤进行处理:

 

方法一:

 

① 获取锁表状况的相关信息,步骤以下:

 

  • (a) 以root用户登录到各主节点机器上;

  •  调用客户端链接工具;

  • 在各主节点的mysql提示符下执行use information_schema;

  • 在各主节点的mysql提示符下执行以下sql语句;

select a.trx_id ,a.trx_query , b.lock_data

from innodb_trx a ,innodb_locks bwhere a.trx_id = b.lock_trx_id;

 

② 针对锁信息查询语句的查询结果,与应用相关人员确认是否能够kill

 

③ 若是应用确承认以kill,则kill对应的sql

 

方法二:

 

调整innodb_lock_wait_timeout值。

 

集群分裂没法提供服务

 

当集群出现分裂的状况时,应该按以下所述步骤进行处理,以对外提供服务。

 

1)集群中有节点状态是Primary

 

① 使用如下命令查看集群状态,查找状态为non-Primary的节点

 

SHOW STATUS where Variable_name="wsrep_cluster_status";

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

| Variable_name        | Value   |

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

| wsrep_cluster_status |non- Primary |  

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

 

② 重启状态为non-Primary的节点

 

③ 检查各个节点的状态,是否能正常提供服务

 

2)集群中全部节点状态都不是Primary

 

① 使用如下命令查看集群状态,发现集群已经整个分裂,状态均为non-Primary

 

SHOW STATUS where Variable_name="wsrep_cluster_status";

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

| Variable_name        | Value      |

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

| wsrep_cluster_status   |non- Primary |     

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

 

② 从新执行选主。选主规则:以最后提交事务的数据库节点选为主,做为启动集群的主节点。同时,主节点对应的seqno也是最大的,能够经过如下命令查看

 

SHOW STATUS LIKE 'wsrep_last_committed';

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

|Variable_name       |Value  |

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

|wsrep_last_committed|409745|

 

③ 若是RW1是当前的主节点,则在RW1下执行下面的命令,从新引导RW1为primary:

 

set global wsrep_provider_options ="pc.bootstrap=1";Kill -15 pid关闭其余节点,关闭后能够经过grastate.dat里的uuid和seqno判断是否会作SST,kill -15关闭的通常不会有SST,只有IST,能够当即重启其余节点

 

④ 首先启动RW2节点

⑤ 待数据同步结束,RW2状态恢复正常后,启动RW3节点

⑥ 检查各个节点的状态,是否能正常提供服务

 

其余异常

 

1)集群因断电宕机

 

① ping 服务器端IP地址失败

 

② 联系网络管理员或系统管理员进行处理,重启服务器

 

③ 重启数据库

 

经过查看各节点的日志,假设最后关闭节点是RW1

从新启动最后关闭的读写服务节点RW1

待数据同步结束,RW1状态恢复正常后,启动RW2节点

待数据同步结束,RW2状态恢复正常后,启动RW3节点

检查各个节点的状态,是否能正常提供服务

 

2)网络交换机故障形成集群对外链接中断

 

① ping 服务器端IP地址失败

 

② 查看/var/log/messages

 

③ 联系网络管理员或系统管理员进行处理

 

3)网络交换机故障形成集群内部链接中断

 

① ping 服务器端IP地址成功

 

② ping 集群内部各节点IP失败

 

③ 查看/var/log/messages

 

④ 联系网络管理员或系统管理员进行处理

 

4)磁盘故障形成集群没法提供服务

 

① 使用smartctl检测磁盘健康状态

 

② 联系系统管理员更换磁盘

 

③ 重启数据库

 

案例1

 

去年9月8号,晚上11点左右,研发人员对数据库进行操做时,执行了1个事务,向用户注册表添加数据,这是一条insert语句,可是忘了提交,而后又执行了另外一条sql,去修改同一张表的表结构,前面没有提交的insert语句已对用户注册表添加了排他锁,致使后续大量sql语句等待执行,引起数据库阻塞,直到30min后第1个事务超时,数据库阻塞才解除。

 

 

咱们当时在11:08收到zabbix告警,显示数据库活跃线程数已达到139,通常活跃线程数超过32就会开始积压,这个跟CPU能处理的线程数有关,所以告警值设置为32。初步排查缘由为元数据索致使,11:07用户开了一个insert语句没有提交,致使元数据锁。

 

 

元数据锁产生的缘由,简单来讲就是修改表数据的同时,修改表结构。为了不这种状况,mysql innodb 在执行写入操做时会对表,添加排它锁,修改表结构,要等待锁释放后才能执行。此次故障处理,没有直接kill掉阻塞线程,由于按以往经验,这种方式能够解决阻塞,但也有必定几率会引发数据文件损坏,因此在阻塞事务即将超时的状况下,并无作任何操做,而是等待事务超时后,数据库自动恢复。

 

案例2

 

第二个例子是,去年11月1号,研发人员在数据库执行查询操做,由于使用排序产生临时表,又由于instance表,跟关联查询语句中的任何表都没有关联关系,致使笛卡尔积,生成的临时表文件过大最终将/目录占满,从而引起故障。

 

 

案例3

 

 

第三个案例是因为网络设备故障引发的,存储网卡闪断致使数据库宕机,在去年6月1日上午10:46,数据库进程故障,有12台数据库同时宕机,一线接到客户投诉‘华北节点控制台没法打开’,当时看了一下,因为mysqld进程属于非正常关闭,启动以前要登陆集群3个节点,查看启动位置sequence number,找出具备最完整数据的节点,做为集群第一个节点优先启动,而后再启动另外两个节点同步数据。

 

 

可是,在尝试执行mysqld_safe命令查看启动位置的时候失败了,继续排查,最后找到故障缘由:数据库主机挂载块存储的目录变成只读状态,从新挂载后命令能够正常执行,而后将数据库陆续启动。

 

此次故障缘由,在后面回溯的时候发现是由于数据库主机存储网卡与上层网络设备互联信息过程当中发生了闪断,致使存储目录变为只读状态,最后引起故障

相关文章
相关标签/搜索