InnoDB的后台线程(IO线程,master线程,锁监控线程,错误监控线程)和内存(缓冲池,重做日志缓冲池,额外内存池)

InnoDB有多个内存块,你可以认为这些内存块组成了一个大的内存池,负责如下工作:

  1. 维护所有进程/线程需要访问的多个内部数据结构。
  2. 缓存磁盘上的数据,方便快速地读取,并且在对磁盘文件的数据进行修改之前在这里缓存。
  3. 重做日志(redo log)缓冲。
  4. ..........

后台线程的主要作用是负责刷新内存池中的数据保证缓冲池中的内存缓存的是最近的数据。此外,将已修改的数据文件刷新到磁盘文件同时保证在数据库发生异常情况下InnoDB能恢复到正常运行状态

后台线程

由于Oracle是多进程的架构(Windows下除外),因此可以通过一些很简单的命令来得知Oracle当前运行的后台进程,如ipcs命令。一般来说,Oracle的核心后台进程有CKPT、DBWn、LGWR、ARCn、PMON、SMON等。

InnoDB存储引擎是否也是这样的架构,只不过是多线程版本的实现后,看InnoDB的源代码,发现InnoDB并不是这样对数据库进程进行操作的。InnoDB存储引擎是在一个被称做master thread的线程上几乎实现了所有的功能。

默认情况下,InnoDB存储引擎的后台线程有4类——IO thread1个master thread1个锁(lock)监控线程1个错误监控线程

如下所示:

show engine innodb status\G

可以看到,IO线程分别是insert buffer thread、log thread、read thread、write thread。在Linux平台下,IO thread的数量不能进行调整,但是在Windows平台下可以通过参数innodb_file_io_threads来增大IO thread。InnoDB Plugin版本开始增加了默认IO thread的数量,默认的read thread和write thread分别增大到了4个,并且不再使用innodb_file_io_threads参数,而是分别使用innodb_read_io_threadsinnodb_write_io_threads参数。

show variables like 'innodb_version'\G

show variables like 'innodb_%io_threads'\G

内存

InnoDB存储引擎内存由以下几个部分组成:缓冲池(buffer pool)、重做日志缓冲池(redo log buffer)以及额外的内存池(additional memory pool),分别由配置文件中的参数innodb_buffer_pool_sizeinnodb_log_buffer_size的大小决定。

如下所示:(分别以字节显示)。

show variables like 'innodb_buffer_pool_size'\G

show variables like 'innodb_log_buffer_size'\G

show variables like 'innodb_additional_mem_pool_size'\G

缓冲池

缓冲池是占最大块内存的部分,用来存放各种数据的缓存。因为InnoDB的存储引擎的工作方式总是将数据库文件按页(每页16K)读取到缓冲池,然后按最近最少使用(LRU)的算法来保留在缓冲池中的缓存数据。如果数据库文件需要修改,总是首先修改在缓存池中的页(发生修改后,该页即为脏页),然后再按照一定的频率将缓冲池的脏页刷新(flush)到文件。可以通过命令show engine innodb status\G来查看innodb_buffer_pool的具体使用情况,如下所示。

在BUFFER POOL AND MEMORY里可以看到InnoDB存储引擎缓冲池的使用情况,buffer pool size表明了一共有多少个缓冲帧(buffer frame),每个buffer frame为16K,所以这里一共分配了8192*16/1024G内存的缓冲池。Free buffers表示当前空闲的缓冲帧Database pages表示已经使用的缓冲帧Modified db pages表示脏页的数量。就当前状态看来,这台数据库的压力并不大,因为在缓冲池中有大量的空闲页可供数据库进一步使用。

注意:show engine innodb status的命令显示的不是当前的状态,而是过去某个时间范围内InnoDB存储引擎的状态,从上面的示例中我们可以看到,Per second averages calculated from the last 24 seconds表示的信息是过去24秒内的数据库状态。

具体来看,缓冲池中缓存的数据页类型有:索引页数据页undo页插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、InnoDB存储的锁信息(lock info)、数据字典信息(data dictionary)等。不能简单地认为,缓冲池只是缓存索引页和数据页,它们只是占缓冲池很大的一部分而已。

下图很好地显示了InnoDB存储引擎中内存的结构情况。

ps:参数innodb_buffer_pool_size指定了缓冲池的大小,在32位Windows系统下,参数innodb_buffer_pool_awe_mem_mb还可以启用地址窗口扩展(AWE)功能,突破32位下对于内存使用的限制。但是,在使用这个参数的时候需要注意,一旦启用AWE功能,InnoDB存储引擎将自动禁用自适应哈希索引(adaptive hash index)的功能

日志缓冲

严格地说,应该是重做(redo)日志缓冲。将重做日志信息先放入这个缓冲区然后按一定频率将其刷新到重做日志文件。该值一般不需要设置为很大,因为一般情况下每一秒钟就会将重做日志缓冲刷新到日志文件,因此我们只需要保证每秒产生的事务量在这个缓冲大小之内即可。

额外的内存池

额外的内存池通常被DBA忽略,认为该值并不是十分重要,但恰恰相反的是,该值其实同样十分重要。在InnoDB存储引擎中,对内存的管理是通过一种称为内存堆(heap)的方式进行的。在对一些数据结构本身分配内存时,需要从额外的内存池中申请,当该区域的内存不够时,会从缓冲池中申请。InnoDB实例会申请缓冲池(innodb_buffer_pool)的空间,每个缓冲池中的帧缓冲(frame buffer)还有对应的缓冲控制对象(buffer control block),这些对象记录了诸如LRU、锁、等待等方面的信息,而这个对象的内存需要从额外内存池中申请。因此,当你申请了很大的InnoDB缓冲池时,这个值也应该相应增加。

 

posted @ 2017-01-12 17:25  wade&luffy  阅读(1158)  评论(0编辑  收藏  举报