MySQL那些事(InnoDB架构和存储结构)

一、序言

本节内容为博主根据MySQL 8.0版本官方文档手动翻译过后的最新内容,并加上自己的经验对InnoDB的理解。


二、InnoDB架构

下面这张图是从官方文档上捞过来的架构图,可以看到InnoDB的架构主要分为两部分,一部分是内存结构,还有一部分是磁盘结构。
InnoDB架构图


三、InnoDB内存结构

从上面的架构图中可以看出,InnoDB内存结构主要分为Buffer Pool、Change Buffer和Log Buffer三部分,下面我们具体聊聊这3个部分的作用。

1、Buffer Pool (缓冲池)

Buffer Pool从名字其实就可以看出是一片内存区域,该区域会缓存表和索引数据。通过Buffer Pool可以直接在内存里频繁处理使用到的数据。在专用服务器上,80%的物理内存会被分配到Buffer Pool中。

为了提高大容量读操作的效率,Buffer Pool会被划分为多页(page)来保存行数据。Buffer Pool的实现其实是一个链表,链表上为访问的页数据。

备注:page是一个数据单位,代表InnoDB每次从磁盘读取到内存中的的数据量,每个page可以包含一行或者多行数据。

Buffer Pool会用LRU算法(变体)去管理链表上的数据,当往Buffer Pool中插入新的page时,最近最少使用的page会被添加到链表的中间。

这种中点插入策略会把链表拆分为两个子链表,如下:
Buffer Pool数据结构
可以看到,链表主要分为两部分:

  • 头部是最近被访问的子链表,我们称之为新页(young pages)。
  • 尾部是最近很少被访问的子链表,我们称之为旧页(old pages)。

这种LRU变体算法会将受大量查询影响的page放在new sublist,而old sublist则包含更少使用的page。

当InnoDB从磁盘中读取数据到Buffer Pool中时,首先会将读取到的page插入到两个链表的中间位置(old sublist的头部),访问old sublist的page时,page会被标记为young,该page将会被移到Buffer Pool中的头部(new sublist的头部)。

当有数据库操作时,Buffer Pool中没有被访问到的page会被移到链表的尾部,如果该page依然没有被用到就会被清除掉。

2、Change Buffer

Change Buffer是一种特殊的数据结构,它会缓存对二级索引页的修改,这些修改主要来自于DML语句,比如INSERTUPDATEDELETE
在这里插入图片描述
对于不在Buffer Pool中的二级索引页的修改将被缓存到change buffer中,当二级索引页被读取到Buffer Pool中时,这些修改将会被周期性地合并到Buffer Pool中。

3、Log Buffer

Log Buffer是一片内存区域,这片区域会保存写到日志文件的数据。Log Buffer的大小默认为16MB,里面的数据会周期性的刷新到磁盘中。

Log Buffer越大,支持运行的事务也就越大,大的log buffer可以减少redo log数据频繁刷新到磁盘。如果事务中包含了大量数据行的DML操作,增加Log Buffer的大小可以减少磁盘I/O。


四、InnoDB磁盘结构

InnoDB磁盘结构主要包含索引表空间Doublwrite BufferRedo LogUndo Logs,下面我们具体讲讲后面几项的作用。

1、表空间

表空间主要分为系统表空间File-Per-Table表空间General表空间Undo表空间临时表空间

  • 系统表空间:针对Double write buffer和Change buffer的一块存储区域。如果表建立在系统表空间内,那么也会包含表和索引的数据。
  • File-Per-Table表空间:过去InnoDB都是把表数据存储在系统表空间内,这种方式适用于专门用于数据库处理的机器,而File-Per-Table允许每个表数据都可以存储在自己的表空间数据文件里(.ibd文件)。默认都是用这种方式存储表数据。
  • General表空间:共享表空间,可以通过CREATE TABLESPACE语法创建共享表空间。
  • Undo表空间:该表空间包含undo日志,通过该日志可以撤销事务对聚簇索引数据的最新修改,即我们常说的数据回滚。
  • 临时表空间: 除了用于存放临时表数据,还会保存对临时表修改的回滚段。

2、Doublewrite Buffer(双写缓冲区)

双写缓冲区是位于系统表空间内的一块存储区域,InnoDB会在该存储区域完成Buffer Pool中已刷新的page写入。

为什么说叫做双写缓冲区呢?因为数据页在落地数据文件前,首先会往双写缓冲区写入数据,用来保证数据的完整性。

3、Redo Log

Redo log是一种基于磁盘的数据结构,主要用于未完成事务的数据恢复。Redo Log会编码更新表数据的请求,未完成更新数据文件的修改在数据库初始化期间自动重放。

默认情况下,Redo Log在磁盘上分为两个文件:ib_logfile0ib_logfile1,MySQL将会循环写入数据到redo log文件中。

4、Undo Log

Undo log是与单个读写事务相关联的Undo log日志记录的集合,该日志会包含如何撤销事务最新修改的一些信息。

一个事务最多分配4个undo日志文件,每个日志文件对应的操作类型如下:

  • 对表的INSERT操作。
  • 对表的UPADATE和DELETE操作。
  • 对临时表的INSERT操作。
  • 对临时表的UPADATE和DELETE操作。

五、结语

本篇文章比较偏概念性,好让大家对InnoDB的内存结构和磁盘结构有个大概的了解,更加详细的内容以及相关MySQL参数设置参考MySQL 8.0官方文档

下一节我们将具体聊聊MySQL中InnoDB和MyISAM存储引擎的区别。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nick说说前后端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值