MySQL之 InnoDB 内存结构

从MySQL 5.5版本开始默认 使用InnoDB作为引擎,它擅长处理事务,具有自动崩溃恢复的特性,在日常开发中使用非常广泛
下面是官方的InnoDB引擎架构图,主要分为内存结构磁盘结构两大部分。
01.jpg

InnoDB 内存结构

1. Buffer Pool

Buffer Pool:缓冲池,简称BP。其作用是用来缓存表数据与索引数据,减少磁盘IO操作,提升效率。
Buffer Pool由 缓存数据页(Page) 和 对缓存数据页进行描述的控制块 组成, 控制块中存储着对应缓存页的所属的 表空间、数据页的编号、以及对应缓存页在Buffer Pool中的地址等信息.
Buffer Pool默认大小是128M, 以Page页为单位,Page页默认大小16K,而控制块的大小约为数据页的5%,大概是800字节。
03.jpg

注:Buffer Pool大小为128M指的就是缓存页的大小,控制块则一般占5%,所以每次会多申请6M的内存空间用于存放控制块
如何判断一个页是否在BufferPool中缓存 ?
MySQl中有一个哈希表数据结构,它使用表空间号+数据页号,作为一个key,然后缓冲页对应的控制块作为value。
10.jpg

  • 当需要访问某个页的数据时,先从哈希表中根据表空间号+页号看看是否存在对应的缓冲页。
  • 如果有,则直接使用;如果没有,就从free链表中选出一个空闲的缓冲页,然后把磁盘中对应的页加载到该缓冲页的位置

2.Page管理机制

Page页分类

BufferPool的底层采用链表数据结构管理Page。在InnoDB访问表记录和索引时会在Page页中缓存,以后使用可以减少磁盘IO操作,提升效率。
Page根据状态可以分为三种类型:
05.jpg

  • ree page : 空闲page,未被使用
  • clean page:被使用page,数据没有被修改过
  • dirty page:脏页,被使用page,数据被修改过,页中数据和磁盘的数据产生了不一致

Page页如何管理

针对上面所说的三种page类型,InnoDB通过三种链表结构来维护和管理

1. free list 表示空闲缓冲区,管理free page
  • Buffer Pool的初始化过程中,是先向操作系统申请连续的内存空间,然后把它划分成若干个【控制块&缓冲页】的键值对。
  • free链表是把所有空闲的缓冲页对应的控制块作为一个个的节点放到一个链表中,这个链表便称之为free链表
  • 基节点: free链表中只有一个基节点是不记录缓存页信息(单独申请空间),它里面就存放了free链表的头节点的地址,尾节点的地址,还有free链表里当前有多少个节点。

07.jpg
*磁盘加载页的流程: *

  1. 从free链表中取出一个空闲的控制块(对应缓冲页)。
  2. 把该缓冲页对应的控制块的信息填上(例如:页所在的表空间、页号之类的信息)。
  3. 把该缓冲页对应的free链表节点(即:控制块)从链表中移除。表示该缓冲页已经被使用了。
2.flush list:表示需要刷新到磁盘的缓冲区,管理dirty page,内部page按修改时间排序。
  • InnoDB引擎为了提高处理效率,在每次修改缓冲页后,并不是立刻把修改刷新到磁盘上,而是在未来的某个时间点进行刷新操作. 所以需要使用到flush链表存储脏页,凡是被修改过的缓冲页对应的控制块都会作为节点加入到flush链表.
  • flush链表的结构与free链表的结构相似

08.jpg
注: 脏页即存在于flush链表,也在LRU链表中,但是两种互不影响,LRU链表负责管理page的可用性和释放,而flush链表负责管理脏页的刷盘操作。

3.lru list:表示正在使用的缓冲区,管理clean page和dirty page。

缓冲区以midpoint为基点,前面链表称为new列表区,存放经常访问的数据,占63%;后面的链表称为old列表区,存放使用较少数据,占37%

普通LRU算法

LRU = Least Recently Used(最近最少使用): 就是末尾淘汰法,新数据从链表头部加入,释放空间时从末尾淘汰.
06.jpg

  1. 当要访问某个页时,如果不在Buffer Pool,需要把该页加载到缓冲池,并且把该缓冲页对应的控制块作为节点添加到LRU链表的头部。
  2. 当要访问某个页时,如果在Buffer Pool中,则直接把该页对应的控制块移动到LRU链表的头部
  3. 当需要释放空间时,从最末尾淘汰

普通LRU链表的优缺点
优点: 所有最近使用的数据都在链表表头,最近未使用的数据都在链表表尾,保证热数据能最快被获取到
缺点:

  1. 如果发生全表扫描(比如:没有建立合适的索引 or 查询时使用select * 等),则有很大可能将真正的热数据淘汰掉.
  2. 由于MySQL中存在预读机制,很多预读的页都会被放到LRU链表的表头。如果这些预读的页都没有用到的话,这样,会导致很多尾部的缓冲页很快就会被淘汰。

02.jpg

改进型LRU算法

改性LRU:链表分为new和old两个部分,加入元素时并不是从表头插入,而是从中间midpoint位置插入(就是说从磁盘中新读出的数据会放在冷数据区的头部),如果数据很快被访问,那么page就会向new列表头部移动,如果数据没有被访问,会逐步向old尾部移动,等待淘汰。
11.jpg
冷数据区的数据页什么时候会被转到到热数据区呢 ?

  1. 如果该数据页在LRU链表中存在时间超过1s,就将其移动到链表头部 ( 链表指的是整个LRU链表)
  2. 如果该数据页在LRU链表中存在的时间短于1s,其位置不变(由于全表扫描有一个特点,就是它对某个页的频繁访问总耗时会很短)
  3. 1s这个时间是由参数 innodb_old_blocks_time 控制的

3. Change Buffer

change Buffer基本概念

Change Buffer:写缓冲区,是针对二级索引(辅助索引) 页的更新优化措施
Change Buffer作用: 在进行DML操作时,如果请求的是 辅助索引(非唯一键索引)没有在缓冲池 中时,并不会立刻将磁盘页加载到缓冲池,而是在CB记录缓冲变更,等未来数据被 读取时,再将数据合并恢复到BP中。
ChangeBuffer占用BufferPool空间,默认占25%,最大允许占50%,可以根据读写 业务量来进行调整。参数innodb_change_buffer_max_size;
43.jpg

  1. ChangeBuffer用于存储SQL变更操作,比如Insert/Update/Delete等SQL语句
  2. ChangeBuffer中的每个变更操作都有其对应的数据页,并且该数据页未加载到缓存中;
  3. 当ChangeBuffer中变更操作对应的数据页加载到缓存中后,InnoDB会把变更操作Merge到数据页上;
  4. InnoDB会定期加载ChangeBuffer中操作对应的数据页到缓存中,并Merge变更操作

change buffer更新流程

情况1: 对于唯一索引来说,需要将数据页读入内存,判断到没有冲突,插入这个值,语句执行结束;
情况2: 对于普通索引来说,则是将更新记录在 change buffer,流程如下:

  1. 更新一条记录时,该记录在BufferPool存在,直接在BufferPool修改,一次内存操作。

  2. 如果该记录在BufferPool不存在(没有命中),在不影响数据一致性的前提下,InnoDB 会将这些更新操作缓存在 change buffer 中不用再去磁盘查询数据,避免一次磁盘IO。

  3. 当下次查询记录时,会将数据页读入内存,然后执行change buffer中与这个页有关的操作.通过这种方式就能保证这个数据逻辑的正确性。

    12.jpg

写缓冲区,仅适用于非唯一普通索引页,为什么?

如果在索引设置唯一性,在进行修改时,InnoDB必须要做唯一性校验,因此必须查询磁盘,做一次IO操作。会直接将记录查询到BufferPool中,然后在缓冲池修改,不会在ChangeBuffer操作。

什么情况下进行 merge ?

将 change buffer 中的操作应用到原数据页,得到最新结果的过程称为merge .
change buffer,实际上它是可以持久化的数据。也就是说,change buffer 在内存中有拷贝,也会被写入到磁盘上,以下情况会进行持久化:

  1. 访问这个数据页会触发 merge
  2. 系统有后台线程会定期 merge。
  3. 在数据库正常关闭(shutdown)的过程中,也会执行 merge 操作。

Change Buffer 的使用场景

  • change buffer 的主要目的就是将记录的变更动作缓存下来,所以在merge发生之前应 当尽可能多的缓存变更信 息,这样 change buffer的优势发挥的就越明显.
  • 应用场景: 对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时 change buffer 的使用 效果最好。这种业务模型常见的就是账单类、日志类的系统。

4. Log Buffer

Log Buffer:日志缓冲区,用来保存要写入磁盘上log文件(Redo/Undo)的数据,日志缓冲区的内容定期刷新到磁盘log文件中。日志缓冲区满时会自动将其刷新到磁盘,当遇到BLOB或多行更新的大事务操作时,增加日志缓冲区可以节省磁盘I/O。
LogBuffer主要作用是: 用来优化每次更新操作之后都要写入redo log 而产生的磁盘IO问题.
14.jpg
LogBuffer空间满了,会自动写入磁盘。可以通过将innodb_log_buffer_size参数调大,减少磁盘IO频率

原文链接:https://www.cnblogs.com/zwhdd/p/17268132.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MySQL之 InnoDB 内存结构 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • MySQL的子查询及相关优化学习教程

    MySQL的子查询及相关优化学习教程 什么是子查询? 子查询其实就是一个SQL查询语句嵌套在另一个查询语句中的查询。子查询主要分为标量子查询和表子查询两种类型。 标量子查询:返回单个值的子查询,通常用在WHERE语句中。 表子查询:返回多个行的子查询,通常用在FROM语句中。 子查询的优化 查询语句嵌套过深或者存在大量的子查询会导致查询效率低下,因此进行适当…

    MySQL 2023年5月19日
    00
  • MySQL优化之连接优化

    MySQL优化是整个系统优化的一个重要方面。连接是MySQL中很耗费资源的操作之一。因此,优化MySQL连接是提高MySQL性能的重要手段之一。本篇文章将详细讲解连接优化的完整攻略。 连接优化攻略 1. 减少连接数 MySQL连接数的多少会影响系统的性能。因此,在连接优化中,我们应该尽可能的减少连接数。常见的方法是利用连接池技术,即由连接池来管理连接,并对连…

    MySQL 2023年5月19日
    00
  • mysql 5.7.17 64bit安装配置方法图文教程

    MySQL 5.7.17 64bit安装配置方法图文教程 MySQL是一种常见的数据库管理系统,可以帮助我们存储和访问数据。这篇文章将详细介绍如何在64位Windows操作系统上安装和配置MySQL数据库。 Step 1: 下载MySQL 首先需要从官方网站https://dev.mysql.com/downloads/mysql/5.7.html#down…

    MySQL 2023年5月18日
    00
  • MySQL中binlog备份脚本分享

    关于MySQL的二进制日志(binlog),我们都知道二进制日志(binlog)非常重要,尤其当你需要point to point灾难恢复的时侯,所以我们要对其进行备份。关于二进制日志(binlog)的备份,可以基于flush logs方式先切换binlog,然后拷贝&压缩到到远程服务器或本地服务器的其他存储上,例如挂载的NAS存储,也可以使用mys…

    MySQL 2023年4月19日
    00
  • MySQL 4G内存服务器配置优化

    下面我为大家详细讲解在MySQL 4G内存服务器上进行配置优化的攻略: 1. 确认服务器内存信息 在进行MySQL配置优化之前,我们需要先确认服务器的内存信息。可以使用如下命令: $ free -m 该命令会显示服务器内存的详细信息,包括总内存、已使用内存和空闲内存等。确认服务器内存总量后,我们需要将其转化为MB单位。 2. 修改MySQL配置文件 接着,我…

    MySQL 2023年5月19日
    00
  • MySQL mysqldump备份数据库(附带实例)

    MySQL mysqldump是MySQL自带工具中最常用的备份工具之一。它可以备份 MySQL 数据库的数据和结构,并且可以将这些备份数据还原到另一个 MySQL 数据库中。使用mysqldump进行备份可以方便、快捷、可靠地备份和恢复MySQL数据库。 使用mysqldump备份 MySQL 数据库 以下是使用mysqldump命令备份 MySQL 数据…

    MySQL 2023年3月10日
    00
  • 实验六 存储过程

    实验六 存储过程 第1关:增加供应商相关列sqty use demo; #代码开始 #在S表中增加一列供应零件总数量(sqty),默认值为0。 altertable s add sqty intdefault0; #代码结束 desc s; 第2关:定义、调用简单存储过程 use demo; #代码开始 #1、定义简单存储过程:计算所有供应商供应零件总数量并…

    MySQL 2023年5月10日
    00
  • mysql 5.7.9 winx64在windows上安装遇到的问题

    MySQL 5.7.9 winx64在Windows上安装遇到的问题 MySQL是一款用于管理关系型数据库的开源软件,广泛用于各种网站和应用的开发和维护中。在Windows操作系统上安装MySQL的过程中,可能会出现一些问题。本文将介绍MySQL 5.7.9 winx64在Windows上安装遇到的问题,并提供解决方案,希望能够帮助到大家。 问题一:MySQ…

    MySQL 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部