常见面试题-MySQL专栏(三)MVCC、BufferPool
typora-copy-images-to: imgs
了解 MVCC 吗?
答:
MVCC(Multi-Version Concurrency Control) 是用来保证 MySQL 的事务隔离性的,对一行数据的读和写两个操作默认是不会通过加锁互斥来保证隔离性,避免了频繁加锁互斥,而在串行化隔离级别为了保证较高的隔离性是通过将所有操作加锁互斥来实现的。
MySQL 在读已提交和可重复读隔离级别下都实现了 MVCC 机制,ReadView 生成规则为:
- 在读已提交隔离级别下,ReadView 生成的时机是每个 Select 生成一个 ReadView
- 在可重复读隔离级别下,ReadView 生成的时机是每个事务生成一个 ReadView
MVCC 是基于 undolog、版本链、readview 实现的。

在每次更新或者删除数据时,都会将操作记录在 undo 日志中,每条 undo 日志 通过 roll_pointer 进行关联,构成了数据的版本链
ReadView 中包含以下参数:
- m_ids:表示生成 ReadView 时,当前系统中活跃(未提交)的事务 id 数组
- min_trx_id:表示生成 ReadView 时,当前系统中活跃的事务中最小的事务 id,也就是 m_ids 中的最小值
- max_trx_id:表示生成 ReadView 时,已经创建的最大事务 id
(事务创建时,事务 id 是自增的) - creator_trx_id:表示生成 ReadView 的事务的事务 id
那么在事务里的 sql 查询会和 ReadView 进行对比,来判断是否取该行的数据:
- 如果 row 的 trx_id < min_trx_id,表示这一行数据的事务 id 比 ReadView 中活跃事务的最小 id 还要小,表示这行数据是已提交事务生成的,因此该行数据可见
- 如果 row 的 trx_id > max_id,表示这一行数据是由将来启动的事务生成的,不可见(如果 row 的 trx_id 就是当前事务自己的 id,则可见)
- 如果 row 的 min_id <= trx_id <= max_id,则有两种情况:
- 如果 trx_id 在 ReadView 的活跃事务 id 数组(m_ids)中,则表明该事务还未提交,则该行数据不可见
- 如果不在,则表明该事务已经提交,可见
注意:
- 执行 start transaction 之后,并不会立即生成事务 id,而是在该事务中,第一次修改 InnoDB 时才会为该事务生成事务 id
- MVCC 机制就是通过 ReadView 和 undo 日志进行对比,拿到当前事务可见的数据
了解 BufferPool 缓存机制吗?
参考:
https://blog.csdn.net/mingyuli/article/details/120347093
https://www.processon.com/view/6080de691e08534b2ef0218b
答:
Buffer Pool 本质就是数据库的一个内存组件,Buffer Pool 的大小在 /etc/my.cnf 中进行配置:

为什么不直接更新磁盘上的数据,而是需要设置一套复杂的机制来执行 SQL 呢?
因为针对数据库数据的读写其实是随机的读写,而对于日志文件的读写是顺序的读写,而顺序读写和随机读写速度差距在 2~3 个数量级,磁盘的顺序 IO 几乎可以和操作内存相媲美。
通过 BufferPool 可以保证每个更新请求都是更新内存 BufferPool,然后顺序写日志文件,同时可以保证各种异常情况下的数据一致性,正是通过这套配置,才能让我们的 MySQL 数据库在较高配置的机器上每秒可以抗下几千的读写请求
为什么数据库数据的读写是随机 IO 呢?
因为数据库存储在磁盘中的数据是会被删除的,我们在写的时候就算一直顺序写,但是如果后边删除了中间的一些数据,那么在之后读就不能顺序读了,因为中间有一些数据已经不存在了
InnoDB SQL 执行流程:
-
加载数据页,把需要修改数据所在的数据页,缓存到 BufferPool,
BufferPool 中缓存的其实就是一个个的数据页 -
修改前记录,写 undo 日志,记录更改前数据,如果事务执行失败,使用 undo 日志进行数据回滚
-
更新 Buffer Pool 中的数据
-
准备提交事务,写 redo 日志,保存操作记录。redo 日志用来恢复 BufferPool 中的数据
-
准备提交事务,写 bin-log 日志,保存操作记录。bin-log 日志用来恢复磁盘数据
-
事务提交完成,此时 bin-log 日志写入成功,并在 redo 日志中记录 commit 标记
redo 日志作用:
恢复 BufferPool 中的数据,bin-log 日志是用于恢复磁盘中的数据,其中 redo 日志和 undo 日志是 InnoDB 引擎特有的,而 bin-log 是属于 Server 层的,与引擎无关在 redo 日志中记录 commit 标记是为了保证事务提交之后,redo 与 binlog 数据一致,那么想一下如果 BufferPool 缓存中数据更新完毕,但是在数据库将修改后的数据刷到磁盘之前,数据库宕机了,会不会造成 BufferPool 和磁盘的数据不一致呢?
其实不会,因此当数据库宕机恢复之后,会使用 redo 日志中的数据恢复 BufferPool 中的数据,那么 BufferPool 的数据就是更新后的数据了,等待刷回磁盘即可
-
数据持久化,IO 线程不定期把 Buffer Pool 中的数据随机写入到磁盘,完成持久化
MySQL 的预读机制:
当从磁盘上加载一个数据页时,MySQL 可能会连带着把这个数据页相邻的其他数据页也加载到缓存里去。
触发 MySQL 的预读机制的场景?
-
线性预读:参数
innodb_read_ahead_threshold默认值是 56,表示如果顺序的访问了一个区里的多个数据页,访问的数据页的数量超过了这个阈值,就会触发预读机制,把下一个相邻区中的所有数据页都加载到缓存里去查看默认值:
show variables like 'innodb_read_ahead_threshold'
-
随机预读:如果 Buffer Pool 里缓存了一个区里的 13 个连续的数据页,而且这些数据页都是比较频繁会被访问的,此时就会直接触发预读机制,把这个区里的其他的数据页都加载到缓存里去。
性能不稳定,在 5.5 中已经被废弃,默认是 OFFshow variables like 'innodb_random_read_ahead'
LRU 优化——冷热分离

MySQL 通过使用 LRU 来判断哪些缓存页经常访问,哪些缓存页不常访问,来判断当 BufferPool 缓存被占满之后去淘汰哪些缓存页。
在 MySQL 的 LRU 链表中,采取了 冷热数据分离的思想 ,LRU 链表被拆为了两部分,一部分是热数据,一部分是冷数据,冷数据默认占比 37%,由 innodb_old_blocks_pct 参数控制
查看参数:
show variables like 'innodb_old_blocks_pct',默认是37
原理:数据页第一次被加载到缓存页之后,这个缓存页被放在 LRU 链表的冷数据区域的头部,在 1s(可配置) 之后,如果这个缓存页再次配访问,该缓存页才会被移动到热数据区域的头部。
查看参数:
show variables like 'innodb_old_blocks_time',默认是 1000 毫秒(配置多长时间之后访问该缓存页,才将该缓存页加入热数据区域头部)
为什么 LRU 要进行冷热分离?
如果不这样优化,在 LRU 只使用一个链表,那么在预读机制中多加载的一些缓存页,可能就在刚加载进缓存时使用一下,之后就不再使用了,如果被放在 LRU 链表头部了,会将频繁访问的缓存页挤在 LRU 链表尾部,最后被淘汰。预读机制和全表扫描加载进来的一大堆缓存页,此时都在冷数据区域里,跟热数据区域里的频繁访问的缓存页时没有关系的。
LRU 中热数据区域访问的一些优化:
一般在热数据区域头部的缓存页可能是经常被访问的,所以频繁移动性能不太好,所以 MySQL 对于热数据区域的访问优化了一下,只有在热数据区域的后 3/4 部分的缓存页被访问了,才会被移动到链表头部去(这样就
不会出现链表头部数据频繁交替访问,导致频繁移动链表头部数据)。
什么时间将缓存页刷入磁盘呢?
会有一个后台线程运行定时任务,定时将 LRU 链表的冷数据区域尾部的一些缓存页刷入磁盘里去,清空这几个缓存页,将他们加入到 free 链表中(free 链表存放的就是 BufferPool 中的空缓存页的地址)
并且这个后台线程也会在 MySQL 空闲时,将 flush 链表(flush 链表存放的是 BufferPool 中被修改过的缓存页,也称为脏页,脏页都是需要刷回磁盘的)中的缓存页都刷入磁盘中
相关文章:
常见面试题-MySQL专栏(三)MVCC、BufferPool
typora-copy-images-to: imgs 了解 MVCC 吗? 答: MVCC(Multi-Version Concurrency Control) 是用来保证 MySQL 的事务隔离性的,对一行数据的读和写两个操作默认是不会通过加锁互斥来保证隔离性,避免了频…...
CDN加速:国内外价格与企业云服务最佳搭配方案
随着互联网的快速发展,CDN(内容分发网络)已经成为了企业提供高质量、高速度内容传递的不可或缺的工具。CDN通过将内容分发到离用户更近的服务器上,提高了网站性能,减少了加载时间,改善了用户体验。在本文中…...
uni-app小程序使用vant
步骤一:安装 Vant Weapp # 通过 npm 安装 npm i vant/weapp -S --production# 通过 yarn 安装 yarn add vant/weapp --production# 安装 0.x 版本 npm i vant-weapp -S --production步骤二:在根目录下创建“wxcomponents”文件夹 步骤三:找…...
C-DS二叉树_另一棵树的子树
Description 给你两棵二叉树tree1和tree2,检验tree1中是否包含和tree2具有相同结构和结点值的子树。如果存在,输出true;否则,输出false。 Input 第一行输入t,表示有t个测试样例。 第二行首先输入n1,接着输入n1个整数,表示二叉树tree1。 第三行首先输入n2,接着输入n…...
祝贺璞华大数据产品入选中国信通院“铸基计划”
武汉璞华大数据技术有限公司HawkEye设备数字化管理平台产品,凭借优秀的产品技术能力,通过评估后,入选中国信通院“铸基计划”《高质量数字化转型产品及服务全景图(2023)》的工业数字化领域。 “铸基计划”是中国信通院推出的高质量…...
WebDAV之π-Disk派盘 + MiXplorer
MiXplorer是一款非常强大实用的手机文档管理器,能给用户提供了一系列的文档处理功能,包括本地文件浏览、文件排序、文件筛选、切换视图、新建文件、添加收藏等等,同时还能将你手机里的所有文件都罗列出来,简洁明了,让用户一眼就能够找到相应的文件并对其进行编辑,或是删除…...
java依赖的jar包下载
不需要依赖maven,直接下载jar。 仓库服务...
苹果加大对印度的扶持,提高在其生产iphone的比重
KlipC报道:跟踪苹果产业链,有分析师预计2023年全球约12%-14%的iphone在印度生产,预计2024年,印度将生产20%-25%的iphone。 KlipC的合伙人Andi D表示:“近年来随着苹果对中国的以来,印度已经成为高科技制造和…...
【漏洞复现】typecho_v1.0-14.10.10_unserialize
感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 漏洞利用GetShell 下载链接:https://pan.baidu.com/s/1z0w7ret-uXHMuOZpGYDVlw 提取码:lt7a 首页 漏洞点:/install.php?finish 漏洞利用 …...
Linux常见面试题
1、 冯诺依曼体系的要点是: 数字计算机的数制采用二进制,bit 位, byte 字节 1 byte 8 bit计算机应该按照程序顺序执行计算机硬件由运算器、控制器、存储器、输入设备和输出设备五大部分组成 2、计算机的硬件五个组件 控制器: 指挥系统运算器: 数学和逻…...
HarmonyOS ArkTS基础知识
概述 上一节,学习了TypeScript的基础语法,而在鸿蒙开发当中,有基于自己的编程语言,便是ArkTS。它是一种声明式UI的编程范式的语言,开发框架如下图所示: 根据框架图,分析,我将它大致…...
嵌入式课后习题第一章解答
嵌入式系统是一种以应用为中心,以计算机技术为基础,软/硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机。它与通用PC的区别主要体现在以下几个方面: 应用针对性:嵌入式系统是专为特定应…...
postMessage
A:端口3000 import React, { useEffect } from react;function App() {useEffect(() > {const childWindow document.getElementById(child).contentWindow;const sendMessageToChild () > {childWindow.postMessage("主页面消息", "http://localhost:…...
挑战100天 AI In LeetCode Day01(1)
挑战100天 AI In LeetCode Day01(1) 一、LeetCode介绍二、LeetCode 热题 HOT 100-12.1 题目2.2 题解 三、面试经典 150 题-13.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站,提供各种算法和数据结构的题目,面向程序…...
大数据疫情分析及可视化系统 计算机竞赛
文章目录 0 前言2 开发简介3 数据集4 实现技术4.1 系统架构4.2 开发环境4.3 疫情地图4.3.1 填充图(Choropleth maps)4.3.2 气泡图 4.4 全国疫情实时追踪4.6 其他页面 5 关键代码最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 大数据疫…...
uniapp调起拨打手机号
您可以使用uniapp提供的API来调起拨打手机号的功能。具体步骤如下: 在template标签内添加一个按钮,例如: <template><view><button type"primary" click"callPhone">拨打客服电话</button><…...
nacos配置中心docker部署、配置及 goLang 集成使用
为什么需要配置中心 平时我们写一个demo的时候,或者说一个单体的应用,都会有一个配置文件,不管是 json文件或者yaml文件,里面包含了redis,mysql,es等信息,如果我们修改了配置文件,往往我们需要重启&#x…...
PubDef:使用公共模型防御迁移攻击
对抗性攻击对机器学习系统的可靠性和安全性构成了严重威胁。通过对输入进行微小的变动,攻击者就可以导致模型生成完全错误的输出。防御这种攻击是一个很活跃的研究领域,但大多数提议的防御措施都存在重大的缺点。 这篇来自加州大学伯克利分校研究人员的…...
【QT5之QFtp模块】编译及使用
下载 传送门:https://github.com/qt/qtftp 或者 git clone https://github.com/qt/qtftp.git 下载ZIP,解压待用。 编辑 使用QtCreator打开qtftp.pro; 修改如下: qtftp.pro中,将第21行注释; src/qftp.pro中,将第4行…...
数据结构 编程1年新手视角的平衡二叉树AVL从C与C++实现②
接下来,是数据的插入 我们需要对数据插入的结点先进行判断,有如下三个情况 当插入的数据value<结点的value,应该递归地插入该结点的左子树(的左子树...的左子树) 当插入的数据value>结点的value,应…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
