当前位置: 首页 > news >正文

秋招Day14 - MySQL - 事务

MySQL事务的四大特性说一下?

原子性,隔离性(并发执行的事务之间不会相互干扰,解决脏读、不可重复读、幻读),一致性(数据库从一个一致性状态转变到另一个一致性状态,比如转帐后银行的总金额不变),持久性(一旦提交或回滚,对数据库造成的影响是永久的)。

隔离级别是否会脏读是否会不可重复读是否会幻读
Read Uncommitted(读未提交)✅ 可能✅ 可能✅ 可能
Read Committed(读已提交)❌ 不会✅ 可能✅ 可能
Repeatable Read(可重复读)❌ 不会❌ 不会✅ 可能(但 InnoDB 已解决)
Serializable(可串行化)❌ 不会❌ 不会❌ 不会

说一下持久性 

即使数据库发生崩溃,也能回到最近一次提交的状态,因为有redo log记录所有的物理变更 

ACID靠什么保证呢?

原子性靠undo log,隔离性靠MVCC锁机制实现,持久性靠redo log,一致性由其他三大原则共同保证。

详细说说如何保证持久性?

redo log记录事务中所有的变更操作,并在事务提提交时刷盘(如果参数设置正确),这样即使数据库发生了崩溃,重启后也能通过重放redo log恢复脏页数据。

但是,将数据页刷到磁盘的时候,如果发生崩溃,可能会导致数据页不完整,因为MySQL的数据页默认是16KB,而操作系统的页大小一般只有4KB。

为了解决部分写入的问题,MySQL采用了双写机制。脏页刷盘时,先将数据页写到一个双写缓冲区中(2M的连续空间),然后再将其写入磁盘的实际位置(数据页的位置和共享表空间)。

崩溃恢复时,如果发现数据页损坏,会从双写文件中恢复副本,确保数据页的完整性

当涉及主从复制的时候,MySQL通过两阶段提交确保redo log和binlog的一致性,第一阶段将已写入完成的redo log标记为prepare状态,第二阶段写入binlog,再提交redo log为commit状态

崩溃恢复时,如果发现redo log为prepare状态但是binlog中有相应的XID,就会判断事务已经提交,不用回滚;反之会回滚。

如果redo log空间被占用过多,Checkpoint 机制会定期将内存中的脏页刷到磁盘,然后更新checkpoint LSN,这样能减少崩溃恢复时需要处理的 Redo Log 数量。

详细说说如何保证事务隔离性?

主要通过锁机制MVCC多版本控制。

InnoDB的锁机制主要是行锁,分为间隙锁(防止幻读),记录锁和临键锁。

MVCC通过保存数据的历史版本,让读操作不需要加锁也能读取快照,通过undo log实现保存快照

事务会不会自动提交?

每条单独的SQL语句不需要显式定义事务开始和结束,单独的SQL语句本身就是一个事务,执行成功会commit,失败会rollback。

多条SQL语句可以用START TRANSACTION开启事务,最后手动COMMIT提交

A 事务未提交,B 事务上查询到的是旧值还是新值?

快照读当前读的区别

快照读是普通的SELECT,默认不加锁,读取的是当前事务的快照版本,不会阻塞

当前读,比如select for update,事务A提交或回滚之前事务B会阻塞

怎么更改事务的隔离级别?

当前会话:SET SESSION TRANSACTION ISOLATION LEVEL REPETABLE READ

全局:SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITED

事务的隔离级别是如何实现的?

  1. 读未提交隔离级别中,写操作默认会尝试加排它锁(记录锁),但是读操作默认不会尝试加任何锁,也没有MVCC机制,所以不能阻止脏读
  2. 读已提交隔离级别中,写操作默认会尝试加行级排它锁(记录锁),读操作通过MVCC机制读取已经提交的最新版本快照阻止脏读。另外,读已提交每次读取数据前都会生成一个新的ReadView,会读取到其他事务修改后提交的数据,导致数据不一致,也就是不可重复读问题。
  3. 可重复读隔离界别中,通过重复使用ReadView阻止了不可重复读。对于幻读问题,InnoDB也提供了临键锁,锁住当前位置和前面的空隙,来防止别的事务插入新的数据
  4. 串行化级别下,读操作默认加S锁,写操作默认加X锁,除了SS不会冲突,其他任何操作都冲突,事务提交后才会释放锁,事务之间不会产生干扰,所以不会出现脏读、幻读和不可重复读的问题。

请详细说说幻读呢?

幻读就是一个事务能够读取到别的事务提交后新插入的数据,导致在同一个事务中,多次执行同一个范围查询,得到的结果却比之前变多。

幻读可以通过加间隙锁解决。MVCC本质上并不能完全解决幻读问题,因为不能阻止其他事务实际插入数据,虽然快照读并不会读取别的事务新插入的数据,但是后续的当前读操作会导致幻读问题

MVCC了解吗?

多版本并发控制,基于undo log版本链ReadView可见性判断。所有事务共享一个undo log版本链,每次修改数据时都会记录上一个版本到undo log,默认的REPEATABLE READ隔离等级下,每个事务通过复用事务开始时的ReadView,只能看到它开始前已经提交的数据版本。

读写操作相互都不会阻塞,因为读操作默认不会尝试加锁,而是读取快照(可重复读及以下级别) 

每次读取数据时,要用ReadView进行可见性判断(RP下复用,RC下创建新的),ReadView记录了当前活跃的事务id集合、最小活跃事务id,下一个即将要分配的事务id、创建ReadView的事务ID等,通过和数据页undo log版本链中的DB_TRX_ID比较,判断版本对当前事务是否可见。

 

http://www.lqws.cn/news/499177.html

相关文章:

  • Redis哨兵模式深度解析与实战部署
  • 网页动画与交互性:开发者基础指南
  • 基于springboot+uniapp的“川味游”app的设计与实现7000字论文
  • 如何快速判断Excel文档是否被修改过?Excel多版本比对解决方案
  • 操作系统 第九章 部分
  • 线程池 JMM 内存模型
  • PySide环境配置及工具使用
  • 【题解-Acwing】1022. 宠物小精灵之收服
  • 技术逐梦之旅:从C语言到Vue的成长之路
  • LeetCode中K个链表的链接的解法
  • 108页精品PPT | 大型某著名企业能源行业数字化转型汇报方案能源化工数字化转型
  • AI-Sphere-Butler之如何将豆包桌面版对接到AI全能管家~新玩法(一)
  • Redis基本介绍
  • 词编码模型怎么进行训练的,输出输入是什么,标签是什么
  • leetcode:98. 验证二叉搜索树
  • oracle 表空间与实例妙用,解决业务存储与权限处理难题
  • 企业主动风险管理破局供应链“黑天鹅”,善用期货
  • C# Task 模式实现 Demo(含运行、暂停、结束状态)
  • Redis精简总结|一主二从哨兵模式(工作机制)|集群模式|缓存的穿透雪崩击穿
  • 以计数器程序为例,简析JVM内存模型中各部分的工作方式
  • 72-Oralce Temporay tablespace(单实例和多租户下的管理)
  • 互联网大数据求职面试:从Zookeeper到Flink的技术探讨
  • 华为云Flexus+DeepSeek征文|基于Dify构建抓取金融新闻并发送邮箱工作流
  • 实现 “WebView2 获取word选中内容
  • 板凳-------Mysql cookbook学习 (十--9)
  • TCP客户端发送消息失败(NetAssist做客户端)
  • Java底层原理:深入理解JVM内存管理机制
  • 在Springboot项目部署时遇到,centos服务器上,curl请求目标地址不通 ,curl -x 可以请求通的解决办法
  • AWS服务器扩充硬盘
  • 汽车制造领域:EtherCAT转Profinet网关案例全面解析