作者引见
吕尚
一、前言 PXC 全称 Percona XtraDB Cluster 是 Percona 公司针对 MySQL 提出的高可用性和可扩展性处置计划。 它具有很多优点:同步复制,数据强分歧;多主复制,能够在恣意节点中止写操作;节点自动配置等。 但同时,运用中也有着一些限制,需求业务及运维人员了解、关注。 本文引见了在PXC集群日常运用中呈现的一次毛病,希望能够给大家带来启示。 二、毛病现象 在同一组效劳器上的集群A(3307端口)和集群B(3308端口)写节点衔接数在同一时间段暴增,SQL running 线程堆积, 对业务产生了一定影响。
MySQL thread监控图 三、剖析过程 最初的着眼点是业务新发布和两个集群交叉的业务变更。经排查,毛病开端前并没有新发布,也没有跑任何程序任务,因而承认了这种可能性。
集群结构简图 两个集群都属于PXC架构,共用一组效劳器。在查看第三个节点db3的监控状况时(这台是作为两个集群共同的读节点),发现了端倪: db3 节点的 wsrep_flow_control_sent 指标上升,阐明发送了流控(FC)音讯。
Galera流控监控图 PXC数据同步流程 在引见流控之前,我们需求先搞清一个问题:PXC是如何做数据同步的?
流控原理 Flow control allows any node in the cluster to instruct the group when it needs replication to pause and when it is ready for replication to continue. This prevents any node in the synchronous replication group from getting too far behind the others in applying replication. 节点接纳写集并把它们依照全局次第组织起来,并将接纳到的未应用和提交的事务保存在接纳队列中。 假如当前节点无法及时处置队列中的写集,会招致队列越来越长;当这个接纳队列长度抵达我们配置的阈值,将触发流控。 触发流控时,写节点调用 galera_pre_commit 接口广播时(上述第 4 步)会中止阻塞,卡住一切写集,以便让执行慢的读节点尽快处置队列中堆积的写集内容。 当接纳队列减小到一个我们配置的阈值以下时,读节点发送continue音讯,复制将恢复。 其实就像水龙头往池子里灌水,池子水快满了就打开,池子水流走了水位线下去了再翻开。 所以,流控的目的实践上是为了保障集群节点的分歧性,而不像主从异步复制一样呈现大量的延迟。 流控参数变量与状态值 gcs.fc_limit 表示的是接纳队列抵达多大时,触发 FC(单位是事务个数,与事务大小无关)。 gcs.fc_factor 表示接纳队列在多大时,FC 会解除。度量值为 gcs.fc_limit*gcs.gc_factor ; 假如小于这个长度,则 FC 解除。 wsrep_local_recv_queue 表示当前节点从其他节点接受的队列中事务个数。 假如这个值抵达 gcs.fc_limit 值的话,就会发作 flow control ,本节点会向整个集群发送flow control音讯,整个集群会被阻塞。当该值小于 gcs.fc_limit*gcs.fc_factor 之后,flow control 解除。 wsrep_flow_control_paused_ns 流控发作时,复制同步暂停的时间。 wsrep_flow_control_paused 该状态值发作变更,含义为从上一次 SHOW GLOBAL STATUS 命令开端, 流控占全体同步数据时间的百分比(初始值0.0),理想状况下应该趋近于0.0;当它比较大的时分(超越0.6)我们需求及时采取措施,缓解流控。 wsrep_flow_control_recv 本地节点收到的集群流控事情信息数量,由于流控信息每个节点都会收到,该状态值分歧适用来定位问题节点。 wsrep_flow_control_sent 本地节点发送给集群的流控事情信息数量,能够用来确认哪个节点招致了流控产生。 流控产生的缘由?如何处置?
第 1、2 类缘由,我们需求关注监控和报警,及时处置效劳器硬件毛病和系统性能问题。 第 3 类缘由,我们能够依据 wsrep_cert_deps_distance 的值调整读节点的参数 wsrep_slave_threads ;相当于进步读节点的并发度来缓解。 第 4 类缘由,我们能够经过DB规范限制和日常巡检去规避和发现问题,处置问题。 往常回到我们当前的毛病, 查看 db3 系统监控,发现毛病期间该效劳器的 IO 运用率抵达了 100% 。
系统磁盘IO监控图 到此,毛病的直接缘由我们找到了:读节点磁盘 IO 升高惹起了流控降低了写节点的队列发送速度,构成了线程堆积。 那么毛病的基本缘由是什么呢?是什么惹起了效劳器 IO 飙高呢? 查看监控图能够看到,毛病时间点 db3 效劳器有明显的磁盘运用率变更(剩余空间先降落再上升)。
系统磁盘空间监控图 这种变更最容易想到的就是改表操作,运用 pt-online-schema-change 工具创建暂时表,挪数据后再 rename 、删除旧表。 但改表的操作 3 个节点都会同步执行,会有相似的图形变更,从监控上看这个明显不是。 其他有可能的缘由就是产生舷?暂时表了,这种暂时表属于 MySQL 自动创建,运用完成后自动删除。 普通最常见的就是排序暂时表,循着这条线索,查看了目的效劳器的慢查询日志。 慢查询日志内容: 发现集群B的确有数个并发的排序慢查询,执行时间700余秒,向前推算和毛病开端时间吻合。 需求留意的是,普通的排序操作都是在内存中完成的,产生磁盘暂时表的缘由:
MySQL排序判别流程: 当排序数据量不超越 sort buffer 容量时,MySQL 将会在内存运用快速排序算法中止排序(内部排序); 当排序数据量超越 sort buffer 容量时,MySQL 将会借助暂时文件运用归并排序算法中止排序(外部排序); 当需求借助暂时表的时分,MySQL 会优先运用内存暂时表(此时表引擎为 memory引擎),回内存暂时表取数据并不触及随机读和扫描行,所以会运用 rowId 排序方式; 当内存暂时表大小超越 tmp_table_size 限制时,则需求将内存暂时表转换为磁盘暂时表,此时回表会有随机读,所以会选择全字段排序方式。 如上所述,查询字段能否能够运用内存排序成为了关键的性能点。而 TEXT 、 BLOB 等类型不被 memory 存储引擎支持,所以不能运用内存暂时表。 Instances of BLOB or TEXT columns in the result of a query that is processed using a temporary table causes the server to use a table on disk rather than in memory because the MEMORY storage engine does not support those data types (see Section 8.4.4, “Internal Temporary Table Use in MySQL”). Use of disk incurs a performance penalty, so include BLOB or TEXT columns in the query result only if they are really needed. For example, avoid using SELECT *, which selects all columns. 慢查询表字段定义: 经过表结构信息,能够看出 select 字段中的 outer_feedback_result 字段是 mediumtext 类型,无法运用内存暂时表排序。 四、总结 集群B的数据库中,两个表的衔接查询存在排序,查询字段存在无法运用内存表的mediumtext类型,招致排序被挪到磁盘中止。 同时慢查询存在并发,惹起 IO 上涨至 100% 拖慢了读节点,进而呈现流控,惹起两集群写节点线程堆积。 我们在数据库运用中要对带大字段的 SQL 坚持警惕,应避免在线上执行可能构成严重影响的 SQL ,将其放到统计离线库执行。 在运用 PXC 架构时要留意单个节点性能对写角色节点和整个效劳器上集群的连带影响。 对不同业务类型的 DB 最好能够隔离资源,避免相互影响。 参考文献: 《MySQL运维内参》作者:周彦伟、王竹峰、强昌金 《Galera Flow Control in Percona XtraDB Cluster for MySQL》by Jay Janssen 《MySQL 8.0 Reference Manual》11.3.4 The BLOB and TEXT Types 官方文档 招募贴: END |
万奢网手机版
官网微博:万奢网服务平台