MySQL里Wating for Slave workers to free pending events到底在等什么

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: MySQL里Wating for Slave workers to free pending events到底在等什么

一、问题来源

这是一位朋友给我的一个截图,说show slave status一直处于Wating for Slave workers to free pending events状态,这个库是MTS从库,版本为5.7.25

https://mmbiz.qpic.cn/mmbiz_png/nts52nHheTySvftSngeTyZ4sVW3VFHhGibJp0J6O8cNZdfBFjCGFMq8xGoavMpYlHGD3KjD9icxJibUYyemfZGKvw/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1

二、关于等待

我曾经在我的主从原理系列中(已经成书)解释过大部分协调线程的等待,如下:

  • “Waiting for dependent transaction to commit”

由于协调线程判定本事务由于last commit大于current_lwm因此不能并行回放,协调线程处于等待,大事务会加剧这种情况。

  • “Waiting for slave workers to process their queues”

由于没有空闲的工作线程,协调线程会等待。这种情况说明理论上的并行度是理想的,但是可能是参数slave_parallel_workers设置不够。当然设置工作线程的个数应该和服务器的配置和负载相结合考虑。

  • “Waiting for Slave Worker queue”

由于工作线程的任务队列已满,协调线程会等待。这种情况前面说过是由于一个事务包含了过多的Event并且工作线程应用Event的速度赶不上协调线程分配Event的速度,导致了积压并且超过了16384个Event。

但是对于Wating for Slave workers to free pending events等待,只是简单的提及了可能涉及到big event,这里想说的就是实际上这个等待可能和两方面有关:

  1. 如果涉及到big event,那么要求worker线程当前没有积压的event正在执行
  2. 如果不是big event,那么需要判断当前worker线程积压的event大小加上本次进入worker线程对列的event大小之和不能超过参数slave_pending_jobs_size_max的大小

什么是big event呢?根据源码判断如下:

 bool big_event= (ev_size > rli->mts_pending_jobs_size_max);

遇到这种问题应该在日志中能够看到

2020-10-28T14:07:49.522388+08:00 14 [Note] Multi-threaded slave statistics for channel '': seconds elapsed = 676;.....waited due the total size 的大小不为0。

三、判断的维度

这里我们简单考虑一下判断一下可以进入worker线程队列的维度。首先我们说对于woker线程队列来讲他有一个固定的大小也就是积压不能超过16384个event,这里我们还明白来,这些积压的event还不能太大,如果太大就会出现Wating for Slave workers to free pending events等待,因此总结一下:

  • 如果协调线程发现分配的woker线程积压的event个数超过了 16384个event,那么进入Waiting for Slave Worker queue等待
  • 如果协调线程发现分配的worker线程积压的event的大小超过了slave_pending_jobs_size_max设置的大小,那么进入Wating for Slave workers to free pending events等待

当然这是从个数和大小两个不同的维度来判断的,如果一个大事务,我们知道这样的事务会形成很多8K左右的event(比如一次delete了1000W的数据),那么如果只用个数来判断那么就是积压的event大小最多达到(8K*16384=128M),实际上我们的参数slave_pending_jobs_size_max 默认为16M,这种情况下可能协调线程会先触发Wating for Slave workers to free pending events等待。

因此不管是触发了Waiting for Slave Worker queue等待还是Wating for Slave workers to free pending events等待,我们都需要检查一下worker线程回放event的效率是不是遇到了问题。

四、关于源码等待

函数入口append_item_to_jobs

  • 关于等待,如下:
  bool big_event= (ev_size > rli->mts_pending_jobs_size_max);

/*
C waits basing on data sizes in the queues.
If it is a big event (event size is greater than
slave_pending_jobs_size_max but less than slave_max_allowed_packet),
it will wait for all the jobs in the workers's queue to be
completed. If it is normal event (event size is less than
slave_pending_jobs_size_max), then it will wait for
enough empty memory to keep the event in one of the workers's
queue.
NOTE: Receiver thread (I/O thread) is taking care of restricting
the event size to slave_max_allowed_packet. If an event from
the master is bigger than this value, IO thread will be stopped
with error ER_NET_PACKET_TOO_LARGE.
*/
while ( (!big_event && new_pend_size > rli->mts_pending_jobs_size_max)//条件1
|| (big_event && rli->mts_pending_jobs_size != 0 ))//条件2
{
rli->mts_wq_oversize= TRUE;
rli->wq_size_waits_cnt++; // 增加由于big event或者积压大小过多导致的等待次数
thd->ENTER_COND(&rli->pending_jobs_cond, &rli->pending_jobs_lock,
&stage_slave_waiting_worker_to_free_events, &old_stage);//进入等待状态
mysql_cond_wait(&rli->pending_jobs_cond, &rli->pending_jobs_lock);//等待条件变量
mysql_mutex_unlock(&rli->pending_jobs_lock);
thd->EXIT_COND(&old_stage);
if (thd->killed)
return true;
if (rli->wq_size_waits_cnt % 10 == 1)
sql_print_information("Multi-threaded slave: Coordinator has waited "
"%lu times hitting slave_pending_jobs_size_max; "
"current event size = %zu.",
rli->wq_size_waits_cnt, ev_size);
mysql_mutex_lock(&rli->pending_jobs_lock);
new_pend_size= rli->mts_pending_jobs_size + ev_size;
}
  • 关于唤醒,如下:当woker线程执行完event后,会进行减去执行完event size的操作如下,入口函数remove_item_from_jobs:
减去执行完event size
rli->mts_pending_jobs_size-= ev->common_header->data_written;

唤醒
/ coordinator can be waiting /
if (rli->mts_pending_jobs_size < rli->mts_pending_jobs_size_max &&
rli->mts_wq_oversize) // TODO: unit/general test wq_oversize
{
rli->mts_wq_oversize= FALSE;
mysql_cond_signal(&rli->pending_jobs_cond);
}


全文完。



            </div>
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
编译器 测试技术 C++
【Python 基础教程 01 全面介绍】 Python编程基础全攻略:一文掌握Python语法精髓,从C/C++ 角度学习Python的差异
【Python 基础教程 01 全面介绍】 Python编程基础全攻略:一文掌握Python语法精髓,从C/C++ 角度学习Python的差异
628 0
|
Ubuntu 关系型数据库 MySQL
libmysqlclient.so.18(libmysqlclient.so.20 libmysqlclien.so) => not found
libmysqlclient.so.18(libmysqlclient.so.20 libmysqlclien.so) => not found
1457 0
libmysqlclient.so.18(libmysqlclient.so.20 libmysqlclien.so) => not found
|
Python
Mac安装Python3.12开发环境
Mac安装Python3.12开发环境
726 2
|
存储 Oracle 关系型数据库
达梦数据库入门语法:从基础到进阶的指南
达梦数据库入门语法:从基础到进阶的指南
3221 2
|
SQL 关系型数据库 MySQL
OBCP实践 - 迁移 MySQL 数据到 OceanBase 集群
OBCP实践 - 迁移MySQL数据到OceanBase集群,这是一个涉及到将现有MySQL数据库的数据和表结构迁移到OceanBase分布式数据库集群的实际操作过程。OceanBase是一款高度兼容MySQL协议的分布式数据库产品,支持在线平滑迁移,以便企业用户可以从传统的MySQL数据库平滑迁移到OceanBase,以实现更高的可用性、扩展性和性能。
460 0
|
SQL 存储 容灾
关于主从延迟,一篇文章给你讲明白了!
在实际的生产环境中,由单台MySQL作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面 因此,一般来说都是通过集群主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy)来提升数据库的并发负载能力进行部署与实施总结MySQL主从集群带来的作用是:提高数据库负载能力,主库执行读写任务(增删改),备库仅做查询。提高系统读写性能、可扩展性和高可用性。数据备份与容灾,备库在异地,主库不存在了,备库可以立即接管,无须恢复时间。用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。可以简单理解为记录的就是sq
2364 0
|
SQL Oracle 关系型数据库
|
数据中心 Windows
Windows Server 2012 R2 安装密钥
Windows Server 2012 R2 安装密钥(只适用安装,不支持激活) 标准版 = NB4WH-BBBYV-3MPPC-9RCMV-46XCB数据中心版 = BH9T4-4N7CW-67J3M-64J36-WW98Y M98WF-NY2PP-73243-PC8R6-V6B...
8627 0
|
SQL 数据库连接 调度
达梦(DM)数据库管理工具
讲述达梦(DM)数据库管理工具的使用
|
Oracle 关系型数据库 MySQL
【大数据实时数据同步】GoldenGate实时同步异常:OGG-03533:character ‘c2 a0‘ at offset 0 that is not available报错解决
博主所在单位目前使用Oracle GoldenGate将各个业务生产库汇聚到一起做数仓实时ODS平台,源端库可能涉及Oracle、Mysql、达梦、Guassdb库。 最近遇到了这个错误:`OGG-03533:character &#39;c2 a0&#39; at offset 0 that is not available。` 导致报错的原因是源端库有业务人员手动用excel往数据库导入数据,源端库字符集:`AMERICAN_AMERICA.AL32UTF8` ,目标库ODS字符集:`AMERICAN_AMERICA.ZHS16GBK`。
【大数据实时数据同步】GoldenGate实时同步异常:OGG-03533:character ‘c2 a0‘ at offset 0 that is not available报错解决