mysql 内存架构

news2025/7/21 11:31:49

1. 背景

从 innodb 的整体架构中可以知道 innodb 的内存架构中分为 buffer pool 缓存区, change pool 修改缓冲区, adaptive hash index 自适应哈希索引, 和 log buffer 日志缓冲区.

2. buffer pool

buffer pool 是用于缓冲磁盘页的数据,mysql 的80%的内存会分配给 buffer pool 来使用。

当进行数据查询的时候,如果数据页在buffer pool 中存在的话,buffer pool 则直接返回,如果不存在则会去从磁盘读取,读取后再加载到磁盘中。

当有更新操作时,更新 buffer pool 中的数据,并且记录 redo log,到了 checkpoint 点之后把内存中的脏页(内存和磁盘数据不一致的页)刷到磁盘上。

2.1. buffer pool 的数据结构

buffer pool 的内存结构中,分为3种缓存页 和 3种链表,缓存页分为 空闲页 free page,干净页 clean page,脏页 dirty page。链表分为 free list 当前没有被分配的内存页(即 free page 组成的链表),LRU list 读取到数据的内存页(即干净页和脏页组成的链表),flush list 脏页链表(即脏页组成的链表),这里需要注意在 flush list 中的页也存在与 LRU list 中。

2.2. free list

free list 定义是当前没有被使用的内存页,也就是空闲的内存页,当执行查询操作时,如果页已经在 buffer pool 中了,则查询到直接返回,如果没有在 buffer pool,并且 free list 不为空,则会从磁盘中查询对应的数据,放入 free list 的某一页中,并且把这页从 free list 中移除,放入 LRU 队列中。

2.3. LRU list

LRU list 顾名思义是使用了 LRU 算法,当内存满的时候淘汰最久没有被使用的数据以释放内存空间,来缓存最近使用的数据,innoDB 在原有的 LRU 算法上做了优化,把内存区域又分为了 new 和 old 2个部分,默认配置是 37,意味着 37% 的区域是 old,63% 的区域是 new。

ref:https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-pool.html

当有新的数据从磁盘查询到内存时,会写入到 old sub list 的头部,当此数据再次被查询的时候,即在 old sublist 中命中之后,会放入 new sublist 的头部。

这样做的目的是为了避免缓存中的热点数据被污染,以提高缓存的命中率,比如有一个sql select * from table,没有设置过滤条件,那大量的数据都会被加载到缓存中,但是这种sql可能很长时间只跑一次,在未来的一段时间内都不会再次查询,如果不拆分 old 和 new,会导致缓存的污染。

2.4. flush list

flush list 中保存的数据表示当前内存中的脏页的数量,即 check point 刷盘的时候需要刷的脏页。

需要注意的是 flush list 中的数据在 LRU 中也会保存,所以当 LRU 中的缓存被淘汰,也会触发 flush list 中的脏页刷盘。

3. change buffer(double write都是mysql 专用的 O:IMU)LRU list(复制脏页进buffer pool)?

上面提到的 buffer pool 主要是用于提升 mysql 查询性能的,mysql 写的性能提升提升主要依赖 change buffer,以前 change buffer 称为 insert buffer,因为以前只做了 insert 操作的性能优化,之后版本更新之后,也能对于修改和删除做缓存处理,所以改名为 change buffer。

3.1. change buffer 解决的问题

我们假设,现在有一张表,其二级索引数据没有 load 到内存的 buffer pool 中,我们对表进行更新操作,那这个时候 innodb 会从磁盘中 load 数据出来到内存中,这是第一次随机 IO 读取,然后在内存进行 update 操作,更新的字段如果涉及二级索引的更新,需要再次读取二级索引的数据到内存中,进行更新,这是第二次随机读取的操作。那 change buffer 就是为了减少第二次随机 IO 读取,以提高更新的效率。

change buffer 的思路是,假设有很多次的更新,但是没有查询,二级索引的更新是可以批处理的,一直等到下一次使用二级索引查询的时候,把磁盘上的二级索引查询出来,和 change buffer 中的索引修改的增量记录做 merge 之后,在使用,那磁盘的查询操作就会从多次变成一次了。

3.2. merge 是不是等于刷盘?

merge 是指把 change buffer 中的增量变更在下一次查询的时候,合并到 buffer pool 中,从而这个 buffer pool 也变成了脏页。刷盘是指的是 buffer pool 中的脏页写到磁盘的过程,这是两个事情。

3.3. 宕机会不会丢失?

不会丢失,因为事务提交的时候,会写 redo log,redo log 中会包含 change buffer 的内容,如果出现宕机,机器重启之后会基于 redo log 做重放,可以恢复 change buffer。

3.4. 查看当前的change buffer

Ibuf: size 1, free list len 12, seg size 14, 1118 merges
merged operations:
 insert 1, delete mark 1117, delete 0

4. log buffer

log buffer 的作用是缓存 redo log 的写入操作,考虑到一个大事务,在事务期间可能会有很多次数据库操作,不需要在事务中的每一次操作都写入 redo log,可以缓存一定量的 redo log,在合适的时间进行写盘。

合适的时间取决于 mysql 的配置,0 1 2,默认是 1,1是可以保证 ACID 的,0 和 2 都有可能在极端情况下产生数据丢失。具体 0 1 2 的配置可见:https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit

5. adaptive index

adaptive index 自适应哈希索引,目的是为了提升索引的检索效率,B+ 树的检索时间复杂度是 O(logn),生产上 B+ 树的深度一般是 3-4,而 hash 索引的时间复杂度是 O(1)。

mysql 会默认开启自适应哈希索引,基于mysql 的规则,如果是符合自适应 hash 索引要求的,会在 B+ 树的基础上,建立自适应哈希索引。mysql 建立哈希索引必须是对于这个页的访问模式是一样的并且此处超过一定次数,查询条件必须是等值条件查询,比如 select * from table where a = ? 或者是联合索引 where a=? and b=?。

5.1. adaptive index 锁的问题

因为自适应索引是针对于 B+ 树的索引进行优化,涉及到索引的并发问题,所以 mysql 更新自适应索引时需要获得锁,在 5.7 之前只有一把锁,有性能问题,在之后的更新中加入了分片的概念,默认分片是8个分片,也就是8个锁,提高了并行处理的能力。

5.2. 查看当前 mysql adaptive index

可以通过 show engine innodb status 语句来查看是否开启了自适应哈希索引。

可以看到下面的内容,mysql 默认分片是8个分片,所以看到有8块自适应哈希索引。

以及看到通过自适应哈希索引的查询效率是 0.09,而不通过自适应哈希索引的,即通过 B+ 树查询的效率是 0.15.

INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 1 buffer(s)
Hash table size 34679, node heap has 3 buffer(s)
0.09 hash searches/s, 0.15 non-hash searches/s

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过cfssl自签证书https证书

背景 公司内部自建Web服务,通过自签CA,然后签发https证书 工具地址: GitHub - cloudflare/cfssl: CFSSL: Cloudflares PKI and TLS toolkit 使用步骤: 1. 在release页面中下载最新的二进制包,我使用的是1.5的解压并重命名二进制文件 tar…

Idea集成码云

1:Idea集成码云1.1:IDEA安装码云插件【第一步】Idea 默认不带码云插件, 我们第一步要安装 Gitee 插件。如图所示, 在 Idea 插件商店搜索 Gitee,然后点击右侧的 Install 按钮。安装成功后,重启 Idea。Idea 重…

复旦团队发布国内首个模型MOSS 类ChatGPT

复旦团队发布国内首个模型MOSS 类ChatGPT 首先看到这个标题,还有这个名字,我是正经(zhen jing)的 (bu shi 流浪地球?550W?不了解的可以把550W倒过来写,就懂了 看到新闻里的一些图…

Interview系列 - 07 Java | 集合的快速失败和安全失败机制 | 迭代器类源码 | CopyOnWriteArrayList

文章目录1. 集合的快速失败 (fail-fast)1. 使用增强for遍历集合并使用ArrayList的 remove() 方法删除集合元素2. 使用 forEach 遍历集合并使用ArrayList的 remove() 方法删除集合元素3. 使用迭代器遍历集合并使用ArrayList的 remove() 方法删除集合元素4. 使用迭代器遍历集合并…

人脑脊液的代谢组学研究—标识恶性神经胶质瘤的特征

百趣代谢组学分享,脑疾病病人的脑脊液(CSF)通常用来诊断和监测研究,但是恶性胶质瘤病人脑脊液组成的变化很少被人们所知。该研究作者建立了靶向代谢组学分析方法,采用SRM监测模式,使用正负离子切换的方法在…

MySQL实战之深入浅出索引(上)

1.前言 提到数据库,大家肯定会想到数据库的索引,很多人都知道索引是为了提高查询效率的,那么今天我就给大家讲一下,什么是索引,索引的数据结构是什么,索引是如何工作的。 因为索引的内容比较多&#xff0…

大数据应用要经得起考验,不可盲目跟风_光点科技

一项大数据应用,如果不是经得起推敲的,那就值得怀疑它是不是优秀的大数据应用,是不是有可利用的价值,是不是值得将人力物力财力花费在其中。所以,必须对大数据应用进行必要的筛选,做一定的检验之后才可以做…

vegfr2药物|适应症|市场销售数据-上市药品前景分析

癌症作为人类身体健康的主要威胁,其高死亡率一直是人类死亡的主要原因。尽管人类为控制癌症付出了巨大的努力,然而癌症的发病率和死亡率还是在高速增长。而肺癌、结直肠癌、肝癌和乳腺癌等被认为是癌症死亡的主要因素。而根据科研人员发现,癌…

JavaScript HTML DOM 简介

文章目录JavaScript HTML DOM 简介HTML DOM (文档对象模型)HTML DOM 树查找 HTML 元素通过 id 查找 HTML 元素通过标签名查找 HTML 元素通过类名找到 HTML 元素下面我们将学到如下内容JavaScript HTML DOM 简介 通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素…

高清无码的MP4如何采集?python带你保存~

前言 大家早好、午好、晚好吖 ❤ ~ 又是我,我又来采集小姐姐啦~ 这次我们采集的网站是(看下图): 本文所有模块\环境\源码\教程皆可点击文章下方名片获取此处跳转 话不多少,我们赶快开始吧~ 第三方模块: requests >>> pip install requests 如果安装python第三方模块…

刷题专练之数组移除元素

文章目录前言一、移除元素1.题目介绍2.思路:3.代码二、移动零1.题目介绍2.思路3.代码三、删除有序数组中的重复项1.题目介绍2.思想3.代码四、80. 删除有序数组中的重复项 II1.题目介绍2.思路3.代码4.推荐题解前言 我每个刷题篇的题目顺序都是特别安排的,…

FSM——squirrel状态机使用

FSM——squirrel状态机使用 1 FSM介绍 1.1 概念 FSM(finite state machine):有限状态机 是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。核心内容:有限个状态、通过外部操作引起状态的转移。用来对状态的流转进行解耦&a…

C++031-C++日期模拟

文章目录C031-C日期模拟日期模拟题目描述 给出天数求月份日期题目描述 给出天数求月份日期-倒计时题目描述 求任意日期插值在线练习:总结C031-C日期模拟 在线练习: http://noi.openjudge.cn/ https://www.luogu.com.cn/ 日期模拟 题目描述 给出天数求月…

CSS 网页动画【快速掌握知识点】

目录 前言 一、使用CSS3动画 二、使用CSS过渡 三、使用CSS变换: 前言 CSS是一种用于网页设计和排版的语言,也可以用它来制作网页动画。 一、使用CSS3动画 CSS3引入了动画属性,允许您为元素设置动画效果。您可以使用关键帧来定义动画的开始…

MVP简单模型搭建【架构】

MVP简介 MVP是一种项目架构设计模式(说白了就是我们产品的一种设计方案) 其实MVP本质 就是将View和Model完全隔离,通过Presenter统一调度管理(Presenter扮演着中介的角色)传统的设计思路是我们直接跟房东谈&#xff0…

聊聊动态线程池的9个场景(改进版)

线程池是一种基于 池化思想管理线程 的工具,使用线程池可以减少 创建销毁线程的开销,避免线程过多导致 系统资源耗尽。在 高并发以及大批量 的任务处理场景,线程池的使用是必不可少的。 如果有在项目中实际使用线程池,相信你可能…

数仓模型之维度建模

目录 1、数仓架构原则 2、如何搭建一个好的数仓 2.1 建模方法 2.2 建模解决的痛点 2.3 数仓系统满足的特性 2.4 数仓架构设计 3、维度建模 4、案例 5、问题讨论 今天我们来聊聊在数仓模型中举足轻重的维度建模。 简单而言,数据仓库的核心目标是为展现层提…

Hive学习——开窗函数精讲

目录 一、基于行的窗口函数——行的起点~行的终点 二、基于值的窗口函数——值的起点~值的终点 三、基于分区的窗口函数 四、基于缺省的窗口函数 五、lead与lag 六、first_value和last_value 七、排名函数——rank(113)、dense_rank(112)、row_number(123) 八、NTILE分…

nvm (node版本管理工具)安装的详细步骤,并解决安装过程中遇到的问题

1、下载NVM,跳转下载链接后,如下图,下载红框后解压文件 2、安装 注意:双击安装之后,会有两个地址选择, 1、地址中不能存在空格 2、不要放在C盘中,后面需要改个设置文件,安装到C盘的…

银行家算法

银行家算法 银行家算法是一种用来避免操作系统死锁出现的有效算法,所以在引入银行家算法的解释之前,有必要简单介绍一下死锁的概念。 一、死锁 死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成…