面试笔记——MySQL(事务:事务特性、并发事务、事务隔离、Redo Log与Undo Log、MVCC)

事务

概念与特性

事务(Transaction)指的是一组数据库操作,这些操作要么全部成功执行,要么全部不执行,保证了数据库的一致性和完整性,它使得数据库操作可以按照逻辑上的单元进行组织和执行,提高了数据的可靠性和可维护性。事务通常具有以下四个特性,通常被称为ACID属性:

  1. 原子性(Atomicity):事务中的所有操作要么全部执行成功,要么全部不执行,即事务是一个不可分割的最小执行单元。如果事务中的任何一部分操作失败,整个事务都将被回滚(Rollback),数据库状态将会恢复到事务开始前的状态,保持数据的一致性。

  2. 一致性(Consistency):事务执行的结果必须使数据库从一个一致性状态转变到另一个一致性状态。这意味着事务必须满足数据库的约束和规则,如唯一性约束、外键约束等。

  3. 隔离性(Isolation):多个事务同时并发执行时,每个事务都应该被隔离开来,互相不受影响。即使有多个事务同时修改同一数据,它们之间也不能相互干扰,每个事务应该感知不到其他事务的存在。

  4. 持久性(Durability):一旦事务提交(Commit),其所做的修改将会永久保存在数据库中,即使系统发生故障,数据也不会丢失。数据库系统通常通过将事务日志写入持久存储介质(如磁盘)来实现持久性。

并发事务

并发事务可能引发的问题:脏读、不可重复读、幻读
通过隔离级别解决上述问题:读未提交、读已提交、可重复读、串行化

问题描述
脏读一个事务读到另外一个事务还没有提交的数据。
不可重复读在一个事务中,同一查询多次执行却得到了不同的结果。
幻读在一个事务中,同一查询多次执行却得到了不同数量的结果。

脏读
假设有两个事务,事务 A 读取了事务 B 修改但尚未提交的数据,然后事务 B 回滚了修改,那么事务 A 所读取的数据就是不正确的,因为它读取到了未提交的、“脏”的数据。脏读可能导致读取到不一致的数据,降低了数据的可靠性。
在这里插入图片描述
不可重复读
假设事务 A 在执行查询时读取了某一行数据,然后事务 B 修改了这行数据并提交了事务,之后事务 A 再次执行相同的查询,此时得到的数据就可能与之前不同,导致了不一致的读取结果。这种情况下,事务 A 的读操作就发生了不可重复读。不可重复读可能破坏了事务的隔离性。
在这里插入图片描述
幻读
假设事务 A 在执行一个范围查询时,得到了一些行,然后事务 B 在执行 INSERT 或 DELETE 操作,导致事务 A 再次执行相同的查询时得到了不同的行数,就发生了幻读。幻读可能会导致在同一事务中看到不一致的数据,破坏了事务的隔离性。

还有一种情况——在解决了不可重复读问题的背景下,事务A想要在数据库中添加id为1的数据,首先它会查询是否存在id为1的数据,此时的查询结果是没有;在事务A进行插入操作之前,事务B向数据库中插入了id为1的数据并提交;当事务A再进行插入操作时,就会报错;事务A再次查询数据,但查询结果和第一次查询一致(表示没有该数据),此时就出现了幻读:
在这里插入图片描述

假设有一个银行账户表,其中有两个账户:账户A和账户B。

  1. 脏读:假设账户A的余额为1000元,事务A读取了账户A的余额,此时账户A的余额为1000元。然后事务B修改了账户A的余额为2000元,但尚未提交。此时,事务A再次读取账户A的余额,就会读到未提交的“脏”数据2000元,而实际上账户A的余额还是1000元。

  2. 不可重复读:假设事务A读取了账户A的余额为1000元,然后事务B将账户A的余额修改为2000元并提交。接着,事务A再次读取账户A的余额,此时读取到的余额为2000元,与之前的结果不同。

  3. 幻读:假设事务A执行了一个范围查询,查询所有余额大于1000元的账户,此时得到了账户A和账户B两个结果。然后事务B插入了一笔新的账户记录,使得账户C的余额也大于1000元。接着,事务A再次执行相同的查询,却得到了账户A、账户B和账户C三个结果,出现了幻读现象。

事务隔离

隔离级别脏读不可重复读幻读
Read uncommitted 未提交读
Read committed 读已提交×
Repeatable Read(MySQL默认) 可重复读××
Serializable 串行化×××

注意:事务隔离级别越高(上表中,隔离级别有上到下依次增高),数据越安全,但是性能越低。MySQL默认隔离级别是可重复读

Redo Log与Undo Log

缓冲池(buffer pool):是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。
数据页(page):是InnoDB 存储引擎磁盘管理的最小单元,每个页的大小默认为 16KB。页中存储的是行数据。
图1:
在这里插入图片描述
当我们操作数据的时候(如上图中的update,delete语句),并不是直接操作磁盘,而是首先去操作内存(缓冲池)。当一个操作被提交后,会先查询缓冲池中是否存在需要操作的数据。若没有,则从磁盘中将数据加载到内存(将数据所在的某页数据存储在缓冲池)。当缓冲池中有数据,则在操作完数据之后,按一定的频率将缓冲池的数据同步到磁盘中。以此减少磁盘的I/O,加快处理速度。

以上方法虽然提高了效率,但也存在一些问题。例如,当操作完数据后,缓冲区里面的已有新的数据页,但还并未同步到磁盘中,此时缓冲区里面的数据页称为脏页。若数据还未完成同步,而服务器发生宕机,那么内存中的数据就会丢失,已经操作完成的数据(在缓存中)也会丢失,因此违背了事务的持久化的特性。

Redo Log(重做日志):记录的是事务提交时数据页的物理修改,是用来实现事务的持久性
该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中, 用于在刷新脏页到磁盘,发生错误时, 进行数据恢复使用。
图2:
在这里插入图片描述
当进行数据操作时,缓冲池中的数据发生了变化,同时Redo Log buffer 中会记录这些数据页的变化,一旦Redo Log buffer 中发生变化,就会同步把这些数据记录到磁盘文件中。若对脏页中的数据进行同步失败时,就会从Redo Log中同步数据。

ps:在磁盘中,Redo log file实际有两份,他们是循环写的。有两份Redo log file的原因:

  1. 容错和可靠性:有两份Redo Log文件可以提高数据库的容错能力。如果一份Redo Log文件发生损坏或丢失,数据库可以继续正常运行并使用另一份Redo Log文件来进行恢复。这样可以避免因为单点故障导致的数据丢失或数据库无法启动等问题。

  2. 性能和并发:两份Redo Log文件可以提高并发性能。MySQL的Redo Log是循环写入的,当一个Redo Log文件写满时,数据库会切换到另一份Redo Log文件,这样可以避免写操作的阻塞,提高了并发处理能力。

  3. 恢复速度:当数据库需要进行恢复操作时,拥有两份Redo Log文件可以加快恢复的速度。数据库可以同时使用两份Redo Log文件进行恢复操作,从而加快了恢复的速度,减少了系统 downtime。

关于通过日志同步数据(图2),而不是采用直接同步数据(图1)的问题?
因为操作数据的时候,可能有多条记录(包含大量的操作)。而将数据同步到磁盘的时候,都是随机磁盘I/O,因此同步数据的性能是非常低的。如果使用Redo Log,在进行日志文件同步的时候是顺序磁盘I/O(因为日志文件是以追加的形式添加的数据),因此同步日志文件的性能会提升很多。所以,采用Redo Log方式同步。这种方式也称为WAL。

这部分可与Redis中的双写一致性联系https://blog.csdn.net/Z__XY_/article/details/136820674?spm=1001.2014.3001.5501。

补充:

  1. 随机磁盘I/O

    • 随机磁盘I/O指的是对磁盘上的数据进行随机的读取或写入操作,即访问不连续的数据块。
    • 随机磁盘I/O的特点是磁盘臂需要频繁地移动,寻找数据所在的位置,因此会导致磁盘的寻道时间增加,I/O性能相对较低。
  2. 顺序磁盘I/O

    • 顺序磁盘I/O指的是对磁盘上的数据进行顺序的读取或写入操作,即按照数据在磁盘上的物理顺序进行访问。
    • 顺序磁盘I/O的特点是磁盘臂不需要频繁移动,可以顺序地读取连续的数据块,因此具有较高的I/O性能,能够充分利用磁盘的吞吐能力。

Undo Log(回滚日志): 用于记录数据被修改前的信息 , 作用包含两个 : 提供回滚 和 MVCC(多版本并发控制) 。undo log和redo log记录物理日志不一样,它是逻辑日志,它保证了事务的原子性和一致性

  • 可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,
  • 当update一条记录时,它记录一条对应相反的update记录。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

Undo Log与Redo Log的区别总结如下:

  • Undo日志记录了事务对数据库的修改操作的逆操作(记录的是逻辑日志),用于回滚操作和MVCC,保证事务的原子性和一致性
  • Redo日志记录了事务对数据库的修改操作的正向操作(记录的是数据页的物理变化),用于恢复数据库的持久性,保证事务的持久性
  • Undo日志记录旧值,Redo日志记录新值。
  • Undo日志的主要目的是回滚,而Redo日志的主要目的是恢复。
  • Undo日志通常与事务数据绑定,Redo日志通常是独立的。
MVCC

MVCC(Multi-Version Concurrency Control,多版本并发控制),指维护一个数据的多个版本,使得读写操作没有冲突。当一个事务执行写操作时,数据库系统会为其创建一个新版本,并将该版本标记为最新版本。其他事务仍然可以读取旧版本的数据,直到该版本被清除或过期。
MVCC的具体实现,主要依赖于数据库记录中的3个隐式字段、undo log、readView。

隐藏字段
如图:
在这里插入图片描述

隐藏字段含义
DB_TRX_ID最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID。
DB_ROLL_PTR回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。
DB_ROW_ID隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。

undo log

  • 回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。
  • 当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。
  • 而update、delete的时候,产生的undo log日志不仅在回滚时需要,mvcc版本访问也需要,不会立即被删除。

undo log版本链:
不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。
如图1——事务2对数据进行修改:
在这里插入图片描述
然后,事务3又对同一个数据进行修改:
在这里插入图片描述

随后,事务4对同一数据进行修改:
在这里插入图片描述
此时得到一个undo log版本链。

Readview
ReadView(读视图)是 快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id。

  • 当前读

    • 读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select … lock in share mode(共享锁),select … for update、update、insert、delete(排他锁)都是一种当前读。
    • 如下图,事务A分别使用操作1和操作3查询id为1的数据,事务B在事务A执行操作1、3之间进行了数据修改操作,那么事务A在操作3拿到的是修改后的最新数据:
      在这里插入图片描述
  • 快照读

    • 简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
    • Read Committed:每次select,都生成一个快照读,即,每次读到的都是最细数据。
    • Repeatable Read:开启事务后第一个select语句才是快照读的地方,解决了可重复读的问题。

ReadView维护的事务包含了一下四个核心字段:
在这里插入图片描述
下图中展示了4个事务在不同时刻的操作:
在这里插入图片描述
如果在事务5的sql语句——“查询id为30的记录”时刻,此时readview中记录核心字段的组成——m_ids:事务3、4和5(事务2在此刻之前已经提交了事务);min_trx_id:事务3;max_trx_id:事务6(当前最大事务是5);creator_trx_id:事务5(因为在该事务中进行的查询操作,说明在该事务中创建的readview)。

readview为了能够在快照读中读取最准确的数据,定义了以下规则(还是用上面的事务5作为创建事务id为例):
在这里插入图片描述

  • 针对①,说明事务5 可以访问 自己更改的数据;
  • 针对②,当前最小的活跃事务id是事务3,比事务3小的事务id则是事务2,说明该事务已经提交了,则事务5也能访问事务2修改的数据;
  • 针对③,事务5的id小于事务6,则说明 不能访问 事务6更改后的数据;
  • 针对④,判断事务id 大于等于最小活跃事务id,且小于等于预分配事务id,且不在m_ids中,这表示事务5能已提交的事务修改后的数据。(举例:若事务4在事务5的第一条查询语句之前完成事务提交,则说明事务5可以访问事务4修改后的数据。)

不同的隔离级别,生成ReadView的时机不同:

  • READ COMMITTED :在事务中每一次执行快照读时生成ReadView。
  • REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

RC隔离级别下,在事务中每一次执行快照读时生成ReadView。 如图:
在这里插入图片描述
事务5在第一次查询时,可以访问事务2更改后的数据(从上到下依次将事务id带入版本链数据访问规则进行判断,如——针对事务4:①事务4不等于事务5;②事务4大于最小活跃事务(事务id为3);③事务4<小于预分配事务id(id为6);④事务4虽在最小活跃事务id和预分配事务id范围内,但它同时数据m_ids,因此不能访问事务4。其他事务按相同的方式判断):
在这里插入图片描述

事务5在第二次查询,可以访问事务3更改后的数据:
在这里插入图片描述

RR隔离级别下,仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。 如图:
在这里插入图片描述

MVCC机制的优点包括:

  • 提高了并发性:多个事务可以同时读取和修改数据库,而不会相互阻塞,提高了数据库的并发处理能力。
  • 避免了读写冲突:通过使用快照读和版本控制,MVCC可以避免读写冲突,提高了系统的稳定性和可靠性。
  • 支持一致性读取:MVCC保证了读取操作可以读取到一致性的数据快照,即使在并发写入的情况下也能保持一致性。

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

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

相关文章

中等职业学校大数据课程建设方案

大数据产业是以数据及数据所蕴含的信息价值为核心生产要素&#xff0c;通过数据技术、数据产品、数据服务等形式&#xff0c;使数据与信息价值在各行业经济活动中得到充分释放的赋能型产业。 大数据产业定义一般分为核心业态、关联业态、衍生业态三大业态。 一、专…

Nginx实现原理全解析:构建高效Web服务器的关键

1、Nginx是什么 Nginx&#xff08;engine X&#xff09;是一个开源的轻量级的HTTP服务器&#xff0c;能够提供高性能的HTTP和反向代理服务。与传统的Apache服务器相比&#xff0c;在性能上Nginx占用系统资源更小、支持高并发&#xff0c;访问效率更高&#xff1b;在功能上&…

Doris实战——工商信息查询平台的湖仓一体建设

目录 前言 一、架构1.0&#xff1a;传统Lambda架构 二、OLAP引擎调研 三、架构2.0&#xff1a;数据服务层All in Apache Doris 四、架构 3.0&#xff1a;基于Doris Multi-Catalog的湖仓一体架构 五、实践经验 5.1 引入Merge-on-Write&#xff0c;百亿级单表查询提速近三…

谷歌DeepMind推出3D游戏AI代理SIMA,实现自然语言操控游戏新纪元

近日&#xff0c;谷歌DeepMind研究团队推出了一款名为SIMA的创新AI代理&#xff0c;专为3D游戏环境设计。这款代理独树一帜&#xff0c;无需访问游戏源代码或依赖定制API&#xff0c;仅通过输入图像和简单的自然语言文本指令&#xff0c;便能实现与人类玩家相当的游戏操作。 AI…

LangChain教程 | langchain 文件加载器使用教程 | Document Loaders全集

提示&#xff1a; 想要了解更多有关内置文档加载器与第三方工具集成的文档&#xff0c;甚至包括了&#xff1a;哔哩哔哩网站加载器、区块链加载器、汇编音频文本、Datadog日志加载器等。 本文主要收集与讲解日常使用的加载器&#xff0c;足够咱们平时开发人工智能的工作使用&am…

【前端性能】前端性能指标和测量方法总结

文章目录 前端性能指标和测量方法总结重要指标名词概念指标测量方法performance APIChrome PerformanceChrome Lighthouseweb-vitals 前端性能指标和测量方法总结 重要指标名词概念 图源 https://dev.to/xnimorz/hitchhiker-s-guide-to-frontend-performance-optimization-460…

计算机+任何行业都等于王炸!

最近笔者刷到一则消息&#xff0c;一位测试员在某乎上分享&#xff0c;从月薪5K到如今的20K&#xff0c;他总共跳了10次槽&#xff0c;其中还经历过两次劳动申诉&#xff0c;拿到了大几万的赔偿&#xff0c;被同事们称为“职场碰瓷人”。 虽说这种依靠跳槽式的挣钱法相当奇葩&a…

Java微服务分布式事务框架seata的TCC模式

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…

鸿蒙ArkTS实战开发-Native XComponent组件的使用

介绍 本篇Codelab主要介绍如何使用XComponent组件调用NAPI来创建EGL/GLES环境&#xff0c;实现在主页面绘制一个正方形&#xff0c;并可以改变正方形的颜色。本篇CodeLab使用Native C模板创建。 如图所示&#xff0c;点击绘制矩形按钮&#xff0c;XComponent组件绘制区域中渲…

Sketch软件:重塑UI/UX设计流程的革命性工具

Sketch是一款在Mac操作系统上运行的矢量图形设计软件&#xff0c;其功能特色丰富多样&#xff0c;深受设计师们的喜爱。以下是Sketch软件的主要功能特色介绍&#xff1a; 专业矢量图形设计&#xff1a;Sketch为UI设计、移动应用设计和Web设计等领域提供了强大的支持。它支持线条…

探索ChatGPT时代下的下一代信息检索系统:机遇与挑战

1 Introduction 2022 年 11 月 30 日&#xff0c;OpenAI 推出了 ChatGPT&#xff0c;这是一款由先进的 GPT3.5 和更高版本的 GPT-4 生成语言模型提供支持的 AI 聊天机器人应用程序。该应用迅速吸引了全球超亿用户&#xff0c;创下了产品快速传播的新纪录。 它能够以对话的方式…

ElasticSearch 用法

首先讲下 ES的倒排序索引 创建倒排索引是对正向索引的一种特殊处理&#xff0c; 将每一个文档的数据利用算法分词&#xff0c;得到一个个词条 创建表&#xff0c;每行数据包括词条、词条所在文档id、位置等信息 因为词条唯一性&#xff0c;可以给词条创建索引&#xff0c;例如…

旅游小程序开发的费用及功能

随着科技的发展和智能手机的普及&#xff0c;越来越多的行业开始利用小程序来进行线上服务。旅游业作为一个重要的服务业&#xff0c;也纷纷推出了自己的旅游小程序&#xff0c;以方便游客在线预订、查询景点信息等。那么&#xff0c;旅游小程序开发的费用是多少&#xff1f;功…

Google研究者们提出了VLOGGER模型

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【探索Linux】—— 强大的命令行工具 P.29(网络编程套接字 —— 简单的TCP网络程序模拟实现)

阅读导航 引言一、TCP协议二、TCP网络程序模拟实现1. 预备代码⭕ThreadPool.hpp&#xff08;线程池&#xff09;⭕makefile文件⭕打印日志文件⭕将当前进程转变为守护进程 2. TCP 服务器端实现&#xff08;TcpServer.hpp&#xff09;3. TCP 客户端实现&#xff08;main函数&…

babyos 学习记录

宏定义头文件 将一个宏定义取不同的数据到不同的数组中&#xff1b; 侵入式链表 struct list_head { struct list_head *next, *prev; }; // 添加&#xff08;list_add_tail/list_add&#xff09;、删除、查找 xx.h // 定义一个用于链表管理的结构体 typedef sturct{ xxx …

matlab矩形薄板小挠度弯曲有限元编程 |【Matlab源码+理论文本】|板单元| Kirchoff薄板 | 板壳单元

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

分库分表场景下多维查询解决方案(用户+商户)

在采用分库分表设计时&#xff0c;通过一个PartitionKey根据散列策略将数据分散到不同的库表中&#xff0c;从而有效降低海量数据下C端访问数据库的压力。这种方式可以缓解单一数据库的压力&#xff0c;提升了吞吐量&#xff0c;但同时也带来了新的问题。对于B端商户而言&#…

Layui实现删除及修改后停留在当前页

1、功能概述&#xff1f; 我们在使用layui框架的table显示数据的时候&#xff0c;会经常的使用分页技术&#xff0c;这个我们期望能够期望修改数据能停留在当前页&#xff0c;或者删除数据的时候也能够停留在当前页&#xff0c;这样的用户体验会更好一些&#xff0c;但往往事与…

硬核分享|如何将文字转成语音对视频进行配音或旁白解说

硬核分享|如何将文字转成语音对视频进行配音或旁白解说_哔哩哔哩_bilibili 文字转语音工具成为了一种便利而实用的技术应用&#xff0c;它能够将文字内容转化为声音&#xff0c;为我们提供全新的听觉体验。 不论是在阅读、学习、娱乐还是无障碍辅助等方面&#xff0c;文字转语…