MySQL技术内幕InnoDB存储引擎阅读相关笔记-InnoDB基本介绍

一、InnoDB概叙

在这里插入图片描述

1、后台线程

Innodb后台线程主要有:master主线程、多个IO 线程(书上写的是4个,但我看我本地的是read thread、write thread是各4个,应该是版本问题。而且书上写的通过innodb_file_io_threads控制我也没有查到,书上应该是5.1版本)、一个锁监控线程、1个错误监控线程。

1)、InnoDB存储引擎 FILE I/O

通过show engine innodb status\G查看:

在这里插入图片描述

可以看到FILE I/O线程有:一个insert buffer thread插入缓存线程、log thread日志记录线程、read thread4个读线程、write thread4个写线程。

在这里插入图片描述

2)、master thread

​ master thread的线程优先级是最高的,其内部是几个(循环loop)操作,在这个线程中会分为几个操作:例如每一秒钟操作、每10分钟操作(这个时间会延迟,但InnoDB会尽量保证这个频率)。

​ 1、每秒一次的操作:

​ 日志缓冲刷新到磁盘,即便事务没有提交(总是)

​ 合并插入缓冲 (可能)

​ 至多刷新100个缓冲池中的脏页到磁盘(可能)。(书的版本是5.1版,所以数字可能在新版本会有变化?)

​ 如果没有活动,则切到backgroup loop

刷新脏页:InnoDB会通过判断当前缓冲池中脏页的比例是否超过配置参数innodb_max_dirty_pages_pct,如果超过就会执行磁盘同步IO操作。

在这里插入图片描述

​ 可以看到这里默认是75%(书上写的是90%)。还有就是这里也每秒都进行了磁盘IO同步,但为什么不直接找到写到对应数据页中,这是因为日志文件是直接追加的,并不需要找到对应页的位置,以及其他附带的索引文件的操作等。而如果是直接写数据页,就需要进行索引的操作,同时需要去找到应该插入的对应的页,这些操作会花费更多的资源。

2、每10秒操作

​ 刷新100个脏页到磁盘(可能)

​ 合并至多5个插入缓冲(总是)

​ 将日志缓冲刷新到磁盘(总是)

​ 删除无用的Undo页(总是)

​ 产生一个检查点(总是)

​ 刷新100个或者10个脏页到磁盘(总是)

​ 在以上过程中,InnoDB存储引擎会判断过去10秒之内磁盘操作是否小于200次,如果是,InnoDB就判断当前有足够的磁盘能力,所以其就会将100个脏页刷新到磁盘。然后执行full purge,即删除无用的脏页。

​ 3、backgroup loop

​ 这个循环执行是如果当前没有用户活动(数据库空闲),或者关闭时就会切换到这个循环。这个循环的操作:

​ 删除无用的Undo页(总是)

​ 合并20个插入缓冲(总是)

​ 跳回到主线程(总是)

​ 如果没有事情,InnoDB会切换到suspend_loop,将master thread挂起,等待事情的发送。可以通过前面的查看InnoDB的状态的语句查看循环运行情况:

在这里插入图片描述

2、内存

​ InnoDB存储引擎内存的主要组成:缓冲池(buffer pool)、重做日志缓冲池(redo log buffer)、额外的内存池(additional memory pool)。

1)、buffer pool

​ 缓冲池是占最大块内存的部分、用来存放各种数据的缓存。Innodb存储引擎的工作方式总是将数据库文件按页(每页16K)读取到缓冲池,然后按最近最少使用(LRU)的算法来保留再缓冲池的缓存数据。

​ 如果数据库文件需要修改,首先是修改缓存池中的页(发生修改后,存在缓冲池中的该页即称为脏页,因为其已经与数据文件不一致了),然后按照一定的频率将缓冲池中的脏页刷新到对应的数据文件。同样可以通过前面的show engine innodb status\G

在这里插入图片描述

buffer pool size:表明共有多少缓冲帧(buffer frame),每个缓冲帧为16K。

Free bufffers:表明当前空闲的缓冲帧。

Database pages:表明已经使用的缓冲帧。

Modified reads:表示当前的脏页的数量(也就是被修改的页)

2)、Innodb存储引擎内存结构

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

在这里插入图片描述

日志缓冲:日志缓冲(redo 重做日志缓冲),将重做日志信息先放到这个缓冲区,然后按一定频率刷新到重做日志文件,一般情况是每一秒就会将重做日志缓冲刷新到日志文件。

3)buffer pool 的参数

show variables like 'innodb_buffer_pool_size';

在这里插入图片描述

​ 缓冲池的大小。

3、关键特性

1)、插入缓冲

插入缓冲是相对于索引来说的,是插入非唯一索引到索引页,而不是对插入数据到数据页。

​ 主键是行唯一的标识符,在应用程序中行记录的插入顺序是按照主键递增的顺序插入的。因此插入聚集索引一般是顺序的,不需要裁判的随机读取。但非唯一的辅助索引就不同了,因为其需要离散地访问非聚集索引也,插入的性能就变低了。

​ 所以InnoDB就设计了对非聚集索引的插入或更新操作,不是每次直接将将其插入到索引页。而是先将其先放到插入缓冲区中,然后按一定的频率(上面有讲)执行插入缓冲与非聚集索引页叶子节点的合并操作。有了缓存就可以整合,例如如果多个索引数据是同一个索引页。就能一次更新到磁盘了。

​ 按上面的描叙就需要两个对应的条件才能使用插入缓冲:

​ 索引是辅助索引

​ 索引不是唯一的(如果是唯一的,也就需要离散去遍历判断了,这样插入缓冲就失去意义了)

​ 可以通过前面的查看InnoDB语句查看插入缓冲的使用情况

在这里插入图片描述

seg size:当前插入缓冲的大小(单位为16KB),free list len:表示空闲列表的长度,size:表示已经合并的数量。

2)、两次写

在这里插入图片描述

​ 两次写是对于写磁盘数据页来说的,简单理解就是增加一个备份页。例如当数据库在写一个页,但还没有写完就宕机了,我们称为部分写失效(partial page write)。

​ 不过我们不是还有redo重做日志吗?书上是说的:重做日志记录的是对页的物理操作,例如偏移量800,写aaa记录,但如果这个页本身就是损坏的,所以再进行重写也没有意义。所以我们就需要一个备份页,当写入失效时,我们就可以通过副本也来还原该页再进行重做,也就是doublewrite。

​ doublewrite由两部分:一个就是内存中的Doublewrite Buffer,另外就是物理磁盘上共享表空间中连续的128页,即两个区(extent)。当缓冲池的脏页刷新时,并不直接写磁盘,而是通过memcpy函数先将脏页拷贝到内存中,之后马上通过fsync函数同步磁盘,应为doublewrite页是连续的,所以这个过程是顺序写,开销并不大。在完成doublewrite后,在将数据写到各自的表空间中(如果有设置每个表有独立的表空间)。

​ 可以通过show global status like 'innodb_dblwr%'来查看

在这里插入图片描述

​ 第一个是表示:写的页的数量,第二个是表示:实际写入的次数。

3)、自适应哈希

​ InnoDB索引引擎会监控对表上索引的查找,如果观察建立哈希索引可以带来速度的提升,则会自己建立哈希索引,所以称为自适应的。自适应哈希索引通过缓冲池的B+数建立,而且不需要将整个表都建立哈希索引,所以会很快。

​ 可以通过前面查看InnoDB引擎状态的语句在INSERT BUFFER AND ADAPTIVE HASH INDEX这段,查看其使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值