常言说得好,每个成功男人背后都有一个为他默默付出的女人,而对于MySQL来说,这个“人”就是InnoDB存储引擎。

MySQL区别于其他数据库的最为重要的特点就是其插件式的表存储引擎。而在众多存储引擎中,InnoDB是最为常用的存储引擎。从MySQL5.5.8版本开始,InnoDB存储引擎是默认的存储引擎。

InnoDB存储引擎支持事务,其设计目标主要面向在线事务处理(OLTP)的应用。其特点是行锁设计、支持外键,并支持非锁定读,即默认读操作不会产生锁。

InnoDB通过使用多版本并发控制(MVCC)来获取高并发性,并且实现了SQL标准的4中隔离级别,默认为REPEATABLE级别。同时,使用一种被称为next-key-locking的策略来避免幻读现象的产生。除此之外,InnoDB存储引擎还提供了插入缓冲(insert buffer)、二次写(double write)、自适应哈希索引(adaptive hash index)、预读(read ahead)等高性能和高可用的功能。

上图详细显示了InnoDB存储引擎的体系架构,从图中可见,InnoDB存储引擎由内存池,后台线程和磁盘文件三大部分组成。接下来我们就来简单了解一下内存相关的概念和原理。

缓冲池

InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。但是由于CPU速度和磁盘速度之间的鸿沟,基于磁盘的数据库系统通常使用缓冲池记录来提高数据库的的整体性能。

在数据库中进行读取操作,首先将从磁盘中读到的页放在缓冲池中,下次再读相同的页中时,首先判断该页是否在缓冲池中。若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。否则,读取磁盘上的页。

对于数据库中页的修改操作,则首先修改在缓冲池中的页,然后再以一定的频率刷新到磁盘上。页从缓冲池刷新回磁盘的操作并不是在每次页发生更新时触发,而是通过一种称为CheckPoint的机制刷新回磁盘。

所以,缓冲池的大小直接影响着数据库的整体性能,可以通过配置参数innodbbufferpool_size来设置。

具体来看,缓冲池中缓存的数据页类型有:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、InnoDB存储的锁信息(lock info)和数据字典信息(data dictionary)。

在架构图上可以看到,InnoDB存储引擎的内存区域除了有缓冲池之外,还有重做日志缓冲和额外内存池。InnoDB存储引擎首先将重做日志信息先放到这个缓冲区中,然后按照一定频率将其刷新到重做日志文件中。重做日志缓冲一般不需要设置的很大,该值可由配置参数innodblogbuffer_size控制。

数据页和索引页

Page是Innodb存储的最基本结构,也是Innodb磁盘管理的最小单位,与数据库相关的所有内容都存储在Page结构里。Page分为几种类型,数据页和索引页就是其中最为重要的两种类型。

插入缓冲(Insert Buffer)

我们都知道,在InnoDB引擎上进行插入操作时,一般需要按照主键顺序进行插入,这样才能获得较高的插入性能。当一张表中存在非聚簇的且不唯一的索引时,在插入时,数据页的存放还是按照主键进行顺序存放,但是对于非聚簇索引叶节点的插入不再是顺序的了,这时就需要离散的访问非聚簇索引页,由于随机读取的存在导致插入操作性能下降。

InnoDB为此设计了Insert Buffer来进行插入优化。对于非聚簇索引的插入或者更新操作,不是每一次都直接插入到索引页中,而是先判断插入的非聚集索引是否在缓冲池中,若在,则直接插入;若不在,则先放入到一个Insert Buffer中。看似数据库这个非聚集的索引已经查到叶节点,而实际没有,这时存放在另外一个位置。然后再以一定的频率和情况进行Insert Buffer和非聚簇索引页子节点的合并操作。这时通常能够将多个插入合并到一个操作中,这样就大大提高了对于非聚簇索引的插入性能。

两次写(Double Write)

如果说Insert Buffer给InnoDB存储引擎带来了性能上的提升,那么Double Write带给InnoDB存储引擎的是数据页的可靠性。

如上图所示,Double Write由两部分组成,一部分是内存中的double write buffer,大小为2MB,另一部分是物理磁盘上共享表空间连续的128个页,大小也为2MB。在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是通过memcpy函数将脏页先复制到内存中的该区域,之后通过doublewrite buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免操作系统缓冲写带来的问题。在完成doublewrite页的写入后,再讲doublewirite buffer中的页写入各个表空间文件中。

如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,InnoDB存储引擎可以从共享表空间中的doublewrite中找到该页的一个副本,将其复制到表空间文件中,再应用重做日志。

重做日志(Redo Log Buffer)

当缓冲池中的页的版本比磁盘要新时,数据库需要将新版本的页从缓冲池刷新到磁盘。但是如果每次一个页发送变化,就进行刷新,那么性能开发是非常大的,于是InnoDB采用了Write Ahead Log策略,即当事务提交时,先写重做日志,然后再择时将脏页写入磁盘。如果发生宕机导致数据丢失,就通过重做日志进行数据恢复。

InnoDB存储引擎会首先将重做日志信息先放入重做日志缓冲中,然后再按照一定频率将其刷新到重做日志文件。重做日志缓冲一般不需要设置得很大,因为一般情况每一秒钟都会讲重做日志缓冲刷新到日志文件中。可通过配置参数innodblogbuffer_size控制,默认为8MB。

除了每秒刷新机制之外,每次事务提交时重做日志缓冲也会刷新到日志中。InnoDB是事务的存储引擎,其通过Force Log at Commit机制实现事务的持久性,即当事务提交时,必须先将该事务的所有日志写入到重做日志文件进行持久化,然后事务的提交操作完成才算完成。InnoDB的写入机制大致入下图所示。

为了确保每次日志都写入到重做日志文件,在每次讲重做日志缓冲写入重做日志后,必须调用一次fsync操作,将缓冲文件从文件系统缓存中真正写入磁盘。

可以通过innodbflushlogattrx_commit来控制重做日志刷新到磁盘的策略。该参数默认值为1,表示事务提交必须进行一次fsync操作,还可以设置为0和2。0表示事务提交时不进行写入重做日志操作,该操作只在主线程中完成,2表示提交时写入重做日志,但是只写入文件系统缓存,不进行fsync操作。由此可见,设置为0时,性能最高,但是丧失了事务的一致性。

自适应哈希索引(Adaptive Hash Index)

InnoDB会根据访问的频率和模式,为热点页建立哈希索引,来提高查询效率。InnoDB存储引擎会监控对表上各个索引页的查询,如果观察到建立哈希索引可以带来速度上的提升,则建立哈希索引,所以叫做自适应哈希索引。

自适应哈希索引是通过缓冲池的B+树页构建而来,因此建立速度很快,而且不需要对整张数据表建立哈希索引。其有一个要求,即对这个页的连续访问模式必须是一样的,也就是说其查询的条件(WHERE)必须完全一样,而且必须是连续的。

锁信息(lock info)

我们都知道,InnoDB存储引擎会在行级别上对表数据进行上锁。不过InnoDB也会在数据库内部其他很多地方使用锁,从而允许对多种不同资源提供并发访问。数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。关于锁的具体知识我们之后再进行详细学习。

数据字典信息(Data Dictionary)

InnoDB有自己的表缓存,可以称为表定义缓存或者数据字典。当InnoDB打开一张表,就增加一个对应的对象到数据字典。

数据字典是对数据库中的数据、库对象、表对象等的元信息的集合。在MySQL中,数据字典信息内容就包括表结构、数据库名或表名、字段的数据类型、视图、索引、表字段信息、存储过程、触发器等内容。MySQL INFORMATION_SCHEMA库提供了对数据局元数据、统计信息、以及有关MySQL server的访问信息(例如:数据库名或表名,字段的数据类型和访问权限等)。该库中保存的信息也可以称为MySQL的数据字典。

后记

本篇文章只是简单的介绍一下InnoDB内存相关的概念和原理,如果大家想要了解更多关于InnoDB的知识,请关注我的微信公众号。

个人博客:Carpediem​remcarpediem.net

参考《MySQL技术内幕InnoDB存储引擎》

《高性能MySQL》

姜承晓老师的InnoDB架构图

mysql 额外内存池_MySQL探秘(三):InnoDB的内存结构和特性相关推荐

  1. MySQL探秘(三):InnoDB的内存结构和特性(可靠性和持久性)

     MySQL区别于其他数据库的最为重要的特点就是其插件式的表存储引擎.而在众多存储引擎中,InnoDB是最为常用的存储引擎.从MySQL5.5.8版本开始,InnoDB存储引擎是默认的存储引擎.  I ...

  2. mysql取消mvvc机制_MySQL探秘(六):InnoDB一致性非锁定读

    一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(MVVC)读取当前数据库中行数据的方式.如果读取的行正在执行DELETE或UPDATE操作 ...

  3. mysql+一致性非锁定读_MySQL探秘(六):InnoDB一致性非锁定读

    一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(MVVC)读取当前数据库中行数据的方式.如果读取的行正在执行DELETE或UPDATE操作 ...

  4. 内存池组件以及根据nginx内存池源码设计实现简易内存池

    目录 造轮子内存池原因引入 大量的malloc/free小内存所带来的弊端 弊端 出现场景 大牛解决措施(nginx内存池) 内存池技术 啥叫作内存池技术 内存池技术为啥可以解决上文弊端 高并发内存池 ...

  5. linux boost内存池,开源C++函数库Boost内存池使用与测试

    [IT168 专稿]Boost库是一个可移植的开源C++函数库,鉴于STL(标准模板库)已经成为C++语言的一个组成部分,可以毫不夸张的说,Boost是目前影响最大的通用C++库.Boost库由C++ ...

  6. mysql 开启引擎命令_MySql中启用InnoDB数据引擎的方法

    1.存储引擎是什么? Mysql中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.通过选择不同的技术, ...

  7. MySQL内存预估_mysql时该如何估算内存的消耗,公式如何计算?

    经常有人问配置mysql时该如何估算内存的消耗.那么该使用什么公式来计算呢? 关心内存怎么使用的原因是可以理解的.如果配置mysql服务器使用太少的内存会导致性能不是最优的;如果配置了太多的内存则会导 ...

  8. java内存池实现_Netty精粹之轻量级内存池技术实现原理与应用

    在Netty中,通常会有多个IO线程独立工作,基于NioEventLoop的实现,每个IO线程负责轮询单独的Selector实例来检索IO事件,当IO事件来临的时候,IO线程开始处理IO事件.最常见的 ...

  9. linux boost内存池,C++ boost库教程之内存池

    Boost  Pool 库提供了一个内存池分配器,它是一个工具,用于管理在一个独立的.大的分配空间里的动 态内存.当你需要分配和回收许多不的对象或需要更高效的内存控制时,使用内存池是一个好的 解决方案 ...

最新文章

  1. 黄山学院计算机课,黄山学院非计算机类专业计算机课程教学管理规定
  2. 经典论文复现 | 基于标注策略的实体和关系联合抽取
  3. php如何判断二维数组为空,PHP判断数组为空的具体方式
  4. 复制vmware overLay网络无法ping通 ping www.baidu.com可以
  5. 为什么金融分析需要应用python语言_python入门第一篇:python语言简介
  6. Linux CentOS7 下安装 TeamViewer
  7. mysql怎么查找删除重复数据_Mysql中如何查找并删除重复数据
  8. Oracle ORA-01033: ORACLE initialization or shutdown in progress 错误解决办法Windows版(手贱强制重启电脑的后果)...
  9. JavaScript判断日期时间差的实例代码
  10. java求导数_java实现队列链表,求一元多项式的导数
  11. iOS开发-XIB、Storyboard操作小技巧
  12. Java Server Faces_用JavaServer Faces开发Web应用(4) (转)
  13. Domino V12 Beta新玩法
  14. 论文阅读KMN:Kernelized Memory Network for Video Object Segmentation
  15. mac 小程序开发者工具。 tunneling socket could not be established
  16. Entering emergency mode. Exit the shell to continue
  17. split-horizon产生的路由欺骗
  18. MS VS+HIK海康机器人工业相机环境配置
  19. 刷脸支付将呈现爆发式增长!中国将全面进入刷脸支付新时代!
  20. 央视:乐视网是创业失败还是涉嫌欺诈?

热门文章

  1. Vhost dataplane in Qemu | PDF
  2. 数据平面开发套件(DPDK)中的Vhost / Virtio的配置和性能
  3. w7如何调出计算机图标来,W7电脑系统怎么显示桌面图标
  4. Django模板层:DTL模板渲染-变量
  5. Python String:一文彻底粉碎字符串
  6. win10专业版 提供管理员权限才能删除文件夹
  7. 几种软件滤波算法的原理和比较(带源码)
  8. java html写入到word文档_java 使用jacob将html页面写入word
  9. mysql数据库主从不同步_mysql数据库主从不同步的解决方法
  10. excel python自动化_excel表自动化-python