MySQL后台线程详解

news/2025/1/6 7:34:41/

前言

MySQL的服务实现通过后台多个线程、内存池、文件交互来实现对外服务的,不同线程实现不同的资源操作,各个线程相互协助,共同来完成数据库的服务。本章简单总结MySQL的一些后台线程以及主要作用。 本章收录在MySQL性能优化+原理+实战专栏,更多优质内容点击此处查看。

在这里插入图片描述InnoDB存储引擎是多线程的模型,因此其后台有多个不同的后台线程,负责处理不同的任务。主要分为:Master ThreadIO ThreadPurge ThreadPage Cleaner Thread

目录

  • 一、Master Thread
  • 二、IO Thread
  • 三、Purge Thread
  • 四、Page Cleaner Thread

一、Master Thread

Master Thread具备最高的线程优先级。其内部有

  • 主循环(loop)
  • 后台循环(backgroup loop)
  • 刷新循环(flush loop)
  • 暂停循环(suspend loop)

多个循环(loop)组成。Master Thread会根据数据库的状态在这些循环之间切换。Loop被称为主循环,因为大多数的操作都是在这个循环中,其中有两大部分的操作:每秒钟的操作每10秒的操作

每秒钟的操作包含以下内容:

  • 重做日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)
  • 合并插入缓冲(可能)
  • 至多刷新100个InnoDB的缓冲池中的脏页到磁盘(可能)
  • 如果当前没有用户活动,这切换到BackGround loop(可能)

我们简单的解读一下“每秒中的操作”:

即使某个事务还没有提交,InnoDB存储引擎仍然每秒会将重做日志缓冲中的内容刷新到重做日志文件。这可以很好的解释为什么再大的事务提交的时间也是很短的。

合并插入缓冲并不是每秒都会发生的。InnoDB存储引擎会判断当前一秒内发生的IO次数是否小于5次,如果小于5次,InnoDB认为当前IO的压力很小,可以执行合并插入缓冲的操作。

刷新100个脏页也不是每秒都会发生的。InnoDB通过判断当前缓冲池中脏页的比例(buf_get_modified_ratio_pct)是否超过了配置文件中的最大脏页的百分数innodb_max_dirty_pages_pct这个动态参数,如果超过了这个阈值,InnoDB认为需要做磁盘同步的操作,将100个脏页写入磁盘中,这个参数不建议调整。

mysql> show variables like '%innodb_max_dirty_pages_pct%';
+--------------------------------+-----------+
| Variable_name                  | Value     |
+--------------------------------+-----------+
| innodb_max_dirty_pages_pct     | 90.000000 |
| innodb_max_dirty_pages_pct_lwm | 10.000000 |
+--------------------------------+-----------+
2 rows in set (0.01 sec)

每10秒的操作包含以下内容:

  • 刷新100个脏页到磁盘(可能的情况下)
  • 合并至多5个插入缓冲(总是)
  • 删除无用的undo页(总是)
  • 刷新100个或者10个脏页到磁盘(总是)

我们来解读一下“每十秒操作”的整个过程:

首先InnoDB会先判断过去十秒之内磁盘的IO操作是否小于200次,如果是,InnoDB认为当前有足够的磁盘IO操作能力,因此将100个脏页刷新到磁盘。

接着,InnoDB会合并插入缓冲。不同于“每秒一次操作”时可能发生的合并插入缓冲操作,这次的合并插入缓冲一定会发生。之后,InnoDB会再进行一次重做日志缓冲刷新到磁盘的操作。

接着InnoDB会进行一步执行full purge的操作,即删除无用undo页。但是在删除前会判断是否有查询操作需要读取之前版本的undo信息,如果没有,这可以删除,但每次最大回收20个undo页。

然后,InnoDB会判断缓冲池中脏页的比例(buf_get_modified_ratio_pct),如果有超过70%的脏页,则刷新100个脏页到磁盘,如果脏页比例小于70%,则只需刷新10个脏页到磁盘。

若当前没有用户活动(数据库空闲时)或者数据库关闭,就会切换到background loop执行以下下操作:

  • 删除无用的Undo页(总是)
  • 合并20个插入缓冲(总是)
  • 跳回到主循环(总是)
  • 不断刷新100个页直到符合条件(可能,跳转到flush loop中完成)

若flush loop中也没有什么事情可以做了,InnoDB会切换到suspend_loop,将Master Thread 挂起,等待事件发生。若用户启用了InnoDB引擎,但是没有创建InnoDB的表,那么Master Thread总是处于挂起状态。

简单总结一下这四种循环的切换过程:

首先会进入主循环,执行每一秒操作和每十秒操作,其中先循环执行每一秒操作的逻辑,当计算器大于等于10时,就进入每十秒操作的逻辑,然后在跳回到“每一秒操作”的逻辑,一直这样循环下去,直到没有用户活动或数据库关闭,会跳到background loop的执行逻辑。

接着background loop的逻辑执行完毕,如果有用户活动,这跳入主循环;如果没有用户活动,则跳到flush loop循环。

接着flush loop的逻辑执行完毕,会跳入suspend_loop(暂停循环)。

最后暂停循环中会将Master Thread挂起,等待事件唤醒。 有新的事件发生时,MasterThread被唤醒,重复1~4的步骤。

以上的逻辑是InnoDB1.0.x版本之前中Master Thread的执行逻辑,在后来的1.0.x和1.1.x版本中对Master Thread的功能做了一些优化,来提升Master Thread的执行效率,进行提升InnoDB的性能,主要优化内容如下:

从之前的版本中我们可以看出,无论何时,InnoDB最大只会刷新100个脏页,合并20个插入缓冲,这是硬编码的。但是随着固态硬盘的出现大大提升了磁盘的写入性能,如果每次刷新脏页和合并插入缓冲的数量不变的话,就会造成磁盘写性能的浪费。特别是对于写入密集的应用程序,每秒可能会产生大于100个的脏页,如果是产生大于20个插入缓冲的情况,Master Thread似乎会“忙不过来”,或者说它总是做得很慢。同时,当发生宕机需要恢复时,由于很多数据还没有刷新回磁盘,会导致恢复的时间可能需要很久,尤其是对于insert buffer来说。

因此从InnoDB1.0.x开始,提供了动态变量innodb_io_capacity,来表示磁盘IO的吞吐量,默认为200。执行规则如下:

  • 在合并插入缓冲时,合并插入缓冲的数量为innodb_io_capacity值为5%;
  • 在从缓冲区刷新脏页时,刷新脏页的数量为innodb_io_capacity.
mysql> show variables like '%innodb_io_capacity%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_io_capacity     | 200   |
| innodb_io_capacity_max | 2000  |
+------------------------+-------+
2 rows in set (0.00 sec)

当用户采用SSD或其它提高IO性能的措施后,可调整innodb_io_capacity直到符合磁盘IO的吞吐量(IPOS),但是不建议超过20000。
set persist innodb_io_capacity=300

Innod1.0.x版本还有增加了一个参数是innodb_adaptive_flushing(自适应刷新。默认开启),该值影响每秒刷新脏页的数量。具体规则:InnoDB会通过判断产生重做日志(redo log)的速度来决定最合适的刷新脏页数量。因此,当脏页的比例小于innodb_max_dirty_pages_pct时,也会刷新一定量的脏页。

还有一个改变是:在InnoDB1.0.x版本开始引入innodb_purge_batch_size(默认值300),用于控制每次full purge操作时回收Undo页的数量。并且从InnoDB1.1版本开始,purge操作独立到单独的线程(purge Thread)中进行,以此来减轻Master Thread的工作。

在InnoDB1.2.x版本中又进行了优化,主要优化内容如下:
这个版本中最大的优化就是:对于刷新脏页的操作,从Master Thread线程分离到一个单独的Page Cleaner Thread,从而减轻了Master Thread的工作,同时进一步提高了系统的并发性。

二、IO Thread

在InnoDB中大量使用了AIO(Async IO)异步IO来处理写请求,这样可以极大的提高数据库的性能。而IO Thread的工作主要是负责这些IO请求的回调处理。在InnoDB1.0版本之前共有4个IO Thread,分别是write、read、inser buffer和log IO Thread。从InnoDB1.0.x版本开始,read thread和write thread分别增大到了4个,分别使用innodb_read_io_threadsinnodb_write_io_threads参数进行设置,并且读线程ID总是小于写线程。

mysql> show variables like '%io_threads%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| innodb_read_io_threads  | 4     |
| innodb_write_io_threads | 4     |
+-------------------------+-------+
2 rows in set (0.01 sec)

异步IO是InnoDB很重要的一个特性,也是提升性能的一个重要功能。与AIO对应的是Sync IO,即每进行一次IO操作,需要等待此次操作结束才能继续接下来的操作。但是如果用户发出的是一条索引扫描的查询,那么这条SQL查询语句可能需要扫描多个索引页,也就是需要进行多次的IO操作。在每扫描一个页并等待其完成后再进行下一次的扫描,这是没有必要的。用户可以发出一个IO请求后立即再发出另一个IO请求,当全部IO请求发送完毕后,等待所有IO操作的完成,这就是AIO。

AIO的另一个优势是可以进行IO Merge操作,也就是将多个IO合并为1个IO,这样可以调高IOPS的性能。

三、Purge Thread

Purge Thread是InnoDB1.1版本开始新加入的线程,专门用于处理回收不再需要的undo页的工作,以此来减轻Master Thread的工作,从而提高CPU的使用率以及提升存储引擎的性能。在Mysql配置文件中,通过Innodb_purge_threads参数来设置线程数。但是在InnoDB1.1版本中,即使设置了此参数大于1,在InnoDB启动时也会将其设为1。在InnoDB1.2版本开始,InnoDB支持多个Purge Thread,默认4个这样做的目的是为了加快undo页的回收。同时由于Purge Thread需要离散地读取undo页,这样也能更进一步利用磁盘的随机读取性能。

mysql> show variables like '%Innodb_purge_threads%';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| innodb_purge_threads | 4     |
+----------------------+-------+
1 row in set (0.00 sec)

四、Page Cleaner Thread

Page Cleaner Thread是INnoDB1.2版本开始引入的。其作用是将之前版本中脏页的刷新操作都放入到单独的线程中来完成。其目的是为了减轻原Master Thread的工作及对于用户查询线程的阻塞,进一步提高InnoDB的性能
在这里插入图片描述


http://www.ppmy.cn/news/54331.html

相关文章

B/S结构系统的会话机制(session)

B/S结构系统的会话机制(session) 文章目录 B/S结构系统的会话机制(session)每博一文案1. session 会话机制的概述2. 什么是 session 的会话3. session 的作用4. session 的实现原理解释5. 补充: Cookie禁用了,session还能找到吗 ?6. 总结一下…

张勇:阿里云是一家云计算产品公司,要坚定走向“产品被集成”

4月26日,在2023阿里云合作伙伴大会上,阿里巴巴董事会主席兼CEO、阿里云智能CEO张勇表示,阿里云的核心定位是一家云计算产品公司,生态是阿里云的根基。让被集成说到做到的核心,是要坚定走向“产品被集成”。 张勇表示&a…

chatGPT账号apikey码-chatGPT 免费APIKEY

ChatGPT API Key免费吗 ChatGPT使用的API密钥可以免费获取,但是其使用可能会受到一些限制。具体而言,根据你所使用的API提供者和服务级别,免费的API密钥可能会受到以下限制: 次数限制:某些API可能会限制您的API调用次…

TryHackMe-Lunizz CTF(boot2root)

Lunizz CTF 端口扫描 循例nmap Web枚举 进80,apache默认页面 gobuster扫一下目录 /hidden一个文件上传点, 图片上传后无权访问/hidden/uploads/ /whatever一个假的命令执行点 /instructions.txt 由 CTF_SCRIPTS_CAVE 制作(不是真实的)感谢…

BMP图像处理(jpeg转bmp,以及bmp图片缩放,附代码)

目录 背景 一、BMP图片讲解: 二、代码: 背景 1、主要记录下BMP图片的功能,里面包括jpeg格式图片转bmp格式的图片,还有bmp图片的缩放,因为bmp格式的图片一般都很大。 2、网上搜的代码,好多的代码都有依…

【社区图书馆】PyTorch高级机器学习实战 读书感想

《PyTorch高级机器学习实战》十大特点 1. 深入全面的内容覆盖: 本书的内容深入而全面,涵盖了深度学习中的多个领域,包括自然语言处理、计算机视觉、强化学习等,并介绍了各种不同的神经网络结构和优化算法。 2. 理论和实践并重&am…

哈夫曼求编码最小化实现

这里介绍哈夫曼求编码的最小化实现重点,假定读者有基础。 不涉及太多设计层面 / 语言相关 / 基础理论的问题。 一、哈弗曼树构建的思想 int chars[] {A, B, C, D, E, F}; int weight[] {1, 2, 3, 4, 5, 6};假设各个字符出现的次数是上面的。出现次数就是权重we…

GPT-4开源平替miniGPT-4来了,仅需23G显存单机可run,附论文、项目代码地址

来源 | 新智元 微信号:AI-era 先是ChatGPT的发布给世界带来了一点小小的NLP震撼,随后发布的GPT-4更是破圈计算机视觉,展现了非凡的多模态能力。 不光能读懂人类的梗,给个手绘草图甚至可以直接写出网站的代码,彻底颠覆…