InnoDB存储引擎

这篇具有很好参考价值的文章主要介绍了InnoDB存储引擎。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

其实存储引擎也很简单,我认为就是一种存储解决方案,实现了新增数据、更新数据和建立索引等等功能。

有哪些已有的存储引擎可以让我们选择呢?

InnoDB、MyISAM、Memory、CSV、Archive、Blackhole、Merge、Federated、Example

种类很多,但是常用的存储引擎目前就只有InnoDB和MyISAM,下面将会介绍到InnoDB存储引擎。

InnoDB体系架构

InnoDB存储引擎,java,开发语言

InnoDB存储引擎有多个内存块,这些内存块组成了一个大的内存池。后台线程主要负责刷新内存池中的数据、将已修改的数据刷新到磁盘等等。接下来我们分别介绍后台线程和内存池。

后台线程

InnoDB后台有多个不同的线程,用来负责不同的任务。主要有如下:

  • Master Thread
    这是最核心的一个线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括赃页的刷新、合并插入缓冲、UNDO 页的回收等.
  • IO Thread
    在 InnoDB 存储引擎中大量使用了异步 IO 来处理写 IO 请求, IO Thread 的工作主要是负责这些 IO 请求的回调处理。
  • Purge Thread
    事务被提交之后, undo log 可能不再需要,因此需要 Purge Thread 来回收已经使用并分配的 undo页. InnoDB 支持多个 Purge Thread, 这样做可以加快 undo 页的回收。
  • Page Cleaner Thread
    Page Cleaner Thread 是在InnoDB 1.2.x版本新引入的,其作用是将之前版本中脏页的刷新操作都放入单独的线程中来完成,这样减轻了 Master Thread 的工作及对于用户查询线程的阻塞。

内存

InnoDB的内存架构主要分为三大块:

  • 缓冲池(Buffer Pool)
  • 重做缓冲池(Redo Log Buffer)
  • 额外内存池

缓冲池

InnoDB为了做数据的持久化,会将数据存储到磁盘上。但是面对大量的请求时,CPU的处理速度和磁盘的IO速度之间差距太大,为了提高整体的效率, InnoDB引入了缓冲池

当有请求来查询数据时,如果缓存池中没有,就会去磁盘中查找,将匹配到的数据放入缓存池中。同样的,如果有请求来修改数据,MySQL并不会直接去修改磁盘,而是会修改已经在缓冲池的页中的数据,然后再将数据刷回磁盘,这就是缓冲池的作用,加速读,加速写,减少与磁盘的IO交互。

缓冲池说白了就是把磁盘中的数据丢到内存,那既然是内存就会存在没有内存空间可以分配的情况。所以缓冲池采用了LRU算法,在缓冲池中没有空闲的页时,来进行页的淘汰。但是采用这种算法会带来一个问题叫做缓冲池污染

LUR算法

在 MySQL 中,LRU 指的是 Least Recently Used 缓存淘汰算法。该算法用于在缓存空间不足时,通过淘汰最近最少使用的数据来腾出空间,以便让新的数据进入缓存。

MySQL 中常用 LRU 算法来管理缓存,例如 InnoDB 存储引擎就使用了 LRU 算法来管理其缓冲池(Buffer Pool)。InnoDB 的缓冲池是一个内存区域,用于缓存数据库中的数据页,通过缓存页,可以避免频繁读取磁盘,从而提高数据库的性能。当需要获取一个数据页时,InnoDB 会首先在缓冲池中查找,如果找到了就直接返回,否则会从磁盘中读取并放入缓冲池中。

当缓冲池空间不足时,InnoDB 就需要根据 LRU 算法来淘汰一些数据页。具体来说,InnoDB 会维护一个“最近使用列表”(Recently Used List)和一个“最近未使用列表”(Recently Unused List),最近使用的数据页会被移到最前面,最近未使用的数据页则会移到后面。当需要淘汰数据页时,InnoDB 会选择最近未使用的数据页进行淘汰,以便让更常用的数据页留在缓冲池中,从而提高缓存命中率。

需要注意的是,LRU 算法是一种基于历史访问模式的淘汰算法,它假设未来的访问模式会和过去的访问模式相似,因此会尽可能地保留最近使用的数据。但是,在实际应用中,访问模式并不一定会保持不变,因此 LRU 算法也有其局限性。针对这个问题,还有其他缓存淘汰算法,如 MRU(Most Recently Used)、LFU(Least Frequently Used)等,可以根据具体场景来选择合适的算法。

缓冲池污染

缓冲池污染(Buffer Pool Contention)是数据库系统中的一个性能问题,指的是多个事务同时访问和争用缓冲池中的同一数据页,从而导致了事务之间的等待和竞争,以及数据库性能下降。缓冲池污染通常发生在高负载的数据库系统中,它可能会导致系统响应变慢,甚至服务不可用。

在一个并发访问的环境中,当多个事务同时需要访问或修改同一个数据页时,它们都需要先将该数据页读入到缓冲池中,再进行读取或修改操作。由于缓冲池的大小有限,当缓冲池中的数据页被占满后,新的事务需要等待已有事务归还缓冲池中的数据页才能继续执行,这就是缓冲池的竞争现象。

缓冲池污染的另一个原因是缓冲池管理算法的问题,常见的缓冲池管理算法包括最近最少使用(LRU)、先进先出(FIFO)等,它们都是基于一些策略来选择要从缓冲池中淘汰的数据页。如果选择的策略不够优秀,就会导致缓冲池中的热点数据页被频繁淘汰,从而影响系统性能。

当你在进行批量扫描甚至全表扫描时,可能会将缓冲池中的热点页全部替换出去。这样以来可能会导致MySQL的性能断崖式下降。所以InnoDB对LRU做了一些优化,规避了这个问题。

MySQL采用日志先行,在真正写数据之前,会首先记录一个日志,叫Redo Log,会定期的使用CheckPoint技术将新的Redo Log刷入磁盘,这个后面会讲。

除了数据之外,里面还存储了索引页、Undo页、插入缓冲、自适应哈希索引、InnoDB锁信息和数据字典。下面选几个比较重要的来简单聊一聊。

InnoDB存储引擎,java,开发语言

插入缓存

插入缓冲针对的操作是更新或者插入,我们考虑最坏的情况,那就是需要更新的数据都不在缓冲池中。那么此时会有下面两种方案。

  1. 来一条数据就直接写入磁盘
  2. 等数据达到某个阈值(例如50条)才批量的写入磁盘

很明显,第二种方案要好一点,减少了与磁盘IO的交互。

两次写

鉴于都聊到了插入缓冲,我就不得不需要提一嘴两次写,因为我认为这两个InnoDB的特性是相辅相成的。

插入缓冲提高了MySQL的性能,而两次写则在此基础上提高了数据的可靠性。我们知道,当数据还在缓冲池中的时候,当机器宕机了,发生了写失效,有Redo Log来进行恢复。但是如果是在从缓冲池中将数据刷回磁盘的时候宕机了呢?

这种情况叫做部分写失效,此时重做日志就无法解决问题。

InnoDB存储引擎,java,开发语言

在刷脏页时,并不是直接刷入磁盘,而是copy到内存中的Doublewrite Buffer中,然后再拷贝至磁盘共享表空间(你可以就理解为磁盘)中,每次写入1M,等copy完成后,再将Doublewrite Buffer中的页写入磁盘文件。

有了两次写机制,即使在刷脏页时宕机了,在实例恢复的时候也可以从共享表空间中找到Doublewrite Buffer的页副本,直接将其覆盖原来的数据页即可。

自适应哈希索引

自适应索引就跟JVM在运行过程中,会动态的把某些热点代码编译成Machine Code一样,InnoDB会监控对所有索引的查询,对热点访问的页建立哈希索引,以此来提升访问速度。

异步IO(AIO)

为了提高磁盘操作性能,当前的数据库系统都采用异步IO的方式来处理磁盘操作。InnoDB也是如此。

与AIO对应的是Sync IO,即每进行一次IO操作,需要等待此次操作结束才能继续接下来的操作。但是如果用户发出的是一条索引扫描的查询,那么这条SQL语句可能需要扫描多个索引页,也就是需要进行多次IO操作。在每扫描一个页并等待其完成再进行下一次扫描,这是没有必要的。用户可以在发出一个IO请求后立即再发出另外一个IO请求,当全部IO请求发送完毕后,等待所有IO操作完成,这就是AIO。

AIO的另外一个优势是进行IO Merge操作,也就是将多个IO合并为一个IO操作,这样可以提高IOPS的性能。

在InnoDB 1.1.x之前,AIO的实现是通过InnoDB存储引擎中的代码来模拟的。但是从这之后,提供了内核级别的AIO的支持,称为Native AIO。Native AIO需要操作系统提供支持。Windows和Linux都支持,而Mac则未提供。在选择MySQL数据库服务器的操作系统时,需要考虑这方面的因素。

MySQL可以通过参数innodb_use_native_aio来决定是否启用Native AIO。在InnoDB存储引擎中,read ahead方式的读取都是通过AIO完成,脏页的刷新,也是通过AIO完成。

刷新邻接页

InnoDB存储引擎在刷新一个脏页时,会检测该页所在区(extent)的所有页,如果是脏页,那么一起刷新。这样做的好处是通过AIO可以将多个IO写操作合并为一个IO操作。该工作机制在传统机械磁盘下有显著优势。但是需要考虑下吧两个问题:

是不是将不怎么脏的页进行写入,而该页之后又会很快变成脏页?
固态硬盘有很高IOPS,是否还需要这个特性?
为此InnoDB存储引擎1.2.x版本开始提供参数innodb_flush_neighbors来决定是否启用。对于传统机械硬盘建议使用,而对于固态硬盘可以关闭。

重做缓冲池

上面聊过,InnoDB中缓冲池中的页数据更新会先于磁盘数据更新的,InnoDB也会采用日志先行(Write Ahead Log)策略来刷新数据,什么意思呢?当事务开始时,会先记录Redo Log到Redo Log Buffer中,然后再更新缓冲池页数据。

Redo Log Buffer中的数据会按照一定的频率写到重做日志中去。被更改过的页就会被标记成脏页,InnoDB会根据CheckPoint机制来将脏页刷到磁盘。

Redo Log 日志详解

额外缓冲池

InnoDB在对一些数据结构本身的内存分配时,需要从额外的内存池中进行申请。例如缓冲池中的中的一些对象记录了锁、等待、LUR等消息,这些对象需要从额外的内存池中申请内存。

ChectPoint技术

说完缓冲池,下面说CheckPoint技术。
CheckPoint技术是用来解决如下几个问题:

  • 缩短数据库恢复时间
  • 缓冲池不够用时,将脏页刷新到磁盘
  • 重做日志不可用时,刷新脏页

缩短数据库恢复时间

缩短数据库恢复时间,重做日志中记录了的checkpoint的位置,这个点之前的页已经刷新回磁盘,只需要对checkpoint之后的重做日志进行恢复。这样就大大缩短了恢复时间。

缓冲池不够用

缓冲池不够用时,根据LRU算法,溢出最近最少使用的页,如果页为脏页,强制执行checkpoint,将脏页刷新回磁盘。

重做日志不可用

重做日志不可用,是指重做日志的这部分不可以被覆盖,为什么?因为:由于重做日志的设计是循环使用的。这部分对应的数据还未刷新到磁盘上。数据库恢复时,如果不需要这部分日志,即可被覆盖;如果需要,必须强制执行checkpoint,将缓冲池中的页至少刷新到当前重做日志的位置。

checkpoint每次刷新多少页到磁盘?每次从哪里取脏页?什么时间触发checkpoint?

InnoDB存储引擎内部,两种checkpoint,分别为:

  • Sharp Checkpoint
  • Fuzzy Checkpoint

Sharp Checkpoint

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

Fuzzy Checkpoint

在数据库运行时,InnoDB存储引擎内部采用Fuzzy Checkpoint,只刷新一部分脏页。

几种发生Fuzzy Checkpoint的情况:
①MasterThread Checkpoint
异步刷新,每秒或每10秒从缓冲池脏页列表刷新一定比例的页回磁盘。异步刷新,即此时InnoDB存储引擎可以进行其他操作,用户查询线程不会受阻。
②FLUSH_LRU_LIST Checkpoint
InnoDB存储引擎需要保证LRU列表中差不多有100个空闲页可供使用。在InnoDB 1.1.x版本之前,用户查询线程会检查LRU列表是否有足够的空间操作。如果没有,根据LRU算法,溢出LRU列表尾端的页,如果这些页有脏页,需要进行checkpoint。因此叫:flush_lru_list checkpoint。
InnoDB 1.2.x开始,这个检查放在了单独的进程(Page Cleaner)中进行。好处:1.减少master Thread的压力 2.减轻用户线程阻塞。
设置参数:innodb_lru_scan_dept:控制LRU列表中可用页的数量,该值默认1024
③Async/Sync Flush Checkpoint
指重做日志不可用的情况,需要强制刷新页回磁盘,此时的页时脏页列表选取的。
这种情况是保证重做日志的可用性,说白了就是,重做日志中可以循环覆盖的部分空间太少了,换种说法,就是极短时间内产生了大量的redo log。
接下来会有几个变量,图解也不难,仔细看看。
InnoDB存储引擎,通过LSN(Log Sequence Number)来标记版本,LSN是8字节的数字。每个页有LSN,重做日志有LSN,checkpoint有LSN。
写入日志的LSN:redo_lsn
刷新回磁盘的最新页LSN:checkpoint_lsn
有如下定义:
checkpoint_age = redo_lsn - checkpoint_lsn
async_water_mark = 75% * total_redo_file_size
sync_water_mark = 90% * total_redo_file_size
刷新过程如下图所示:

InnoDB存储引擎,java,开发语言

④Dirty Page too much Checkpoint
即脏页太多,强制checkpoint.保证缓冲池有足够可用的页。
参数设置:innodb_max_dirty_pages_pct = 75 表示:当缓冲池中脏页的数量占75%时,强制checkpoint。1.0.x之后默认75文章来源地址https://www.toymoban.com/news/detail-715077.html

到了这里,关于InnoDB存储引擎的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL 的 InnoDB 存储引擎简介

    MySQL 是世界上最流行的开源关系型数据库管理系统之一,而其中的存储引擎则是其关键组成部分之一。InnoDB 存储引擎在 MySQL 中扮演了重要角色,提供了许多高级功能和性能优化,适用于各种应用程序和工作负载。本文将深入介绍 InnoDB 存储引擎的各个方面,以帮助您更好地理

    2024年02月08日
    浏览(42)
  • MySQL高级10-InnoDB引擎存储架构

    表空间(Tablespace):一个mysql实例,及一个数据库实例,可以对应多个表空间(ibd文件),用于存储记录,索引等数据。 段(Segment):分为数据段(Leaf node segment)、索引段(Non-leaf node segment)、回滚段(Rollback segment),InnoDB是索引组织表,数据段就是B+树的叶子节点(Leaf node segment),

    2024年02月08日
    浏览(42)
  • mysql--InnoDB存储引擎--架构和事务

    MySQL进阶篇 InnoDB 逻辑存储单元主层级关系图: 1、表空间 表空间是InnoDB存储引擎逻辑结构的最高层, 如果用户启用了参数 innodb_file_per_table(在 8.0版本中默认开启) ,则每张表都会有一个表空间(xxx.ibd),一个mysql实例可以对应多个表空间,用于存储记录、索引等数据。 2、段

    2024年02月14日
    浏览(43)
  • 12. InnoDB引擎底层存储和缓存原理

    本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。 到目前为止,MySQL对于我们来说还是一个黑盒,我们只负责使用客户端发送请求并等待服务器返回结果,表中的数据到底存到了哪里?以什么格式存放的?MySQL是以什么方式来访问的这些

    2024年02月06日
    浏览(46)
  • 【MYSQL】存储引擎MyISAM和InnoDB

    查看MySQL提供所有的存储引擎 mysql show engines; mysql常用引擎包括:MYISAM、Innodb、Memory、MERGE 1、MYISAM:全表锁,拥有较高的执行速度,不支持事务,不支持外键,并发性能差,占用空间相对较小,对事务完整性没有要求,以select、insert为主的应用基本上可以使用这引擎 2、Innod

    2024年01月18日
    浏览(39)
  • MyISAM和InnoDB存储引擎的区别

    MyISAM和InnoDB是使用MySQL最常用的两种存储引擎, 在5.5版本之前默认采用MyISAM存储引擎,从5.5开始采用InnoDB存储引擎。 存储引擎是:数据库管理系统如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。 MySQL的核心就是插件式存储引擎, 支持多

    2024年01月21日
    浏览(51)
  • 【MySQL】 深入了解InnoDB存储引擎的限制

    目录 列数限制 索引数限制 InnoDB的行格式和索引限制 示例和注意事项 **页大小对索引键前缀长度的影响 **对全列索引键的限制 多列索引限制 行大小限制 InnoDB log限制 表空间大小限制 表数量限制 操作系统限制 文件大小和日志文件大小 文件层级限制 随着数据库技术的不断发

    2024年01月24日
    浏览(45)
  • MySQL—MySQL的存储引擎之InnoDB

    存储引擎 说明 MyISAM 高速引擎,拥有较高的插入,查询速度,但不支持事务 InnoDB 5.5版本后MySQL的默认数据库存储引擎,支持事务和行级锁,比MyISAM处理速度稍慢 ISAM MyISAM的前身,MySQL5.0以后不再默认安装 MRG_MyISAM 将多个表联合成一个表使用,在超大规模数据存储时很有用 Me

    2024年04月26日
    浏览(40)
  • MySQL 存储引擎 InnoDB 内存结构之缓冲池

    缓冲池是主存储器中的一个区域,在访问 table 和索引数据时 InnoDB 会对其进行缓存。缓冲池允许直接从内存中访问频繁使用的数据,从而加快处理速度。在专用服务器上,通常将高达 80% 的物理内存分配给缓冲池。 为了高效处理大量读取操作,缓冲池被划分为可以容纳多行

    2024年02月10日
    浏览(39)
  • MySQL存储引擎InnoDB和MyISAM的区别?

    InnoDB和MyISAM是MySQL数据库两种常见的存储引擎,它们在性能、事务支持等方面有一些重要的区别。以下是它们的一些主要区别: 事务支持: InnoDB: 支持事务,具有ACID(原子性、一致性、隔离性、持久性)特性,适用于需要事务支持的应用,如银行、电商等。 MyISAM: 不支持

    2024年02月03日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包