常见面试题-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 进行对比,来判断是否取该行的数据:

  1. 如果 row 的 trx_id < min_trx_id,表示这一行数据的事务 id 比 ReadView 中活跃事务的最小 id 还要小,表示这行数据是已提交事务生成的,因此该行数据可见
  2. 如果 row 的 trx_id > max_id,表示这一行数据是由将来启动的事务生成的,不可见(如果 row 的 trx_id 就是当前事务自己的 id,则可见)
  3. 如果 row 的 min_id <= trx_id <= max_id,则有两种情况:
    1. 如果 trx_id 在 ReadView 的活跃事务 id 数组(m_ids)中,则表明该事务还未提交,则该行数据不可见
    2. 如果不在,则表明该事务已经提交,可见

注意:

  • 执行 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 执行流程:

  1. 加载数据页,把需要修改数据所在的数据页,缓存到 BufferPool,BufferPool 中缓存的其实就是一个个的数据页

  2. 修改前记录,写 undo 日志,记录更改前数据,如果事务执行失败,使用 undo 日志进行数据回滚

  3. 更新 Buffer Pool 中的数据

  4. 准备提交事务,写 redo 日志,保存操作记录。redo 日志用来恢复 BufferPool 中的数据

  5. 准备提交事务,写 bin-log 日志,保存操作记录。bin-log 日志用来恢复磁盘数据

  6. 事务提交完成,此时 bin-log 日志写入成功,并在 redo 日志中记录 commit 标记

    redo 日志作用:恢复 BufferPool 中的数据,bin-log 日志是用于恢复磁盘中的数据,其中 redo 日志和 undo 日志是 InnoDB 引擎特有的,而 bin-log 是属于 Server 层的,与引擎无关

    在 redo 日志中记录 commit 标记是为了保证事务提交之后,redo 与 binlog 数据一致,那么想一下如果 BufferPool 缓存中数据更新完毕,但是在数据库将修改后的数据刷到磁盘之前,数据库宕机了,会不会造成 BufferPool 和磁盘的数据不一致呢?

    其实不会,因此当数据库宕机恢复之后,会使用 redo 日志中的数据恢复 BufferPool 中的数据,那么 BufferPool 的数据就是更新后的数据了,等待刷回磁盘即可

  7. 数据持久化,IO 线程不定期把 Buffer Pool 中的数据随机写入到磁盘,完成持久化

MySQL 的预读机制:

当从磁盘上加载一个数据页时,MySQL 可能会连带着把这个数据页相邻的其他数据页也加载到缓存里去。

触发 MySQL 的预读机制的场景?

  1. 线性预读:参数 innodb_read_ahead_threshold 默认值是 56,表示如果顺序的访问了一个区里的多个数据页,访问的数据页的数量超过了这个阈值,就会触发预读机制,把下一个相邻区中的所有数据页都加载到缓存里去

    查看默认值:show variables like 'innodb_read_ahead_threshold'

    在这里插入图片描述

  2. 随机预读:如果 Buffer Pool 里缓存了一个区里的 13 个连续的数据页,而且这些数据页都是比较频繁会被访问的,此时就会直接触发预读机制,把这个区里的其他的数据页都加载到缓存里去。性能不稳定,在 5.5 中已经被废弃,默认是 OFF

    show 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 中被修改过的缓存页,也称为脏页,脏页都是需要刷回磁盘的)中的缓存页都刷入磁盘中

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

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

相关文章

React中组件之间如何通信?

一、是什么 我们将组件间通信可以拆分为两个词&#xff1a; 组件通信 回顾Vue系列的文章&#xff0c;组件是vue中最强大的功能之一&#xff0c;同样组件化是React的核心思想 相比vue&#xff0c;React的组件更加灵活和多样&#xff0c;按照不同的方式可以分成很多类型的组件…

OpenHarmony,奏响中国基础软件的“光辉岁月”

梦想需要多久的时间&#xff0c;多少血和泪&#xff0c;才能慢慢实现&#xff1f; 天地间任我展翅高飞&#xff0c;谁说那是天真的预言&#xff1f; 《光辉岁月》歌词中的这两个问题&#xff0c;恰好可以送给今天的中国基础软件事业。 曾几何时&#xff0c;我们认为中国基础软件…

AI智能雷达名片平台版小程序源码系统 带完整的搭建教程

大家好啊&#xff0c;今天源码小编来给大家分享一款AI智能雷达名片平台版小程序源码系统。人工智能技术的不断发展和普及&#xff0c;越来越多的企业开始应用AI技术来提高业务效率和提升用户体验。AI智能雷达名片平台版小程序源码系统就是利用人工智能技术&#xff0c;帮助企业…

深入OpenCV Android应用开发

前言 OpenCV是Open Source Computer Vision library(开源的计算机视觉库)的缩写。它是使用最广泛的计算机视觉库。Opencv是计算机视觉领域常用的操作函数的集合&#xff0c;其自身由C/C编写而成&#xff0c;同时也提供了对Python、Java以及任意JVM语言的封装。考虑到大部分And…

华为防火墙ipsec vpn nat穿越2种场景配置案例

第一种方法&#xff0c;出口有nat设备&#xff08;这种方法最后电脑能上网&#xff0c;但不能和对端vpn通&#xff0c;配置检测没发现有问题&#xff0c;待以后再解决&#xff09;&#xff1a; 要实现分部电脑既能访问互联网又能和总部vpn连接 FW_A主要配置&#xff1a; acl …

为什么有的孩子玩着玩着就成了学霸?

毫不夸张地说&#xff0c;几乎所有的父母都想养出聪明宝宝&#xff0c;孩子上学之后能成为学霸就更省心了。 可“聪明”毕竟不能量化&#xff0c;不是说让孩子上几天课就能提升的。很多家长都在促进孩子大脑发育上使足了劲&#xff0c;可到头来却发现是在做“无用功”。 事实…

微服务-网关设计

文章目录 引言I 网关部署java启动jar包II 其他服务部署细节2.1 服务端api 版本号III 网关常规设置3.1 外部请求系统服务都需要通过网关访问3.2 第三方平台回调校验文件的配置IV 微服务日志跟踪4.1 打印线程ID4.2 封装线程池任务执行器4.3 将自身MDC中的数据复制给子线程4.4 微服…

设计模式之观察者(Observer)

事件处理模型 小朋友睡醒了就哭&#xff0c;饿 写程序模拟这个过程&#xff1a; v1:最简单的就是写程序一直观察着&#xff0c;什么时候哭了就进行处理 /*** 披着面向对象外衣的面向过程*/ public class Main1 {public static void main(String[] args) {boolean cry false…

Mabitys总结

一、ORM ORM(Object/Relation Mapping)&#xff0c;中文名称&#xff1a;对象/关系 映射。是一种解决数据库发展和面向对象编程语言发展不匹配问题而出现的技术。 使用JDBC技术时&#xff0c;手动实现ORM映射&#xff1a; 使用ORM时&#xff0c;自动关系映射&#xff1a; &am…

动态表单获取某一项值

<template><div><el-form :model"form" :rules"rules" ref"form"><el-row v-for"(item,index) in form.list" :key"index"><el-col :span"6"><el-form-item label"用户名称…

URI参数在Netty WebSocket中的处理方式,你了解吗?

URI参数传递 概述起因方法1方法2pom 主页传送门&#xff1a;&#x1f4c0; 传送 概述 WebSocket 是 HTML5 中实现实时通信的一种技术&#xff0c;它建立在 HTTP 协议上&#xff0c;但与传统的 HTTP 请求不同&#xff0c;WebSocket 连接一旦建立&#xff0c;就可以在客户端和服…

选择 REST ,还是 GraphQL

在本文中&#xff0c;简单比较 REST 和 GraphQL 的优点和缺点&#xff0c;以便您可以决定哪种 API 架构最适合您的项目 当我们要创建数据驱动的 Web 或移动应用程序&#xff0c;需要开发后台 API&#xff0c;通过它可以从后端服务器来访问或操作数据。目前最流行的 API 架构是…

Flutter的专属Skia引擎解析+用法原理

Skia是一款跨平台的2D图形库&#xff0c;是Google公司开发的&#xff0c;可以用于开发各种应用程序&#xff0c;如浏览器、游戏、移动应用程序等。Skia引擎的主要特点是速度快、可移植性强、占用的内存少、稳定性佳&#xff0c;适用于多种硬件平台。 Skia的目标是提供快速、高…

在Spring Boot中使用MyBatis访问数据库

MyBatis&#xff0c;这个对各位使用Java开发的开发者来说还是蛮重要的&#xff0c;我相信诸位在企业开发项目的时候&#xff0c;大多数采用的是Mybatis。使用MyBatis帮助我们解决各种问题&#xff0c;实际上这篇文章&#xff0c;基本上默认为可以跳过的一篇&#xff0c;但是为了…

什么是代理IP池?如何判断IP池优劣?

代理池充当多个代理服务器的存储库&#xff0c;提供在线安全和匿名层。代理池允许用户抓取数据、访问受限制的内容以及执行其他在线任务&#xff0c;而无需担心被检测或阻止的风险。代理池为各种在线活动&#xff08;例如网页抓取、安全浏览等&#xff09;提高后勤保障。 读完…

使用Python的requests库采集充电桩LBS位置经纬度信息

目录 一、引言 二、采集数据的流程 1、获取充电桩的URL地址 2、发送HTTP请求获取数据 3、解析数据获取经纬度信息 4、存储数据 三、代码实现 四、注意事项和优化建议 五、充电桩数据的后续利用 六、总结 一、引言 随着电动汽车的普及&#xff0c;充电设施的建设也日…

【JavaEESpring】Spring Web MVC⼊⻔

Spring Web MVC 1. 什么是 Spring Web MVC1.1 什么是 MVC ?1.2 是什么 Spring MVC? 2. 学习 Spring MVC2.1 建立连接2.2 请求2.3 响应 3. 相关代码链接 1. 什么是 Spring Web MVC 官⽅对于 Spring MVC 的描述是这样的&#xff1a; 1.1 什么是 MVC ? MVC 是 Model View C…

OpenCV实现手势虚拟拖拽

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 今天来学习一下如何使用OpenCV实现手势虚拟拖拽&#xff0c;欢迎大家一起前来探讨学习~ 一、主要步骤及库的功能介绍 1.主要步骤 要实现本次实验&#xff0c;主要步骤如下&#xff1a; 导入OpenCV库。通过OpenCV读取摄…

中文编程软件视频推荐,自学编程电脑推荐,中文编程开发语言工具下载

中文编程软件视频推荐&#xff0c;自学编程电脑推荐&#xff0c;中文编程开发语言工具下载 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的软件…

使用create-react-app脚手架创建react项目

查看npx版本&#xff1a; npx -v使用如下命令创建项目时&#xff1a; npx create-react-app demo报错&#xff1a; 解决&#xff1a; 以管理员身份运行cmd 然后再次创建项目&#xff0c;又报错&#xff1a; 经查得知&#xff1a;发生此错误是因为用户名中有空格&#xff0c;…