精华内容
下载资源
问答
  • innodb引擎4大特性

    2021-01-27 06:35:06
    该属性通过innodb_adapitve_hash_index开启,也可以通过—skip-innodb_adaptive_hash_index参数 关闭 Innodb存储引擎会监控对表上二级索引的查找,如果发现某二级索引被频繁访问,二级索引成为热数据,建立哈希索引...

    一:插入缓冲

    二:二次写

    三:自适应哈希

    四:预读

    1.插入缓冲(insert buffer)

    插入缓冲(Insert Buffer/Change Buffer):提升插入性能,change buffering是insert buffer的加强,insert buffer只针对insert有效,change buffering对insert、delete、update(delete+insert)、purge都有效

    只对于非聚集索引(非唯一)的插入和更新有效,对于每一次的插入不是写到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,如果在则直接插入;若不在,则先放到Insert Buffer 中,再按照一定的频率进行合并操作,再写回disk。这样通常能将多个插入合并到一个操作中,目的还是为了减少随机IO带来性能损耗。

    使用插入缓冲的条件:

    * 非聚集索引

    * 非唯一索引

    Change buffer是作为buffer pool中的一部分存在。Innodb_change_buffering参数缓存所对应的操作:(update会被认为是delete+insert)

    innodb_change_buffering,设置的值有:inserts、deletes、purges、changes(inserts和deletes)、all(默认)、none。

    all: 默认值,缓存insert, delete, purges操作

    none: 不缓存

    inserts: 缓存insert操作

    deletes: 缓存delete操作

    changes: 缓存insert和delete操作

    purges: 缓存后台执行的物理删除操作

    可以通过参数控制其使用的大小:

    innodb_change_buffer_max_size,默认是25%,即缓冲池的1/4。最大可设置为50%。当MySQL实例中有大量的修改操作时,要考虑增大innodb_change_buffer_max_size

    上面提过在一定频率下进行合并,那所谓的频率是什么条件?

    1)辅助索引页被读取到缓冲池中。正常的select先检查Insert Buffer是否有该非聚集索引页存在,若有则合并插入。

    2)辅助索引页没有可用空间。空间小于1/32页的大小,则会强制合并操作。

    3)Master Thread 每秒和每10秒的合并操作。

    2.二次写(double write)

    Doublewrite缓存是位于系统表空间的存储区域,用来缓存InnoDB的数据页从innodb buffer pool中flush之后并写入到数据文件之前,所以当操作系统或者数据库进程在数据页写磁盘的过程中崩溃,Innodb可以在doublewrite缓存中找到数据页的备份而用来执行crash恢复。数据页写入到doublewrite缓存的动作所需要的IO消耗要小于写入到数据文件的消耗,因为此写入操作会以一次大的连续块的方式写入

    在应用(apply)重做日志前,用户需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是double write

    doublewrite组成:

    内存中的doublewrite buffer,大小2M。

    物理磁盘上共享表空间中连续的128个页,即2个区(extend),大小同样为2M。

    对缓冲池的脏页进行刷新时,不是直接写磁盘,而是会通过memcpy()函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite 再分两次,每次1M顺序地写入共享表空间的物理磁盘上,在这个过程中,因为doublewrite页是连续的,因此这个过程是顺序写的,开销并不是很大。在完成doublewrite页的写入后,再将doublewrite buffer 中的页写入各个 表空间文件中,此时的写入则是离散的。如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,innodb可以从共享表空间中的doublewrite中找到该页的一个副本,将其复制到表空间文件,再应用重做日志。

    51ea611535ba703dd900b4688f90a4d7.png

    3.自适应哈希索引(ahi)

    Adaptive Hash index属性使得InnoDB更像是内存数据库。该属性通过innodb_adapitve_hash_index开启,也可以通过—skip-innodb_adaptive_hash_index参数

    关闭

    Innodb存储引擎会监控对表上二级索引的查找,如果发现某二级索引被频繁访问,二级索引成为热数据,建立哈希索引可以带来速度的提升

    经常访问的二级索引数据会自动被生成到hash索引里面去(最近连续被访问三次的数据),自适应哈希索引通过缓冲池的B+树构造而来,因此建立的速度很快。

    哈希(hash)是一种非常快的等值查找方法,在一般情况下这种查找的时间复杂度为O(1),即一般仅需要一次查找就能定位数据。而B+树的查找次数,取决于B+树的高度,在生产环境中,B+树的高度一般3-4层,故需要3-4次的查询。

    innodb会监控对表上个索引页的查询。如果观察到建立哈希索引可以带来速度提升,则自动建立哈希索引,称之为自适应哈希索引(Adaptive Hash Index,AHI)。

    AHI有一个要求,就是对这个页的连续访问模式必须是一样的。

    例如对于(a,b)访问模式情况:

    where a = xxx

    where a = xxx and b = xxx

    特点

    1、无序,没有树高

    2、降低对二级索引树的频繁访问资源,索引树高<=4,访问索引:访问树、根节点、叶子节点

    3、自适应

    3、缺陷

    1、hash自适应索引会占用innodb buffer pool;

    2、自适应hash索引只适合搜索等值的查询,如select * from table where index_col='xxx',而对于其他查找类型,如范围查找,是不能使用的;

    3、极端情况下,自适应hash索引才有比较大的意义,可以降低逻辑读。

    4.预读(read ahead)

    InnoDB使用两种预读算法来提高I/O性能:线性预读(linear read-ahead)和随机预读(randomread-ahead)

    为了区分这两种预读的方式,我们可以把线性预读放到以extent为单位,而随机预读放到以extent中的page为单位。线性预读着眼于将下一个extent提前读取到buffer pool中,而随机预读着眼于将当前extent中的剩余的page提前读取到buffer pool中。

    线性预读(linear read-ahead)

    方式有一个很重要的变量控制是否将下一个extent预读到buffer pool中,通过使用配置参数innodb_read_ahead_threshold,可以控制Innodb执行预读操作的时间。如果一个extent中的被顺序读取的page超过或者等于该参数变量时,Innodb将会异步的将下一个extent读取到buffer pool中,innodb_read_ahead_threshold可以设置为0-64的任何值,默认值为56,值越高,访问模式检查越严格

    例如,如果将值设置为48,则InnoDB只有在顺序访问当前extent中的48个pages时才触发线性预读请求,将下一个extent读到内存中。如果值为8,InnoDB触发异步预读,即使程序段中只有8页被顺序访问。你可以在MySQL配置文件中设置此参数的值,或者使用SET GLOBAL需要该SUPER权限的命令动态更改该参数。

    在没有该变量之前,当访问到extent的最后一个page的时候,Innodb会决定是否将下一个extent放入到buffer pool中。

    随机预读(randomread-ahead)

    随机预读方式则是表示当同一个extent中的一些page在buffer pool中发现时,Innodb会将该extent中的剩余page一并读到buffer pool中,由于随机预读方式给Innodb code带来了一些不必要的复杂性,同时在性能也存在不稳定性,在5.5中已经将这种预读方式废弃。要启用此功能,请将配置变量设置innodb_random_read_ahead为ON。

    展开全文
  • MySQL之Innodb引擎4大特性

    千次阅读 2021-03-30 15:17:05
    MySQL之Innodb引擎4大特性 原创 anselzhang DBA修炼之路 5天前 面试官:你了解MySQL的Inodb四大特性吗? 1.插入缓冲 (Insert Buffer/Change Buffer) 插入缓存之前版本叫insert buffer,现版本 change buffer,...

    面试官:你了解MySQL的Inodb四大特性吗?
    在这里插入图片描述

    1.插入缓冲 (Insert Buffer/Change Buffer)
    插入缓存之前版本叫insert buffer,现版本 change buffer,主要提升插入性能,change buffer是insert buffer的加强,insert buffer只针对insert有效,change buffering对insert、delete、update(delete+insert)、purge都有效。有什么用呢?

    对于非聚集索引来说,比如存在用户购买金额这样一个字段,索引是普通索引,每个用户的购买的金额不相同的概率比较大,这样导致可能出现购买记录在数据在数据里的排序可能是1000,3,499,35…,这种不连续的数据,一会插入这个数据页,一会插入那个数据页,这样造成的IO是很耗时的,所以出现了Insert Buffer。

    Insert Buffer是怎么做的呢?mysql对于非聚集索引的插入,先去判断要插入的索引页是否已经在内存中了,如果不在,暂时不着急先把索引页加载到内存中,而是把它放到了一个Insert Buffer对象中,临时先放在这,然后等待情况,等待很多和现在情况一样的非聚集索引,再和要插入的非聚集索引页合并,比如说现在Insert Buffer中有1,99,2,100,合并之前可能要4次插入,合并之后1,2可能是一个页的,99,100可能是一个页的,这样就减少到了2次插入。这样就提升了效率和插入性能,减少了随机IO带来性能损耗。
    在这里插入图片描述
    综合上述,Insert Buffer 只对于非聚集索引(非唯一)的插入和更新有效,对于每一次的插入不是写到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,如果在则直接插入;若不在,则先放到Insert Buffer 中,再按照一定的频率进行合并操作,再写回disk。这样通常能将多个插入合并到一个操作中,目的还是减少了随机IO带来性能损耗。

    使用插入缓冲的条件:

    • 非聚集索引
    • 非唯一索引

    innodb_change_buffer设置的值有:

    all: 默认值,缓存insert, delete, purges操作
    none: 不缓存
    inserts: 缓存insert操作
    deletes: 缓存delete操作
    changes: 缓存insert和delete操作
    purges: 缓存后台执行的物理删除操作
    

    可以通过参数控制其使用的大小:

    mysql> show variables like 'innodb_change_buffer_max_size';
    +-------------------------------+-------+
    | Variable_name                 | Value |
    +-------------------------------+-------+
    | innodb_change_buffer_max_size | 25    |
    +-------------------------------+-------+
    1 row in set (0.05 sec)
    

    innodb_change_buffer_max_size,默认是25%,即缓冲池的1/4。最大可设置为50%。当MySQL实例中有大量的修改操作时,要考虑增大innodb_change_buffer_max_size

    上面提过在一定频率下进行合并,那所谓的频率是什么条件?
    1)辅助索引页被读取到缓冲池中。正常的select先检查Insert Buffer是否有该非聚集索引页存在,若有则合并插入。

    2)辅助索引页没有可用空间。空间小于1/32页的大小,则会强制合并操作。

    3)Master Thread 每秒和每10秒的合并操作。

    2.双写机制(Double Write)
    在InnoDB将BP中的Dirty Page刷(flush)到磁盘上时,首先会将(memcpy函数)Page刷到InnoDB tablespace的一个区域中,我们称该区域为Double write Buffer(大小为2MB,每次写入1MB,128个页,每个页16k,其中120个页为后台线程的批量刷Dirty Page,还有8个也是为了前台起的sigle Page Flash线程,用户可以主动请求,并且能迅速的提供空余的空间)。在向Double write Buffer写入成功后,第二步、再将数据分别刷到一个共享空间和真正应该存在的位置。

    MySQL可以根据redolog进行恢复,而mysq在恢复的过程中是检查page"的checksum, checksum就是pgae的最后事务号,发生partial page write问题时. DageR经损坏,找不到该page中的事务号就无法恢复。

    具体的流程如下图所示:
    在这里插入图片描述

    在不同的写入阶段,操作系统crash后,double write带来的保护机制:

    在这里插入图片描述

    阶段一:copy过程中,操作系统crash,重启之后,脏页未刷到磁盘,但更早的数据并没有发生损坏,重新写入即可

    阶段二:write到共享表空间过程中,操作系统crash,重启之后,脏页未刷到磁盘,但更早的数据并没有发生损坏,重新写入即可

    阶段三:write到独立表空间过程中,操作系统crash,重启之后,发现:
    (1)数据文件内的页损坏:头尾checksum值不匹配(即出现了partial page write的问题)。从共享表空间中的doublewrite segment内恢复该页的一个副本到数据文件,再应用redo log;
    (2)若页自身的checksum匹配,但与doublewrite segment中对应页的checksum不匹配,则统一可以通过apply redo log来恢复。

    阶段X:recover过程中,操作系统crash,重启之后,innodb面对的情况同阶段三一样(数据文件损坏,但共享表空间内有副本),再次应用redo log即可。

    3.自适应哈希索引(Adaptive Hash Index,AHI)
    哈希算法是一种非常快的查找方法,在一般情况(没有发生hash冲突)下这种查找的时间复杂度为O(1)。InnoDB存储引擎会监控对表上辅助索引页的查询。如果观察到建立hash索引可以提升性能,就会在缓冲池建立hash索引,称之为自适应哈希索引(Adaptive Hash Index,AHI)。
    在这里插入图片描述

    自适应哈希索引由innodb_adaptive_hash_index 变量启用,AHI是通过缓冲池的B+ Tree构造而来,使用索引键的前缀来构建哈希索引,前缀可以是任意长度。InnoDB存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立hash索引。加快索引读取的效果,相当于索引的索引,帮助InnoDB快速读取索引页。

    根据InnoDB官方文档说明,启用了AHI后,读写的速度会提升2倍,辅助索引的连接操作性能可以提高5倍。

    查看AHI的工作状态:

    show engine innodb status;
    

    在这里插入图片描述

    Hash table size:代表AHI的大小;
    hash searches/s:代表命中hash查询的频率;
    non-hash searches/s:代表没有命中hash查询的频率;
    

    注意:hash查询是等值查询,例如模糊查询、范围查找,是不能使用hash索引的。用户可以根据实际场景去权衡是否要开启AHI。

    4.预读 (Read Ahead)
    预读(read-ahead)操作是一种IO操作,用于异步将磁盘的页读取到buffer pool中,预料这些页会马上被读取到。预读请求的所有页集中在一个范围内。InnoDB使用两种预读算法:

    1. Linear read-ahead:线性预读技术预测在buffer pool中被访问到的数据它临近的页也会很快被访问到。能够通过调整被连续访问的页的数量来控制InnoDB的预读操作,使用参数 innodb_read_ahead_threshold配置,添加这个参数前,InnoDB会在读取到当前区段最后一页时才会发起异步预读请求

    innodb_read_ahead_threshold 这个参数控制InnoDB在检测顺序页面访问模式时的灵敏度。如果在一个区块顺序读取的页数大于或者等于 innodb_read_ahead_threshold 这个参数,InnoDB启动预读操作来读取下一个区块。innodb_read_ahead_threshold参数值的范围是 0-64,默认值为56. 这个值越高则访问默认越严格。比如,如果设置为48,在当前区块中当有48个页被顺序访问时,InnoDB就会启动异步的预读操作,如果设置为8,则仅仅有8个页被顺序访问就会启动异步预读操作。你可以在MySQL配置文件中设置这个值,或者通过SET GLOBAL 语句动态修改(需要有set global 权限)。

    1. Random read-ahead: 随机预读通过buffer pool中存中的来预测哪些页可能很快会被访问,而不考虑这些页的读取顺序。如果发现buffer pool中存中一个区段的13个连续的页,InnoDB会异步发起预读请求这个区段剩余的页。通过设置 innodb_random_read_ahead 为 ON开启随机预读特性。

    通过 SHOW INNODB ENGINE STATUS 命令输出的统计信息可以帮助你评估预读算法的效果,统计信息包含了下面几个值:

    innodb_buffer_pool_read_ahead   通过预读异步读取到buffer pool的页数
    innodb_buffer_pool_read_ahead_evicted 预读的页没被使用就被驱逐出buffer pool的页数,这个值与上面预读的页数的比值可以反应出预读算法的优劣。
    innodb_buffer_pool_read_ahead_rnd  由InnoDB触发的随机预读次数。
    

    更多精彩内容,欢迎关注微信公众号
    在这里插入图片描述

    展开全文
  • InnoDB 引擎大特性

    2021-05-21 11:14:09
    InnoDB 引擎大特性双写缓冲区(DoubleWrite Buffer)原理为什么要用双写缓冲区?AHI 自适应哈希Buffer Pool 双写缓冲区(DoubleWrite Buffer) 原理 双写缓冲区是 InnoDB 引擎为了保证数据安全性,完整性而开发的 ...

    双写缓冲区(DoubleWrite Buffer)

    原理

    在这里插入图片描述

    双写缓冲区是 InnoDB 引擎为了保证数据安全性,完整性而开发的

    双写缓冲区是在系统表空间中

    InnoDB 引擎会在磁盘上划分出连续的两个区的范围

    1个区包含64个页,一个页 16k,1个区 = 64x16 = 1024k = 1M

    因此一个双写缓冲区大小为两个 1M ,共 2M

    当我们写数据时,InnoDB 会先把数据从内存的双写缓冲区中,接着调用 fsync 写入到磁盘的双写缓冲区上(完整页数据),最后再把数据写入对应数据页中

    如果在写页的过程中发生意外崩溃,InnoDB 在稍后的恢复过程中在双写缓冲区中找到完好的 page 副本用于恢复

    为什么要用双写缓冲区?

    问题:双写缓冲区要写磁盘,数据之后也是要写磁盘,为什么还要提前写个双写缓冲区?这样不是增加IO?

    答:首先一页数据是 16 kb,磁盘写一次是 4kb,因此一页数据写磁盘,要写 4 次。
    假如在写的过程中假如写了 8kb 数据库崩了,就会导致部分页写入问题,页的数据不完整,数据就会有问题。而双写缓冲区作为一块预分配的磁盘位置,数据库在写磁盘双写缓冲区时是使用的顺序写,因此效率上要比直接写数据的随机写快的多,出问题的概率小

    问题:fsync 是什么?

    答:fsync 是底层操作系统对外提供的一个 API 接口,他能保证数据必然已经落盘。

    问题:假如数据库突然挂了,双写缓冲区是如何恢复数据的?

    答:双写缓冲区存在的目的就是 Innodb 为了保证 MySQL 数据的原子性。假如数据库数据写一半挂了,那么 MySQL 启动时,会从磁盘的双写缓冲区中找到直接写入的完整的数据副本,再用这个完整的副本去对有问题的页数据进行恢复

    问题:假如写双写缓冲区挂了呢?

    答:既然 MySQL 的双写缓冲区是双写机制,第一步写到磁盘的双写缓冲区自然有可能失败。假如失败了,MySQL 会根据磁盘上 B+ 树的结构,再配合上 Redo 日志对数据进行恢复

    问题:既然可以通过 Redo 日志进行恢复,那么为什么还要双写缓冲区?

    答:MySQL 的 Redo 日志存储的是对页的物理操作,也就是修改部分的操作,非修改部分的数据不保存。也就说假如我修改了 Table 表的 Name 字段,那么 Redo 日志会记载 Name 字段在物理层的偏移量从而定位到 Name 字段的修改信息。但是我们写数据是一页一页的写的,一次必然要写 4KB,假如由于重启导致页数据损坏,正好损坏的不是 Name 字段的数据,而是这个页上其他的非修改数据。那么由于 Redo 日志是增量存储,上面值存储了修改操作的信息,而没有其他数据的信息,因此此时损坏页,Redo 日志就无法修复。而双写缓冲区则拥有全部数据就能修复。

    问题:双写缓冲区多一次写操作,对性能的影响大吗?

    答:不大,因为双写缓冲区的写操作是顺序写。经过测试,使用双写缓冲区与不使用相比,性能仅降低 5%-10%。

    问题:既然双写缓冲区写要是失败了,需要 Redo 日志进行恢复,那么假如写 Redo 日志失败了怎么办?

    答:不存在这种情况,因为每个事务在提交时都会将对应的 Redo 日志刷盘,只有 redo 日志刷盘成功了,事务才能算完成

    AHI 自适应哈希

    在这里插入图片描述

    自适应哈希索引是 Innodb 引擎自行研发的,用于提高 MySQL 的查询效率。

    在 InnoDB 存储引擎内部自己去监控索引表,如果监控到某个索引经常用,那么就认为是热数据,然后内部自己创建一个 hash 索引,称之为自适应哈希索引(Adaptive Hash Index,AHI)。

    创建以后,如果下次又查询到这个索引, 那么直接通过 hash 算法推导出记录的地址,直接一次就能查到数据,比重复去 B+tree 索引中查询三四次节点的效率高了不少。

    MySQL 在哈希索引的设计上还采用了热点分散技术,这样的哈希索引在 MySQL 上默认是启动 8 个的,热点数据会分散到不同的哈希索引上,因此热数据访问时,能将请求分散到不同的哈希索引上,提高了并发访问的性能。

    在这里插入图片描述

    Buffer Pool

    什么是 Buffer Pool?

    InnoDB 为了缓存磁盘中的页,在 MySQL 服务器启动的时候就向操作系统申请了一片连续的内存,他们给这片内存起了个名,叫做 Buffer Pool。

    默认情况下 Buffer Pool 只有 128M 大小(这个值其实是偏小的)。

    启动服务器的时候可以通过配置 innodb_buffer_pool_size 参数的值来控制 Buffer Pool 大小,

    Buffer Pool 内部组成

    Buffer Pool 中默认的缓存页大小和在磁盘上默认的页大小是一样的,都是 16KB。

    为了更好的管理这些在 Buffer Pool 中的缓存页,InnoDB 为每一个缓存页都创建了一些所谓的控制信息,这些控制信息包括该页所属的表空间编号、页号、 缓存页在 Buffer Pool 中的地址、链表节点信息、一些锁信息以及 LSN 信息,当然还有一些别的控制信息,我们称之为控制块

    PS:MySQL 大部分缓存的数据都在 Buffer Pool 中,缓存页就是数据,数据库查询出来的数据都会缓存到缓存页中,便于下次快速查询。控制块保存了缓存也的各种信息地址等,用来找缓存页
    在这里插入图片描述

    Buffer Pool 中的链表结构

    Free 链表

    Free 链表说简单些,就是将所有空闲的缓存页串起来,其实就是把空闲的缓存页对应的控制块的地址用一个链表来维护。这样下次有新数据进来,可以直接来 Free 链上直接找到空闲的缓存页。

    Free 链还会有一个块用于存储,链表头,链表尾,以及链表上的数量。
    在这里插入图片描述

    Flush 链

    在这里插入图片描述
    Flush 链的结构与 Free 链完全一样

    既然我们知道 Buffer Pool 缓存的是数据库中查询出来的数据,那么必然会存在一个问题,假如数据被修改了怎么办?

    因此 MySQL 把缓冲区上面这种被修改过的数据的控制块也用一个链表进行维护,以此来快速定位被修改过的数据,也被称为脏数据(未落盘的数据),因此 Flush 链又被称为脏链。

    PS:MySQL 数据提交后,并不是立刻落盘的,而是依然在缓冲区里,最后会统一落盘。既然数据提交了自然会有 Redo 日志,假如数据库挂了,数据也是能恢复的。

    既然是脏数据为什么不知道把数据删掉?

    答:MySQL 本身数据并不是立刻落盘的。Flush 链上的数据,MySQL 会有定时任务去定时落盘。其次虽然是叫脏数据,但是本质上这些数据就是用户提交的数据,只是没落盘而已,读取时候直接读取是没有问题的。

    LRU 链表

    在这里插入图片描述
    LRU 链表是一种最近最少使用淘汰链表,简单逻辑就是维护一个链表,假如这个数据使用了就提到链表头。假如链表满了,需要淘汰,就从链表尾淘汰。

    而 MySQL 对 LRU 链表做了自己的优化改进

    既然知道 MySQL 在缓冲区中缓存了查询的数据,但是查询的数据那么多,内存肯定放不下咋办?MySQL 就将数据用一个 LRU 链表进行维护,用来淘汰不常使用的数据,剩下的就是热门数据。

    MySQL 对 LRU 改进措施:

    1. 将 LRU 链表分为两部分,前面为热数据去(Young 区),后面为冷数据区(Old 区),Old 区大小占 37%。
      优点:冷热链的切分,排除了全表扫描等类似的大数据量查询,直接把热门数据淘汰出缓冲区的情况。
    2. 对冷链数据移动到热链上做了时间限定。限定时间内对冷链上数据的访问不会移动到热数据区,只有超过这个时间,再次访问冷链上的数据,才会被移动到热数据区。
      优点:避免了短时间内全表扫描等大数据量频繁刷新导致,热门数据被移出热链的情况。
    3. 热链的部分,并非每次访问都会向前移动。只有在热点的后 1/4 内的数据,在访问时才会移动到热链头部,减少移动带来的资源消耗,提升性能。

    参数:
    innodb_old_blocks_pct: 调整冷热区域占比占比,默认 37%。
    innodb_old_blocks_time: 调整限定间隔时间,默认 1S

    MySQL 刷新数据落盘的途径

    MySQL 后台会有个定时器,定时将数据进行统一落盘,以不影响用 户线程处理正常的请求。

    1. BUF_FLUSH_LIST:从 flush 链表中刷新一部分页面到磁盘,刷新的速率取决 于当时系统是不是很繁忙。
    2. BUF_FLUSH_LRU:从 LRU 链表的冷数据中刷新一部分页面到磁盘。后台线程会定时从 LRU 链表尾部开始扫描一些页面,扫描的页面数量可以通 过系统变量 innodb_lru_scan_depth 来指定,如果从里边儿发现脏页,会把它们 刷新到磁盘。
    3. BUF_FLUSH_SINGLE_PAGE: 有时候后台线程刷新脏页的进度比较慢,导致用户线程在准备加载一个磁盘页到 Buffer Pool 时没有可用的缓存页,这时就会尝试看看 LRU 链表尾部有没有可以直接释放掉的未修改页面,如果没有的话会不得不将 LRU 链表尾部的一个脏页同步刷新到磁盘(和磁盘交互是很慢的,这会降低处理用户请求的速度)。当然,有时候系统特别繁忙时,也可能出现用户线程批量的从 flush 链表中 刷新脏页的情况,很显然在处理用户请求过程中去刷新脏页是一种严重降低处理 速度的行为,这属于一种迫不得已的情况。

    InnoDB 的内存结构总结

    在这里插入图片描述

    展开全文
  • InnoDB的关键特性:插入缓冲(insert buffer)两次写(double write)自适应哈希索引(Adaptive Hash Index)异步IO(AIO)刷新临接页(Flush Neighbor Page)插入缓冲Insert BufferInnoDB存储引擎中,主键是行唯一的标识符,...

    InnoDB的关键特性:

    插入缓冲(insert buffer)

    两次写(double write)

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

    异步IO(AIO)

    刷新临接页(Flush Neighbor Page)

    插入缓冲

    Insert Buffer

    InnoDB存储引擎中,主键是行唯一的标识符,通常应用程序插入行记录是顺序的,所以插入聚集索引一般也是顺序的。

    表中的非聚集索引(辅助索引)在进行插入的时候,数据页的存放还按照主键进行顺序存放,但是对于非聚集索引叶子结点的插入就不在是顺序的,这时候需要离散的访问非聚集索引,由于随机读取的存在而导致了插入操作的性能下降。(在一般情况下辅助索引是比较顺序的)。

    InnoDB设计了Insert Buffer,对于非聚集索引的插入或者更新操作,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,如果在直接插入,如果不在,则先放入到一个Insert Buffer对象中。然后再以一定的频率和情况进行Insert Buffer和辅助索引叶子节点的Merge(合并)操作,通常能将多个插入缓冲合并到一个操作中(因为在一个索引页中),这就大大提高了非聚集索引插入的性能。

    使用Insert Buffer需要满足的条件:1.索引是辅助索引;2.索引不是unique索引

    Change Buffer

    1.0以后的版本引入了Change Buffer,对数据库DML操作(insert,update,delete)都进行缓冲。分别是Insert Buffer、Delete Buffer、Purge Buffer

    使用的满足要求依然是辅助索引且不唯一。

    对一条记录的Update操作分为两个过程:

    将记录标记为已删除

    真正的记录删除

    Merge Insert Buffer

    将insert buffer进行合并到真正的索引页的情况发生在如下:

    辅助索引页被读取到缓冲池中;

    Insert Buffer Bitmap页追踪到该辅助索引页已经没有可用空间;

    Master Thread执行

    两次写

    double write带给InnoDB存储引擎的是数据页的可靠性。

    double write由两部分组成,一部分是内存中的doublewrite buffer,另一部分是物理磁盘上共享表空间中连续128个页,即2个区。两者大小都为2MB。在对缓存池的脏页进行刷新的时候,并不是直接写入到磁盘,而是先将脏页复制到内存中的doublewrite buffer中,之后通过doublewrite buffer分两次,每次1MB顺序的写入共享表空间的物理磁盘上,然后在同步回磁盘,避免了缓冲带来的问题。由于写入是顺序的写入,所以开销不是很大。完成doublewrite后,在将doublewrite buffer中的页写入各个表空间文件中。

    自适应哈希索引

    哈希是一种非常快的查询方法,时间复杂度O(1)。B+树的查找次数取决于树高,树高多少层,一般需要查询多少次。

    InnoDB存储引擎回监控对表上各索引页的查询。如果观察到建立哈希索引能够对性能进行提升,则会建立哈希索引,称之为自适应哈希索引。

    异步IO

    为了提高磁盘操作性能,当前的数据库系统都采用AIO进行磁盘处理。

    刷新临接页

    工作原理是:当刷新一个脏页的时候,InnoDB存储引擎会检测该页所在区的所有页,如果是脏页,那么一起刷新。好处是通过AIO可以多个IO写入操作合并成一个IO操作,提高了效率。

    1.2版本之后通过参数innodb_flush_neighbors来控制是否启动该特性。

    展开全文
  • 1、插入缓冲(insert buffer) 2、二次写(double write) 3、自适应哈希索引(ahi) 4、预读(read ahead)
  • Innodb存储引擎4大特性

    2021-02-07 10:46:16
    Innodb 存储引擎特性:DoubleWriteInsert/Change BufferAdaptive Hash IndexFlush neighbor pageDoubleWrite:(root@DB)[information_schema]> showvariables like '%double%'-> ;+——————–+——-+| ...
  • 一、前言Innodb Plugin引擎开始引入多种格式的行存储机制,目前支持:Antelope、Barracuda两种。其中Barracuda兼容Antelope格式。另外,Innodb plugin还支持行数据压缩特性,不过前提是采用Barracuda行存储格式。表...
  • 这篇文章主要介绍了mysql的innodb数据库引擎,需要的朋友可以参考下一.mysql体系结构和存储引擎1.1、数据库和实例的区别数据库:物理操作系统或其他形式文件类型的集合。在mysql下数据库文件可以是frm,myd,myi,...
  • InnoDb的crash recovery机制会自动的完成在发生故障前的数据变更提交,不会恢复任何已经发生改变但是没有提交的数据。 InnoDB有它自己的buffer pool去缓存表和索引数据在主存中便于访问。频繁被访问的数据会从内存...
  • MySQL 有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用:MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE。MySQL支持数个存储引擎作为对不同表...
  • 本文介绍MySQL存储引擎InnoDB的核心特性。事务事务的核心特性Atomic原子性所有语句作为一个单元全部成功执行或全部取消。不能出现中间状态Consistent一致性如果数据库在事务开始时处于一种状态,则在执行该事务期间...
  • MYSQL 常用的引擎主要有一下几种,MRG_MYISAM 、CSV 、MyISAM、InnoDB、MEMORY ,NDB,其中MyISAM、InnoDB是mysql最常用的存储引擎,今天主要讨论 InnoDB引擎。一、什么是InnoDB引擎InnoDB引擎是MYSQL数据库的另一个...
  • 图书目录:推荐序前言致谢第1章 mysql体系结构和存储引擎1.1 定义数据库和实例1.2 mysql体系结构1.3 mysql表存储引擎1.3.1 innodb存储引擎1.3.2 myisam存储引擎1.3.3 ndb存储引擎1.3.4 memory存储引擎1.3.5 archive...
  • 前言在MySQL中InnoDB属于存储引擎层,并以插件的形式集成在数据库中。从MySQL5.5.8开始,InnoDB成为其默认的存储...体系架构InnoDB存储引擎是由内存池、后台线程、磁盘存储三部分组成。线程InnoDB 使用的是多线...
  • 一.mysql体系结构和存储引擎1.1、数据库和实例的区别数据库:物理操作系统或其他形式文件类型的集合。在mysql下数据库文件可以是frm,myd,myi,ibd结尾的文件。数据库实例:由数据库后台进程/线程以及一个共享内存...
  • innodb引擎内存架构

    2021-05-25 17:23:59
    innodb引擎内存架构 后台线程 Master Thread具有最高的线程优先级别。其内部由多个循环组 成:主循环(loop)、后台循环(backgroup loop)、刷新循环(flush loop)、暂停循环(suspend loop)。Master Thread会...
  • Innodb的三大特性插入缓冲(change buffer)、两次写(double write)、自适应哈希索引(adaptive hash index)Insert Buffer是什么?InnoDB 缓冲池包含了Insert Buffer的信息但Insert Buffer 其实和数据页一样,也是物理...
  • InnoDB存储引擎

    2021-05-30 22:52:39
    文章目录1 MySQL体系结构2 InnoDB存储引擎概述3 InnoDB体系架构3.1 后台线程3.2 内存4 Checkpoint5 Master Thread6 InnoDB关键特性6.1 插入缓冲6.2 两次写6.3 自适应哈希索引6.4 异步IO6.5 刷新邻接页7 InnoDB关闭 ...
  • InnoDB通常来说,InnoDB存储引擎是OLTP应用中核心表的首选存储引擎OLTP应用:On-Line Transaction Processing联机事务处理过程(OLTP),也称为面向交易的处理过程,其基本特征是前台接收的用户数据可以立即传送到计算...
  • 前言在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理...MySQL主要存储引擎的区别MySQL默认的存储引擎是MyISAM,其他常用的就是InnoDB,另外还有MERGE、MEMORY(HEAP)等。主要的几个存储引擎My...
  • 正 文:MySQL下INNODB引擎的SELECT COUNT(*)性能优化及思考最近有项目有高并发需求,服务器采用负载均衡,数据库采用阿里云的RDS MYSQL,16核64G内存,连接数:16000 IOPS:14000,前几场活动一切正常,RDS的cpu都维持...
  • InnoDB存储引擎中的锁及带来的问题

    千次阅读 2021-10-22 19:26:24
    MySQL常用存储引擎有MyISAM、Memory、BDB、InnoDB等。 MySQL常用存储引擎的锁机制 MyISAM和MEMORY采用表级锁(table-level locking); BDB采用页面锁(page-leve locking)或表级锁,默认为页面锁; InnoDB支持行级...
  • 根据文件,不难发现,自适应索引是InnoDB引擎的内存结构中的一种特性。 对自适应hash索引的描述: 自适应hash索引特性使InnoDB可以在具备适当的工做负载和足够的缓冲池内存的系统上执行更像内存中的数据库,而不牺牲...
  • mysql InnoDB存储引擎

    2021-02-12 02:18:52
    InnoDB是事务安全的MySQL存储引擎,设计上采用了类似于Oracle数据的架构。通常来说,InnoDB存储引擎是OLTP应用中核心表的首选存储引擎。该存储引擎是第一个完整支持ACID事务的MySQL存储引擎,其特点是行锁设计、支持...
  • 分析innodb和Myisam引擎的优缺点和区别 MyISAM和InnoDB的区别. InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定. MyISAM InnoDB 构成上的区别: 每个MyISAM在磁盘上存储成三个...
  • 从1996年发布MySQL1.0版本到现在已经历经25年头啦,在这期间不断更新版本,目前最新的版本是8.0。那InnoDB是什么东西?首先它肯定是MySql的存储引擎...本文对InnoDB存储引擎底层原理详解仅限目前所掌握的知识进行讲述。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 65,761
精华内容 26,304
关键字:

innodb引擎的4大特性