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的机制刷新回磁盘。

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

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

 在架构图上可以看到,InnoDB存储引擎的内存区域除了有缓冲池之外,还有重做日志缓冲和额外内存池。InnoDB存储引擎首先将重做日志信息先放到这个缓冲区中,然后按照一定频率将其刷新到重做日志文件中。重做日志缓冲一般不需要设置的很大,该值可由配置参数innodb_log_buffer_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。在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是 1. 通过memcpy函数将脏页先复制到内存中的该区域(doublewrite buffer),1.1 之后通过doublewrite buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上(doublewrite),然后马上调用fsync函数,同步磁盘,避免操作系统缓冲写带来的问题(map技术的过程)2. 在完成doublewrite页的写入后,再讲doublewirite buffer中的页写入各个表空间文件中。

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

重做日志(Redo Log Buffer)

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

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

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

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

 可以通过innodb_flush_log_at_trx_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的数据字典。

参考

  • 1.《MySQL技术内幕InnoDB存储引擎》

  • 2.《高性能MySQL》

  • 3. 姜承晓老师的InnoDB架构图

MySQL探秘(三):InnoDB的内存结构和特性(可靠性和持久性)相关推荐

  1. mysql 额外内存池_MySQL探秘(三):InnoDB的内存结构和特性

    常言说得好,每个成功男人背后都有一个为他默默付出的女人,而对于MySQL来说,这个"人"就是InnoDB存储引擎. MySQL区别于其他数据库的最为重要的特点就是其插件式的表存储引 ...

  2. MySQL探秘(四):InnoDB的磁盘文件及落盘机制(持久性)

    任何一个技术都有其底层的关键基础技术,这些关键技术很有可能也是其他技术的关键技术,学习这些底层技术,就可以一通百通,让你很快的掌握其他技术.如何在磁盘上存储数据,如何使用日志文件保证数据不丢失以及如何 ...

  3. MySQL(二)InnoDB的内存结构和特性

    目录 In-Memory Structures 缓冲池 Buffer Pool 更新缓冲Change Buffer Adaptive Hash Index (redo)Log Buffer 总结 磁盘 ...

  4. InnoDB的内存结构和特性

    常言说得好,每个成功男人背后都有一个为他默默付出的女人,而对于MySQL来说,这个"人"就是InnoDB存储引擎. MySQL区别于其他数据库的最为重要的特点就是其插件式的表存储引 ...

  5. MySQL探秘(七):InnoDB行锁算法

     在上一篇<InnoDB一致性非锁定读>中,我们了解到InnoDB使用一致性非锁定读来避免在一般的查询操作(SELECT FOR UPDATE等除外)时使用锁.然而锁这个事情是无法避免的, ...

  6. MySQL探秘(八):InnoDB的事务

     事务是数据库最为重要的机制之一,凡是使用过数据库的人,都了解数据库的事务机制,也对ACID四个基本特性如数家珍.但是聊起事务或者ACID的底层实现原理,往往言之不详,不明所以.所以,今天我们就一起来 ...

  7. mysql源码分析——InnoDB的内存结构源码

    一.说明 本来是想在前面的一篇分析中把源码和内容同时过一遍,可突然发现,那可能是非常大的一章.所以就把源码独立了出来,在此章节中对相关四类内存数据结构进行分析,在代码分析过程中,可以和前面的说明以及早 ...

  8. 你居然还不知道Mysql存储引擎InnoDB分为内存架构、磁盘架构?

    作者:陌北有棵树,Java人,架构师社区合伙人! 关于MySQL对于后端程序员的重要性不言而喻,而InnoDB也已经是MySQL默认的存储引擎.作为我们每天打交道的存储引擎,我们对它可能需要对它有更多 ...

  9. 【mysql】-【innodb数据存储结构】

    文章目录 数据库的存储结构:页 磁盘与内存交互基本单位:页 页结构概述 页的大小 页的上层结构 页的内部结构 File Header(文件头部)和File Trailer(文件尾部) File Hea ...

最新文章

  1. mysql 分库分表 ~ 方案选择浅谈
  2. C++异常处理(try和catch)
  3. 独家 | 大数据与AI技术在金融科技的应用
  4. modbus协议和串口服务器,Modbus RTU通信模式与Modbus ASCII通信模式的异同点
  5. POPUP_TO_DECIDE_WITH_MESSAGE
  6. 单源最短路 Dijkstra算法 和 SPFA算法
  7. LDC1000学习资料
  8. 天津大学计算机在线作业答案,天大19秋《计算机应用基础》在线作业二【满分答案】...
  9. ruby 生成随机字符串_Ruby程序生成随机数
  10. Yolo系列知识点梳理(Yolov1-v5)
  11. JS如何关闭当前浏览器窗口?
  12. 为什么我 11 岁的儿子说要放弃编程,却又转战 Python
  13. linux下NIS服务的配置
  14. matlab心理学函数包,心理学研究方法:基于MATLAB和PSYCHTOOLBOX
  15. Appscan漏洞之Authentication Bypass Using HTTP Verb Tampering
  16. oracle drop怎么用,Oracle Drop Table
  17. HANA XS Administration Tool登录参数设置
  18. win10+anaconda+pycharm python画图完整过程
  19. 2019年互联网公司月饼颜值大比拼!
  20. canvas实现3D魔方

热门文章

  1. 深入理解asp.net中的 __doPostBack函数
  2. C++学习基础八——重载输入和输出操作符
  3. 直接用img 的src属性显示base64转码后的字符串成图片【原】
  4. Java用JSONObject-lib来解析json串
  5. .Net 应用框架设计系列(二)
  6. [Python学习] 专题二.条件语句和循环语句的基础知识
  7. iOS之深入解析CocoaPods的GitLab CI与组件自动化构建与发布
  8. HarmonyOS之JS/Java跨语言调试
  9. iOS之深入探究CADisplayLink和NSTimer的对比和内存溢出问题
  10. 在OSI参考模型中,当两台计算机进行文件传输时,为防止中间出现网络故障而重传整个文件的情况,可通过在文件中插入同步点来解决,这个动作发生在( )