后台线程

Master Thread

核心的后台线程,主要负责将缓冲池的数据异步刷新到磁盘,保证数据的一致性,包括(脏页的刷新)、合并插入缓冲、(UNDO页的回收)等

IO Thread

4个write、4个read、1个insert buffer、1个log

参数innodb_read_io_threads和innodb_write_io_threads可以进行设置。

Purge Thread

回收已经使用并分配的UNDO页。(从Innodb 1.1版本开始独立线程)

从Innodb 1.2版本开始,Innodb支持多个Purge Thread,进一步加快UNDO页的回收。同时由于Purge Thread需要离散的读取UNDO页,这样能更进一步利用磁盘的随机读取性能。

Page Cleaner Thread

在Innodb 1.2版本中引入,将之前版本中脏页的刷新操作都放入到单独的线程中完成。减轻Master Thread的工作以及用户查询线程的堵塞,进一步提高InnoDB存储引擎的性能。

内存

缓冲池

缓冲池的配置通过参数innodb_buffer_pool_size来设置。

show variables like 'innodb_buffer_pool_size';

缓冲池中缓存的数据页类型有:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引、Innodb存储的锁信息(lock info)、数据字典信息(data dictionary)等。

从InnoDB 1.0.x版本开始,允许有多个缓冲池示例。每个页根据哈希值平均分配到不同的缓冲池中。好处是减少数据库内部的资源竞争,增加数据库的并发处理能力。通过参数innodb_buffer_pool_instances来进行配置,默认为1。

show variables like 'innodb_buffer_pool_instances';

LRU List、Free List和Flush List

数据库中的缓冲池通常是通过LRU(Latest Recent Used,最近最少使用)算法进行管理的。即最频繁进行的页在LRU列表的前端,而最少使用的页在LRU列表的尾端。当缓冲池不能存放新读到的页时,将首先释放LRU列表中的尾端的页。

InnoDB的缓冲池对传统的LRU算法做了一些优化。在LRU列表中还加入了midpoint位置。新读取到的页,虽然是最新访问的页,但并不是直接放入到LRU列表的首部,而是放入LRU列表的midpoint位置。这个算法在InnoDB存储引擎下称为midpoint insertion strategy。默认情况下位置在LRU列表长度的5/8处。通过参数innodb_old_blocks_pct控制。

为什么不使用传统的LRU算法,如果直接将读取到的页放入到LRU的首部,那么某些SQL操作可能会是缓冲池中的页全部被刷出,从而影响缓冲池的效率。常见的这类操作为索引或数据的扫描操作。这类操作需要访问表中的许多页,甚至是全部的页,而这些页仅仅是这次操作需要的,并不是热点数据。

同时,InnoDB使用参数innodb_old_blocks_time管理页读取到midpoint位置后等待多久才会被加入到LRU的热端(midpoint之前的称为new列表热端,之后的列表称为old列表)。可以通过下面的设置尽可能使LRU列表中热点数据不被刷出。

set global innodb_old_blocks_time = 1000;

如果预估自己的热点数据不止63%,那么通过下面的设置来减少热点页的刷出,但是还是会被刷出。

set global innodb_old_blocks_time = 20;

当数据库刚启动时,LRU列表是空的,即没有任何的页。这是页都存放在Free列表中,当需要从缓冲池中分页时,首先从Free列表中查找是否可用的空闲页,若有则从Free列表中删除,放入到LRU列表中。否则,根据LRU算法,淘汰LRU列表末尾的页,分配给新的页。

当页从LRU列表的old部分加入到new部分时,称此时发生的操作为page made young,而因为innodb_old_blocks_time的设置而导致没有从old部分变为new部分的操作称为page not made young。

通过命令查看LRU列表及Free列表的使用状况。

show engine innodb status\G;
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 137428992
Dictionary memory allocated 417853
Buffer pool size 8191
Free buffers 7724
Database pages 467
Old database pages 0
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 433, created 34, written 36
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 467, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

在LRU列表中的页被修改后,称该页为脏页,即缓冲池中的页和磁盘上的页的数据产生了不一致。这是数据库会通过CHECKPOINT机制将脏页刷新回磁盘,而Flush列表中的页即为脏页列表。注意:脏页即存在于LRU列表中,也存在于Flush列表中。LRU列表管理缓冲池中页的可用性,Flush列表用来管理页刷新回磁盘,二者不影响。

重做日志缓冲

InnoDB存储引擎首先将重做日志信息放入重做日志缓冲区,然后按照一定的频率将其刷入到重做日志文件。由参数innodb_log_buffer_size控制,默认为8M。

重做日志在下面三种情况下会把重做日志缓冲中的内容刷新到外部磁盘的重做日志文件中。

  • Master Thread每一秒将重做日志缓冲刷新到重做日志文件。
  • 每个事物提交时会将重做日志缓冲刷新到重做日志文件。
  • 当重做日志缓冲池剩余空间小于1/2时,重做日志缓冲刷新到重做日志文件。

Checkpoint技术

如果使用Update或Delete操作,改变了页中的记录,那么此时页是脏的,即缓冲池中的页的版本比磁盘的新。数据库需要将新版本的数据从缓冲池刷新到磁盘。

但是不能每一次变化,都将新页的数据刷新到磁盘。一方面开销太大,再就是如果在刷新过程中发生了宕机,那么数据不能恢复,为了避免发生数据丢失的问题,数据库普遍采用Write Ahead Log策略,即当事务做日志提交时,先写重做日志,再修改页。如果发生宕机,通过重做日志文件来完成数据的恢复。

如果缓冲池缓存数据库中所有的数据,而且重做日志能够无线的增大,那么不需要将缓冲池中的新版本刷新回磁盘。因为发生宕机的时候通过重做日志文件就可以恢复整个数据库系统中的数据到宕机发生的时刻。但是这需要两个条件:1.缓冲池可以缓存数据库所有的数据,2.重做日志能够无限增大。这几乎是不可能的(原因就不说了...),而且就算满足条件,宕机数据库恢复的时间会非常久。(说到底,就是得用Checkpoint技术,实现分批定时将数据刷新到磁盘)

Checkpoint(检查点)技术目的是解决如下问题:

  • 缩短数据库的恢复时间;当发生宕机时,数据库不需要重做所有的日志,因为Checkpoint之前的页都已经刷新到磁盘。
  • 缓冲池不够用时,将脏页刷新到磁盘;当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,若此页为脏页,那么需要强制执行Checkpoint,将脏页也就是新版本刷回磁盘。
  • 重做日志不可用时,刷新脏页。所谓的不可用,是指重做日志的设计是循环使用的,并不是让其无限增大的,重做日志可以被重用的部分是指这些重做日志已经不再需要(应该是已经被刷回到磁盘),发生宕机时,恢复操作不需要这部分重做日志,因此这部分可以被覆盖重用,也即是上面说的重做日志不可用,但是如果想要使用不可用的重做日志,就需要强制使用Checkpoint,将缓冲池中的页至少刷新到当前重做日志的位置(这里和下面的分析有一些冲突)。

对于InnoDB存储引擎,通过LSN来标记版本的。而LSN是8个字节的数字,每个月有LSN,重做日志有LSN,Checkpoint也有LSN。

通过命令查看LSN。

show engine innodb status\G;
LOG
---
Log sequence number 33646077360
Log flushed up to 33646077360
Last checkpoint at 33646077360
0 pending log writes, 0 pending chkp writes
49687445 log i/o's done, 1.25 log i/o's/second

在InnoDB存储引擎有两种Checkpoint,分别是:

  • Sharp Checkpoint
  • Fuzzy Checkpoint

Sharp Checkpoint发生在数据库关闭时将所有的脏页都刷新回磁盘,这是默认的工作方式,即参数innodb_fast_shutdown = 1。

在内部使用Fuzzy Checkpoint进行页的刷新,即只刷新部分脏页,而不是刷新所有的脏页回磁盘。

可以分为如下一些情况:

  • Master Thread Checkpoint
  • FLUSH_LRU_LIST_Checkpoint
  • Async/Sync Flush Checkpoint
  • Dirty Page too much Checkpoint

对于Master Thread Checkpoint,差不错以每秒或者每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘。这个过程是异步的,即此时InnoDB可以进行其他操作。

FLUSH_LRU_LIST_Checkpoint是因为InnoDB需要保证LRU列表中需要有差不多100个空闲页可使用。如果没有100个空闲页,那么InnoDB会将LRU列表尾端的页移除。如果这些页中有脏页,那么需要进行Checkpoint,而这些页来自LRU列表。从MySql 5.6版本开始,这个检查工作被放在一个单独的Page Cleaner线程中进行,并且用户可以通过参数innodb_lru_scan_depth控制LRU列表中可用页的数量,默认为1024。

Async/Sync Flush Checkpoint指的是重做日志不可用的情况,这是需要强制将一些页刷新回磁盘(这里和上面的分析有一些冲突,希望可以交流学习),而此时是从脏页列表中选取的。这包含一系列的触发的判断条件,目的是为了保证重做日志的循环使用的可用性。在InnoDB 1.2.x版本之前,Async Flush Checkpoint会阻塞发现问题的用户查询线程,而Sync Flush Checkpoint会阻塞所有的用户查询线程,并且等待脏页刷新完成。从InnoDB 1.2.x版本以后,也就是MySQL 5.6版本,这部分被放到单独的Page Cleaner Thread中,不会阻塞用户查询线程。

最后一种Checkpoint的情况是Dirty Page too much,即脏页数据太多,导致强制执行Checkpoint。其目的是保证缓冲池中有足够可用的页,由参数innodb_max_drity_pages_pct控制,目前默认值75,即75%。

转载请注明出处。

作者:wuxiwei

出处:http://www.cnblogs.com/wxw16/p/6222624.html

InnoDB体系结构学习笔记的更多相关文章

  1. Oracle体系结构学习笔记

    Oracle体系结构由实例和一组数据文件组成,实例由SGA内存区,SGA意思是共享内存区,由share pool(共享池).data buffer(数据缓冲区).log buffer(日志缓冲区)组成 ...

  2. Oracle 9i & 10g编程艺术-深入数据库体系结构-学习笔记(持续更新中)

    --20170322 --1.0 --更新表的统计信息begin dbms_stats.set_table_stats(user,'EMP',numrows => 10000);end; beg ...

  3. Java异常体系结构学习笔记

    异常类的继承层次       1.Throwable是所有异常类的父类,他也继承自Object.所以Throwable是一个类,而不是接口. 2.Error这个分支的异常是由于Java虚拟机内部错误导 ...

  4. (1.3)学习笔记之mysql体系结构(C/S整体架构、内存结构、物理存储结构、逻辑结构)

    目录 1.学习笔记之mysql体系结构(C/S架构) 2.mysql整体架构 3.存储引擎 4.sql语句处理--SQL层(内存层) 5.服务器内存结构 6.mysql如何使用磁盘空间 7.mysql ...

  5. java jvm学习笔记二(类装载器的体系结构)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao                 在了解java虚拟机的类装载器之前,有一个概念我们是必须先知道的,就是java的沙箱,什 ...

  6. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  7. ARMV8 datasheet学习笔记3:AArch64应用级体系结构

    1.前言 本文主要从应用的角度介绍ARMV8的编程模型和存储模型 2. AArch64应用级编程模型 从应用的角度看到的ARM处理器元素: 可见的元素(寄存器/指令) 说明 可见的寄存器 R0-R30 ...

  8. MySQL学习笔记-MySQL体系结构总览

    MySQL体系结构总览 不管是用哪种数据库,了解数据库的体系结构都是极为重要的.MySQL体系结构主要由数据库和数据库实例构成. 数据库:物理操作系统文件或者其它文件的集合,在mysql中,数据库文件 ...

  9. 学习笔记:oracle学习一:oracle11g体系结构之体系结构概述和逻辑存储结构

    目录 1.oracle 11g体系结构概述 1.1 三个重要概念 1.2 oracle数据库存储结构 2 逻辑存储结构 2.1 数据块(Data Blocks) 2.2 数据区(Extent) 2.3 ...

随机推荐

  1. 细说前端自动化打包工具--webpack

    背景 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过链接组织在一起.用过Dreamweaver的都知道,做网页就像用word编辑文档 ...

  2. ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入

    原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...

  3. 复杂的 Hash 函数组合有意义吗?

    很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...

  4. 深入理解BFC

    定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...

  5. Android权限管理之RxPermission解决Android 6.0 适配问题

    前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...

  6. Python自然语言处理工具小结

    Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...

  7. 阿里云学生优惠Windows Server 2012 R2安装IIS,ftp等组件,绑定服务器域名,域名解析到服务器,域名备案,以及安装期间错误的解决方案

     前言: 这几天终于还是按耐不住买了一个月阿里云的学生优惠.只要是学生,在学信网上注册过,并且支付宝实名认证,就可以用9块9的价格买阿里云的云服务ECS.确实是相当的优惠. 我买的是Windows S ...

  8. android studio你可能忽视的细节——启动白屏?drawable和mipmap出现的意义?这里都有!!!

    android studio用了很久了,也不知道各位小伙伴有没有还在用eclipse的,如果还有,楼主真心推荐转到android studio来吧,毕竟亲儿子,你会知道除了启动速度稍微慢些,你找不到一 ...

  9. java中Action层、Service层和Dao层的功能区分

    Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...

  10. JavaScript将字符串中的每一个单词的第一个字母变为大写其余均为小写

    要求: 确保字符串的每个单词首字母都大写,其余部分小写. 这里我自己写了两种方法,或者说是一种方法,另一个是该方法的变种. 第一种: function titleCase(str) { var new ...