Mysql之InnoDB中线程详解_mysql purge线程_才放一花天地香的博客-程序员秘密

技术标签: java  Mysql  mysql  数据库  

InnoDB存储引擎是多线程的模型,因此其后台有多个不同的后台线程,负责处理不同的任务。主要分为:Master Thread、IO Thread、Purge Thread和Page Cleaner Thread

Master Thread

通过名字就可以看出,Master Thread是非常重要的线程,维护着InnoDB存储引擎中的大多数的操作,因为此线程的效率也直接影响着InnoDB的整体性能。所以,不同InnoDB版本的改进也主要针对此线程的功能进行的。InnoDB1.0.x版本之前 Master Thread的功能奠定了此线程操作的基础,后面的1.0.x、1.1.x和1.2.x的改动都是在其之前功能的基础上进行的,所以我们有必要先了解下1.0.x版本之前 Master Thread线程有哪些操作,然后再了解后续的版本中是怎么改进的。

Master Thread具备最高的线程优先级。其内部有多个循环(loop)组成:主循环(loop)、后台循环(backgroup loop)、刷新循环(flush loop)、暂停循环(suspend 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这个参数(默认是90,代表90%),如果超过了这个阈值,InnoDB认为需要做磁盘同步的操作,将100个脏页写入磁盘中。

每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。background loop会执行一下操作:

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

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

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

  1. 首先会进入主循环,执行“每一秒操作”和“每十秒操作”,其中先循环执行“每一秒操作”的逻辑,当计算器大于等于10时,就进入“每十秒操作”的逻辑,然后在跳回到“每一秒操作”的逻辑,一直这样循环下去,直到没有用户活动或数据库关闭,会跳到background loop的执行逻辑。
  2. background loop的逻辑执行完毕,如果有用户活动,这跳入主循环;如果没有用户活动,则跳到flush loop循环。
  3. flush loop的逻辑执行完毕,会跳入suspend_loop(暂停循环)。
  4. 暂停循环中会将Master Thread挂起,等待事件唤醒。
  5. 有新的事件发生时,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.

另外一个优化是,参数innodb_max_dirty_pages_pct默认值由之前的90变成了75,这个改动既可以加快刷新脏页的频率,又能保证磁盘IO的负载。

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

还有一个改变是:在InnoDB1.0.x版本开始引入innodb_purge_batch_size,用于控制每次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 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_threads和innodb_write_io_threads参数进行设置,并且读线程ID总是小于写线程。

异步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,这样做的目的是为了加快undo页的回收。同时由于Purge Thread需要离散地读取undo页,这样也能更进一步利用磁盘的随机读取性能。

Page Cleaner Thread

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_38571892/article/details/123535624

智能推荐

Kotlin告别FindViewById的原理_快乐的编码小猪的博客-程序员秘密

引子使用Kotlin引用控件的时候,不用写findViewById,直接用id即可,比如<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-au

精品分享:基于 SpringBoot + Vue 开发的云盘系统(含大文件断点续传剖析)_小螺旋丸的博客-程序员秘密

基于 SpringBoot + Vue 开发的云盘系统,为用户提供一个简单、方便的文件存储方案,快来围观吧!

窗口切换和网页标签切换快捷键_piaoliangjinjin的博客-程序员秘密

日常生活和工作中,当电脑打开很多窗口或者网页打开好多标签,来回切换就成了令人头疼的问题。记住这几个快捷键,就非常必要了。工具/原料 xp/win7/win10 方法/步骤 win+tab 窗口切换,后窗口往前切换, win +shift+tab,前窗口往后切换。 alt+tab窗口切换,左窗口往右切换, alt+shift+tab,右窗口往左切换。 跟第一组快捷键功能相同。但win+更3d一些。 ctrl+tab 网页标签页切换,左标签向右切换

linux下安装mysql_不会推车的娘们的博客-程序员秘密

1  下载mysql   2  上传到服务器   rz 使用secureCRT,我这里上传到 了 /opt/下3  加压 3.1  tar -zxvf  mysql-8.0.11-linux-glibc2.12-x86_64.tar.gz 3.2  在MySQL根目录下新建一个文件夹data,用于存放数据       mkdir data  3.3 创建 mysql 用户组和 mysql 用户  ...

使用迭代器来遍历HashMap_坚持学习的猿的博客-程序员秘密

通过迭代器来遍历HashMap,演示一下迭代器Iterator的使用Map<Integer, String> map = new HashMap<>();map.put(1, "java");map.put(2, "c++");map.put(3, "php");Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();while (iterator.hasN

(一)ORBSLAM2主要配置_weixin_30729609的博客-程序员秘密

  (1)ORBSLAM2文件夹里面有个build.sh文件,里面主要是编译时终端需要执行的命令,这里把它们放到.sh文件中统一执行。  (2)阅读ORBSLAM2的CmakeList可以知道运行ORBSLAM2需要相关的依赖库,具体如下: Eigen Pangolin OpenCV g2o(ORBSLAM2自带) DBoW2(ORBSLAM2自带)...

随便推点

dependencies标签的两种形式_KnifeBlade的博客-程序员秘密

        在使用maven进行多module项目开发时经常会遇到依赖包版本管理的问题,此时我们需要注意pom.xml文件中两个标签的区别:    1、dependencyManagement下的dependencies标签中申明的jar包不会真的去被下载,相当于对依赖包进行版本管理的管理器;    2、单独的dependencies标签(没有被dependencyManagement括起来)...

中国地图着色C语言实验报告,中国地图着色源代码_小丹尼DannyData的博客-程序员秘密

转自百度文库:http://wenku.baidu.com/link?url=1awdq8I04M-DS9l6hEBl1cwTPTPEDQ6uzXLKAbi7iNCLNNnkDDMpn0VkLgblptmhhqawDpBgAOORY5iZ052k1av78fobytpD2U3W9JhZITu&from_mod=copy_login#include #include #include usi...

SpringMVC学习笔记_01_Eicoma的博客-程序员秘密

SpringMVC1. MVC三层架构Model2时代用户发送请求Servlet接收请求数据,调用相应业务逻辑完成业务逻辑处理,返回相应的数据给ServletServlet转向JSP,JSP渲染页面响应给前端,更新页面职责分类Controller 控制器取得表单数据调用业务逻辑转向指定的页面Modle 模型负责业务逻辑处理保存数据的状态View 视图显示页面2. 为什么学习SpringMVC优点轻量,简便易学高效,基于请求响

Fiddler 抓取https请求_全栈测试开发日记的博客-程序员秘密

  引言  在日常测试中,不管是功能测试还是接口测试,避免不了抓包。抓包工具有很多,这里只讲fiddler的使用,并且是对https请求的抓取。  概况  抓包之前,先了解一下Fiddler。  Fiddler是一款免费且功能强大的数据包抓取软件。它通过代理的方式获取程序http通讯的数据,可以用其检测网页和服务器的交互情况,能够记录所有客户端和服务器间的http请求,支持监视、...

appScan常见高危漏洞,走过的坑啊_appscan常见漏洞_weixin_子不语的博客-程序员秘密

appScan常见高危漏洞,走过的坑啊一、SQL 盲注(SQL注入)1、 过滤特殊字符2、使用预编译,不要拼接sql3、对sql执行部分异常进行捕获,不要抛出不同的异常,以免被推测有漏洞4、可能appscan误报误报解决:(1)、把错误的页面单独反复测试(2)、把AppScan扫描的线程数改成1(默认10)二、存储的跨站点脚本编制(xss漏洞)1、对存储的内容进行xss过滤。...

魔兽世界怀旧服服务器信息,魔兽世界怀旧服服务器类型有哪些_怀旧服服务器类型介绍..._小透明熊熊的博客-程序员秘密

魔兽世界怀旧服服务器类型有哪些?魔兽世界怀旧服服务器类型介绍。相信有很多小伙伴们都不知道,魔兽世界怀旧服服务器类型有哪些,小编这就来和大家讲讲魔兽世界怀旧服服务器类型,快点进来和小编一起看看吧。服务器类型我们设有多种类型的服务器供你选择。请谨慎选择,因为每种服务器都有独特的玩法风格。PVE—此类服务器适合不想参加开放世界PvP的玩家。游戏中所有地图都处于“争夺中”状态,除了敌方阵营的主城,在其中所...