InnoDB 缓存

本文主要聊InnoDB内存结构, 先来看下官网Mysql 8.0 InnoDB架构图

MySQL :: MySQL 8.0 Reference Manual :: 17.4 InnoDB Architecture

如上图所示,InnoDB内存主要包含Buffer Pool, Change Buffer, Log BufferAdaptive Hash Index

Buffer Pool

其实 buffer pool 就是内存中的一块缓冲池,用来缓存索引的数据。默认80%的物理内存分配给缓冲池。

我们都知道 mysql 的数据最终是存储在磁盘上的,但是如果读存数据都直接跟磁盘打交道的话,这速度就有点慢了。所以 innodb 自己维护了一个 buffer pool,在读取数据的时候,会把数据加载到缓冲池中,这样下次再获取就不需要从磁盘读了,直接访问内存中的 buffer pool 即可。包括修改也是一样,直接修改内存中的数据,然后到一定时机才会将这些脏数据刷到磁盘上。

其实缓冲池维护的是页数据,也就是说,即使你只想从磁盘中获取一条数据,但是 innodb 也会加载一页的数据到缓冲池中,一页默认是 16k

Buffer Pool 管理

Buffer Pool 中的页有三种状态:

  1.  空闲页:通过空闲页链表(Free List)管理。

  2.  正常页:通过LRU链表(LRU List)管理。

  3.  脏页:通过LRU链表和脏页链表(Flush List)管理。(缓冲池中被修改过的页,与磁盘上的数据页不一致)

Free链表

初始化完的buffer pool时所有的页都是空闲页,所有空闲的缓冲页对应的控制块信息作为一个节点放到Free链表中。

要注意Free链表是一个个控制块,而控制块的信息中有缓存页的地址信息。

在有了free链表之后,当需要加载磁盘中的页到buffer pool中时,就去free链表中取一个空闲页所对应的控制块信息,根据控制块信息中的表空间号、页号找到buffer pool里对应的缓冲页,再将数据加载到该缓冲页中,随后删掉free链表该控制块信息对应的节点。

Flush链表

修改了buffer pool中缓冲页的数据,那么该页和磁盘就不一致了,这样的页就称为【脏页】,它不是立马刷入到磁盘中,而是由后台线程将脏页写入到磁盘。

Flush链表就是为了能知道哪些是脏页而设计的,它跟Free链表结构图相似,区别在于控制块指向的是脏页地址。

LRU链表

对于频繁访问的数据和很少访问的数据我们对与它的期望是不一样的,很少访问的数据希望在某个时机淘汰掉,避免占用buffer pool的空间,因为缓冲空间大小是有限的。

MySQL设计了根据LRU算法设计了LRU链表来维护和淘汰缓冲页。

LRU 算法简单来说,如果用链表来实现,将最近命中(加载)的数据页移在头部,未使用的向后偏移,直至移除链表。这样的淘汰算法就叫做 LRU 算法,但是简单的LRU算法会带来两个问题:预读失效、Buffer Pool污染

预读:  当数据页从磁盘加载到 Buffer Pool 中时,会把相邻的数据页也提前加载到 Buffer Pool 中,这样做的好处就是减少未来可能的磁盘IO。

改进LRU 算法

Buffer Pool的LRU算法中InnoDB 将LRU链表按照5:3的比例分成了young区域和old区域。链表头部的5/8是young区(被高频访问数据),链表尾部的3/8区域是old区域(低频访问数据),箭头朝下的是未被访问的数据,朝上的是被访问的数据。

这样做的目的是,在预读的时候或访问不存在的缓冲页时,先加入到 old 区域的头部,等 1s后(大部分场景扫描数据之后同一个请求会马上访问这部分数据,之后可能就不访问了),如果该页面再次被访问才会被移动到新生代。

Buffer Pool刷盘

(1)有一个后台线程,会认为数据库空闲时;

(2)数据库缓冲池不够用时;(执行sql时刚好碰到缓冲池不够用导致的刷盘时, sql执行得等缓存池刷盘完成)

(3)数据库正常关闭时;

(4)redo log写满时(下文详解);

Change Buffer

在MySQL5.5之前,叫插入缓冲(insert buffer),只针对insert做了优化;现在对delete和update也有效,叫做写缓冲(change buffer)。

它是一种应用在非唯一普通索引页(non-unique secondary index page)不在缓冲池中,对页进行了写操作,并不会立刻将磁盘页加载到缓冲池,而仅仅记录缓冲变更(buffer changes),等未来数据被读取时,再将数据合并(merge)恢复到缓冲池中的技术。写缓冲的目的是降低写操作的磁盘IO,提升数据库性能。

写入流程

执行两条Insert语句,其中左侧的要更新的数据页 Page1 不在Buffer Pool,而右侧需要更新的数据页Page2在Buffer Pool缓存中。

  • 数据页Page1: 不在Buffer Pool中的话, 将修改写入Change Buffer,最终写入表空间
  • 数据页Page2: 在缓存中,直接更新, 最终写入数据文件

两次内存:一次是修改Buffer Pool的数据页、另一次是Change buffer中记录这个写入操作。

三次磁盘:  一次redo log(合并批量), 一次change buffer落盘, 一次脏页落盘. 三次落盘都是等到落盘条件之后触发。

Merge流程

读Page2的时候很好理解,直接从Buffer Pool 中返回,

但是读Page1时,需把Page1从磁盘读入内存,然后将Change Buffer里面的操作日志,Merge生成一个正确版本并返回结果。

适用场景:  数据库大部分是非唯一索引, 并且写多读少。

Log Buffer

Log Buffer是给 redo log 做缓冲用的。redo log 我们都知道是重做日志,用来保证崩溃恢复数据的正确性,innodb 写数据时是先写日志,再写磁盘数据,即 WAL (Write-Ahead Logging),把数据的随机写入转换成日志的顺序写。

即使是顺序写 log ,每次都调用 write 或者 fsync 也是有开销的,毕竟也是系统调用,涉及上下文切换。于是乎,搞了个 Log Buffer(默认16M) 来缓存 redo log 的写入。

刷盘配置

innodb 其实给了个配置,即 innodb_flush_log_at_trx_commit 来控制 redo log 写盘时机。

  • 当值为 0,提交事务不会刷盘到 redo log,需要等每隔一秒的后台线程,将 log buffer 写到操作系统的 cache,并调用 fsync落盘,性能最好,但是可能会丢 1s 数据。

  • 当值为 1,提交事务会将 log buffer 写到操作系统的 cache,并调用 fsync 落盘,保证数据正确,性能最差,这也是默认配置。

  • 当值为 2,提交事务会将 log buffer 写到操作系统的 cache,但不调用 fsync,而是等每隔 1s 调用 fsync 落盘,性能折中,如果数据库挂了没事,如果服务器宕机了,会丢 1s 数据。

redo log

每个 InnoDB 存储引擎至少有 1 个重做日志文件组( redo log group),每个文件组下至少有 2 个重做日志文件(redo log file),默认的话是一个 redo log group,其中包含 2 个 redo log file:ib_logfile0ib_logfile1 。在日志组中每个 redo log file 的大小一致,并以循环写入的方式运行。

如下图举例:

一组 4 个文件,每个文件的大小是 1GB,那么总共就有 4GB 的 redo log file 空间。write pos 是当前 redo log 记录的位置,随着不断地写入磁盘,write pos 也不断地往后移,写到 file 3 末尾后就回到 file 0 开头。CheckPoint 是当前要擦除的位置(将 Checkpoint 之后的页刷新回磁盘),write pos 和 CheckPoint 之间的就是 redo log file 上还空着的部分,可以用来记录新的操作。如果 write pos 追上 CheckPoint,就表示 redo log file 满了,这时候不能再执行新的更新,得停下来先把buffer pool中脏页都flush到磁盘,把 CheckPoint 推进一下。

crash-safe

上面change buffer提到二级索引更新操作,如果 buffer pool中没有更新数据,不会从磁盘拉取数据,而是直接把变更记录在change buffer。假如数据库挂了,更改不是丢了吗? 

mysql通过redo log 和 binlog来防止机器宕机之后数据丢失问题。

场景一:redo log 没有commit,binlog没有fsync,数据丢失。

场景二:redo log 没有commit,binlog已经fsync,重启之后会对比binlog中的trx_id和redo log中的trx_id, 进行commit redo log。

场景三:redo log 已经commit,binlog已经fsync,从redo log恢复数据。

Adaptive Hash Index

在MySQL运行的过程中,如果InnoDB发现,有很多寻路很长(比如B+树层数太多、回表次数多等情况)的SQL,并且有很多SQL会命中相同的页面(Page)的话,InnoDB会在自己的内存缓冲区(Buffer Pool)里,开辟一块区域,建立自适应哈希索引(Adaptive Hash Index,AHI),以加速查询。

MySQL 5.5 版本开始提供AHI特性,并在后续版本持续改进。在最新的8.0.33版本中依然将该特性默认开启。

首先,我们来看一下上图中两个InnoDB内部的B树结构,左边的primary key主键索引,右边是secondary key二级索引。当我们需要找到主键值为5的记录时,就需要从主键索引B数的根节点开始,一直搜索到叶子,找到最下面的左边第二页,然后定位到记录(5…)。而当我们想要查找二级索引键值为35的那条记录的时候,就会先搜索左边的二级索引B树,然后定位到(35,5)这条二级索引记录,再通过对应的主键5到左边的主键索引中找到(5…)这条完整的数据记录。

而如下图所示,AHI通过建立主键5到数据所在数据页的hash索引,可以直接定位到记录(5…)所在的数据页,也就是左边数第二个数据页。如此,在查找记录的时候就省略了从根节点到叶子节点的搜索过程。

如下图所示,AHI的主要数据结构是多个哈希表,可以看做它是B+树索引的hash索引 

优势场景:读多写少,并且是叶节点定位占比多的场景 。

Doublewrite Buffer

Doublewrite Buffer,翻译成中文:双写缓冲区,缩写:DWB。Doublewrite 是保障 InnoDB 存储引擎操作数据页的可靠性。

我们都知道 innodb 默认一页是 16K,而操作系统 Linux 内存页是 4K,那么一个 innodb 页对应 4 个系统页。所以 innodb 的一页数据要刷盘等于需要写四个系统页。

如下图所示:Buffer Pool中的Page1 对应,系统页中的Page1,Page2,Page3,Page4,在写Page4的时候出现了断电了,则会出现:重启后,MySQL内Page 1的页,物理上对应磁盘上的Page 1、Page 2、Page 3三个页,数据完整性被破坏。(Redo Log无法修复这类“页数据损坏”的异常,修复的前提是“页数据正确”并且Redo日志正常

针对上面出现的情况,如何解决这类“页数据损坏”的问题呢?很容易想到的方法是,能有一个“副本”,对原来的页进行还原,这个存储“副本”的地方,就是Doublewrite Buffer

如上图所示,当有页数据要刷盘时:

第1步:页数据先memcopy到DWB的内存里;

第2步:DWB的内存里的数据页,会先刷到DWB的磁盘上;

第3步:DWB的内存里的数据页,再刷到数据磁盘存储.ibd文件上;

第4步:如果出现如上断电场景,从DWB FILE中恢复数据盘;

备注:DWB内存结构由128个页(Page)构成,所以容量只有:16KB × 128 = 2MB。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/479844.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络安全协议基本问题

Http和Https协议的端口号: Http:80 Https:443 网络监听: 网络监听是一种监视网络状态、数据流程以及网络上信息传输的工具,它可以将网络界面设定成监听模式,并且可以截获网络上所传输的信息。但是网络监…

Linux:权限的概念与理解

目录 1. Linux权限的概念 2. Linux权限管理 01.文件访问者的分类 02.文件类型和访问权限 03.文件权限值的表示方法 04. 文件访问权限的相关设置方法 3. 使用 sudo分配权限 4. 目录的权限 ---------- 权限 用户角色(具体的人) 文件权限属性 ---------- 1. Linux权限的…

大英赛-选择题 (持续更新中)

解题策略: 十五分钟内写完,单选: ABCD全部单项选择题 考的语法点弄清不懂得话 看《张道真语法》 不会的单词建议下载墨墨背单词 直接把不会的加入到要背的里面 知识点 2019年初赛: 2019年决赛:

QT信号和槽机制connect用法

信号与槽机制是绝对不可或缺且常用的&#xff0c;其中的参数一般都会比较简单&#xff0c;bool、int、QString之类的&#xff0c;但当我们想要传递相对比较复杂的参数&#xff0c;例如QVector<int>、QList<QString>&#xff0c;以及一些我们自定义的结构体时&#…

白酒:蒸馏过程中香味成分的生成机制与调控技术

在豪迈白酒的酿造过程中&#xff0c;蒸馏是关键的步骤之一&#xff0c;它决定了白酒的香味成分和品质。云仓酒庄对蒸馏过程中香味成分的生成机制与调控技术进行了深入研究&#xff0c;以提高产品的风味和品质。 首先&#xff0c;蒸馏过程中香味成分的生成机制是一个复杂的过程。…

第四百一十八回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义标题栏"相关的内容&#xff0c;本章回中将介绍自定义Action菜单.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里提到的…

图和树的路径问题

图 一&#xff1a;用vector存储无向图 数据结构 const int N 100; vector<int> G[N]; void addEdge(int u, int v){// 无向图G[u].push_back(v);G[v].push_back(u); } int m; // 点的个数创建图 void printList(){for (int i 0; i < m;i){cout << i<<…

NFT Insider #124:Aavegotchi 开启新一季稀有度挖矿,德克萨斯州奥斯汀市登陆 The Sandbox

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members&#xff08;https://twitter.com/WHALEMembers&#xff09;、BeepCrypto &#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、…

基于Gabor滤波器的指纹图像识别,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

Windows系统部署hMailServer邮件服务结合内网穿透实现公网收发邮件

文章目录 前言1. 安装hMailServer2. 设置hMailServer3. 客户端安装添加账号4. 测试发送邮件5. 安装cpolar6. 创建公网地址7. 测试远程发送邮件8. 固定连接公网地址9. 测试固定远程地址发送邮件 前言 hMailServer 是一个邮件服务器,通过它我们可以搭建自己的邮件服务,通过cpola…

外包干了6天,技术退步明显。。。。

说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入上海某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…

【FFT实战篇】C++实现:利用快速傅里叶变换快速计算(多项式)乘法

本文使用C语言实现了快速傅里叶变换FFT并运用其进行多项式乘法计算&#xff0c;适合供学习过《数字信号处理》的读者学习使用FFT快速计算乘法。当然也可供对快速乘法感兴趣的没有系统学习过数字信号处理&#xff08;从CFT到DTFT到DFT&#xff09;的读者参考&#xff0c;提供一种…

如何真正改变自己? 《掌控习惯》

维持改变 1.心态 目标与体系&#xff0c;谁是真正通往成功的钥匙&#xff1f; 2.行动 习惯转变的3个层次 身份 你要成为谁&#xff1f; 你为成为他而幸福吗&#xff1f;过程结果 习惯的基本原理&#xff1a;要重视微小的改变 维持改变成两个方面入手 一、心态&#xff1a;忽略…

面向对象编程三大特征

基本介绍 面向对象编程有三大特征&#xff1a;封装、继承和多态。 1、封装介绍 2、继承介绍 3、多态介绍 向上转型与向下转型 多态常用案例 数值比较。

Oracle 写丢失保护/影子表空间(Lost Write Protection with Shadow Tablespace)

写丢失是Oracle数据库与独立I/O子系统交互时一种错误场景。假如Oracle发出的写磁盘命令&#xff0c;I/O子系统也返回成功写磁盘的消息&#xff08;但数据此时可能依然在I/O系统缓存中&#xff09;&#xff0c;如果在I/O系统实际写盘之前Oracle再次读取该数据&#xff0c;则I/O系…

机器人路径规划:基于红尾鹰算法(Red‑tailed hawk algorithm ,RTH)的机器人路径规划(提供MATLAB代码)

一、机器人路径规划介绍 移动机器人&#xff08;Mobile robot&#xff0c;MR&#xff09;的路径规划是 移动机器人研究的重要分支之&#xff0c;是对其进行控制的基础。根据环境信息的已知程度不同&#xff0c;路径规划分为基于环境信息已知的全局路径规划和基于环境信息未知或…

软考中级 --网络工程师真题试卷 2023下半年

在EIGRP协议中&#xff0c;某个路由器收到了两条路径到达目标网络&#xff0c;路径1的带宽为100Mbps&#xff0c;延迟2ms&#xff0c;路径2的带宽为50Mbps&#xff0c;迟为4ms&#xff0c;如果EIGRP使用带宽和延迟的综合度量标准&#xff0c;那么该路由器选择的最佳路径是(D)。…

Vue.js+SpringBoot开发教学过程管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 教师端2.2 学生端2.3 微信小程序端2.3.1 教师功能如下2.3.2 学生功能如下 三、系统展示 四、核心代码4.1 查询签到4.2 签到4.3 查询任务4.4 查询课程4.5 生成课程成绩 六、免责说明 一、摘要 1.1 项目介绍 基于JAVAVu…

高架学习笔记之系统分析与设计

目录 一、结构化方法&#xff08;SASD&#xff09; 1.1. 结构化分析方法&#xff08;SA&#xff09; 1.1.1. 数据流图&#xff08;DFD&#xff09; 1.1.2. 实体联系图&#xff08;E-R图&#xff09; 1.1.3. 状态转换图(STD) 1.1.4. 数据字典 1.2. 结构化设计方法&#x…

基于python+vue拍卖行系统的设计与实现flask-django-nodejs-php

拍卖行系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品&#xff0c;体验高科技时代带给人们的方便&#xff0c;同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓&#xff0c;iOS相比较起来&#xff0c;拍卖行…
最新文章