【Java面试】五、MySQL篇(下)

文章目录

  • 1、事务的特性
  • 2、并发事务问题
  • 3、事务的隔离级别
  • 4、undo log 和 redo log
    • 4.1 底层结构
    • 4.2 redo log
    • 4.3 undo log
  • 5、MVCC
    • 5.1 隐式字段
    • 5.2 undo log 版本链
    • 5.3 ReadView
    • 5.4 ReadView的匹配规则实现事务隔离
  • 6、MySQL的主从同步原理
  • 7、分库分表
    • 7.1 垂直分库
    • 7.2 垂直分表
    • 7.3 水平分库
    • 7.4 水平分表
    • 7.5 分库分表之后的问题
  • 8、面试

在这里插入图片描述

1、事务的特性

一组操作,同成功,同失败。开启事务后,所有操作作为一个整体去提交或撤销。

在这里插入图片描述
事务的特性:ACID

  • 原子性A:事务是最小的操作单元,不可分割
  • 一致性C:事务完成后,所有的数据保持一致的状态
  • 隔离性I:数据库的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
  • 持久性D:落盘,事务一旦提交,改变就是永久的

具体以银行转账的例子描述ACID:A向B转500块,这个操作不可再分割,转账过程,A账户扣除了500,B账户必须增加500,数据要一致。A向B转账的过程中,不能受其他事务和操作的干扰,即隔离性。最后事务提交,数据落盘,即持久化

2、并发事务问题

  • 脏读
  • 不可重复读
  • 幻读

在这里插入图片描述

脏读即:事务B更新了数据,但还没commit,A事务就给读走了

在这里插入图片描述

解决:将隔离级别由读未提交 -> 改为 -> 读已提交

隔离级别改为读已提交后,发现会出现两次读取的结果不一致的情况 ⇒ 不可重复读即:A刚开始读的id=1的数据,值为x,期间事务B又更新并commit了id=1的这条数据,此时A事务第二次读,发现两次数据不一样

在这里插入图片描述

解决:将隔离级别由读已提交 -> 改为 -> 可重复读

改为可重复读的隔离级别后,又出现了幻读 ⇒ 幻读即:事务A先查id=1数据,发现没有。然后准备insert id=1的数据,但期间事务B写入了id=1的数据,事务Ainsert时失败,于是事务A再查id=1数据,发现还是没有(可重复读的隔离级别),事务A自己感觉见鬼了

在这里插入图片描述

3、事务的隔离级别

并发事务有脏读、不可重复读、幻读三个问题。以下四种隔离级别,对应的问题如下:(√即存在这个问题,x即不存在这个问题)

在这里插入图片描述

总之:

  • 读未提交 ⇒ 存在脏读问题
  • 读已提交 ⇒ 存在不可重复读问题(Oracle默认的隔离级别)
  • 可重复读 ⇒ 存在幻读问题(MySQL默认的隔离级别)
  • 串行化 ⇒ 无并发事务的三大问题,但性能不高

4、undo log 和 redo log

4.1 底层结构

缓冲池:

  • buffer pool,主内存的一个区域,里面存了磁盘上经常操作的那些数据
  • 增删改查时,先去缓冲池找,没找到再去磁盘加载
  • 以一定频率把池里的数据刷回磁盘,减少IO次数,提高速度

数据页:

  • InnoDB存储引擎管理磁盘的最小单元
  • 每页大小默认16KB
  • 每页中存的是行数据

在这里插入图片描述

该架构下,存在问题:如果从缓冲池刷数据到磁盘时,磁盘所在服务器宕机或IO异常,缓冲池的数据在内存,断电会丢失 ⇒ redo log

4.2 redo log

  • 重做日志,包括redo log buffer(存缓冲池中)、redo log file(存磁盘中)
  • 用来保证事务的持久性的

增删改的事务提交后,写到缓冲池、缓冲池的redo log、磁盘的redo log,此时缓冲池数据刷回磁盘失败时,可用磁盘的redo log去做恢复。问:你有空往磁盘的redo log写数据,没空直接把增删改的数据写回磁盘吗?⇒ 前者是追加,顺序写,后者是磁盘寻道,随机写,性能差别很大。
在这里插入图片描述
最后,如果缓冲池的数据成功刷回磁盘了,那磁盘里的redo log就没用了,会自动定期清理。

rodo log,简言之,用于保证持久化的,当缓冲池数据刷回磁盘失败时,靠redo log恢复。

4.3 undo log

作用:

  • 用于做回滚
  • 用于MVCC(多版本并发控制)

undo log是逻辑日志,客户端做delete,undo log中记录insert。客户端update,undo log也update,但update成前一版数据。总之就是逆操作。rollback时,执行undo log即可。undo log保证的是事务的一致性和原子性。

5、MVCC

Multi-Version Concurrency Control,多版本并发控制。即维护了一条数据的多个版本,使得并发事务下读写操作没有冲突(读哪个版本,是隔离级别决定的,但多个版本的维护,是MVCC支持的),或者说是保证事务隔离性的。

在这里插入图片描述
MVCC的实现,依赖三个东西:

  • 隐式字段
  • undo log日志
  • readView

5.1 隐式字段

每张表会有三个额外字段:

在这里插入图片描述

一个字段记录最近操作这条数据的事务ID,一个字段记录上一个版本的数据的内存地址:

在这里插入图片描述

5.2 undo log 版本链

insert、update、delete时,产生undo log,用于回滚和版本控制。刚开始的状态:

在这里插入图片描述

事务2修改id = 30数据的age为3,得到版本1的数据,表里的指针指向undo log最开始的初始数据:

在这里插入图片描述

事务3将id = 30数据的name改为A3:此时,表里存第二个版本在undo log的内存地址,这个地址指向undo log里存版本1的数据

在这里插入图片描述

事务4将id = 30数据的age改为10:

在这里插入图片描述

不同事务或者相同事务对同一条记录进行修改,针对该记录,在undo log中生成一条数据记录,并由db_roll_prt字段形成版本链表。链表的头部是最近那个版本的数据,链表尾部是最早的原始数据。

5.3 ReadView

  • 当前读:读取的是记录的最新版本
  • 快照读:读已提交的隔离级别下,每次select,生成一个快照去读。可重复读的隔离级别下,开启事务后的第一个select执行,会记录一个快照,后面每次select都是在这个快照读

ReadView是快照读时,MVCC提取哪个版本数据的依据,记录并维护当前未提交的事务ID。包含字段:

在这里插入图片描述

以下图为例,事务5在第一次读数据的时候:活跃事务Id(即未提交的事务)有三个(3、4、5),因此m_ids数量为3,最小事务ID为3,预分配事务ID为6(5+1),creator_trx_id为5

在这里插入图片描述
不同的隔离级别,生成 ReadView 的时机不同:

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

5.4 ReadView的匹配规则实现事务隔离

前面undo log中生成了一个版本链,而一个事务可以访问哪个版本的数据,由每个版本数据的trx_id和ReadView里的值决定。规则如下(trx_id表示这个版本的数据的db_trx_id):

在这里插入图片描述

以上规则很好理解,比如trx_id < min_trx_id,说明产生这个版本数据的事务ID,比当前未提交的所有事务里面最小的事务ID还要小(事务ID小,说明这个事务开启的早,持续时间更久),即这个版本的数据已经提交了,那当前事务自然是可以访问的。相反trx_id > max_trx_id,说明产生这个版本的事务Id,比所有未提交的事务里最年轻的事务,还要年轻,因此,当前事务不可访问这个版本的数据

读已提交的隔离级别下:

分析事务5的两次查询,其readview如下,每次select都会产生一个select:
在这里插入图片描述

以第一个readview为例:并发事务产生了四个版本的数据,最近的一条数据trx_id为4,带入右边规则:

4 == 5,不成立
4 < 3,不成立
4 > 6,不成立
3 <= 4 <= 6成立,但4345中的一个,整体不成立

都不成立,因此,事务5当前不可以访问这个版本的数据。再看上一个版本的数据,trx_id为3

3 == 5,不成立
3 < 3,不成立
3 > 6,不成立
3 <= 3 <= 6成立,但3345中的一个,整体不成立

都不成立,因此,这个版本的数据,事务5当前还是不能访问。再看上一个版本的数据,trx_id为2

2 == 5,不成立
2 < 3,成立

成立,可以访问。根据读已提交的隔离策略,可以看到。读到的正是事务2提交的那一版,符合"读已提交"的策略。
在这里插入图片描述

同理,事务5在第二次select时,读已提交策略下会生成了新的ReadView,ReadWiew各个字段如图中所标:

在这里插入图片描述
最近的一条数据trx_id为4,带入右边规则:

4 == 5,不成立
4 < 4,不成立
4 > 6,不成立
4 <= 4 <= 6成立,但4345中的一个,整体不成立

都不成立,因此,事务5当前不可以访问这个版本的数据。再看上一个版本的数据,trx_id为3

3 == 5,不成立
3 < 4,成立

因此,当前(第二次select时)事务5可以看到DB_TRX_ID为3的数据,正好是事务3提交的那一版本,符合"读已提交"的策略。最后,看下可重复读事务隔离策略下情况:
在这里插入图片描述

带入4条规则,可以得出,事务5两次select,可以拿到的版本都是事务2提交的那个版本。

由此,可以看到MVCC保证了MySQL事务隔离性。 当然,事务的隔离性还有锁在处理,比如一个事务获取了一行数据的排他锁,那其他事务就不能再获取该行的其他锁,其他事务如果尝试获取这行数据的共享锁或排他锁,都会被阻塞,直到持有排他锁的事务释放锁或事务结束。

6、MySQL的主从同步原理

一个Java服务,配置连接了主库和从库,其中,主库用于写,从库用于读

在这里插入图片描述
主从之间实现数据同步的核心 ⇒ 二进制日志binlog(记录了DDL,如create,以及DML,如insert)

在这里插入图片描述

insert一条数据,实现步骤:

  • insert后,主库将变更写进Binlog
  • 从库有线程IoThread去读主库的Binlog,并将变化写入到从库自己的中继日志Relay Log
  • 从库重做中继日志的时间,使用线程SQLThread进行insert
  • 同步完成

7、分库分表

主从结构下,分担了读数据的压力,但解决不了海量数据的存储问题。 ⇒ 分库分表

需要分库分表的时机:项目的业务数据越来越多或做的产品突然火了,单表数据量达1000万行或者20G以后。此时,正常的SQL优化或者加索引解决不了性能问题。
在这里插入图片描述

拆分策略:

  • 垂直分库
  • 垂直分表
  • 水平分库
  • 水平分表

在这里插入图片描述

7.1 垂直分库

以表为依据,按业务的不同,将不同业务的表分配到不同的库中。不同的微服务,连接自己的库,如下:

在这里插入图片描述

改成多个库,如此,在高并发下,提高了磁盘的IO以及数据库连接数

7.2 垂直分表

以字段为依据,根据字段属性将不同字段拆分到不同表中。拆分规则:

  • 把不常用的字段单独放一个表
  • 把text、blob等大数据类型的字段分出来放到一个附表

如下,商品订单表,id、name、category、brand、title字段,属于常用的字段,List或者点开购物应用就要展示的数据。而description属于点开某个商品看详情的时候才能用到的字段,且属于大字段,可做如下拆分:将description单独分一个表,注意id做关联(注意,下面垂直分表后,图中画的是分后的两个表在两个库,这个没限制,也可能在同一个库):
在这里插入图片描述

如此,冷热数据分离,减少了不必要的IO(在tb_sku表select * 也不会把大字段description从磁盘读出来),两表互不影响。

7.3 水平分库

将一个库的数据拆分到多个库中,表结构一样,存的数据不一样。
在这里插入图片描述
正常一个Java微服务连接一个库,查数据时,想成功路由到数据所在的库,可以考虑:

  • 根据id节点取模
  • 按id也就是范围路由,节点1(1-100万),节点2(100万-200万)

7.4 水平分表

将一个表的数据拆分到多个表中(这几个表也可以放在同一个库)

在这里插入图片描述
数据的查询则和水平分库一样,可以考虑取模。如此,可以解决单一表数据量过大而产生的性能问题。

7.5 分库分表之后的问题

  • 分布式事务一致性问题(一个业务操作,需要更新多个数据库,控制事务,同成功同失败)
  • 跨节点关联查询
  • 跨节点分页、排序函数
  • 主键避重

⇒ 分库分表后,引入分库分表中间件解决以上问题以及路由问题:

  • sharding-sphere
  • mycat

在这里插入图片描述
最后:

  • 水平分库,将一个库的数据拆分到多个库中,解决海量数据存储和高并发的问题
  • 水平分表,解决单表存储和性能的问题
  • 垂直分库,根据业务进行拆分,高并发下提高磁盘IO和网络连接数
  • 垂直分表,冷热数据分离,多表互不影响

8、面试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

Android面试题之Jetpack的三大核心组件

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 ViewModel 和 LiveData 是 Android Jetpack 组件库中的两个核心组件&#xff0c;它们能帮助开发者更有效地管理 UI 相关的数据&#xff0c;并且…

5款免费文字转语音工具,视频剪辑师都在用

随着“行走美丽中国”话题的热度不断攀升&#xff0c;越来越多的人开始将他们游历各地的精彩瞬间制作成视频&#xff0c;并分享至网络。 在众多视频内容中&#xff0c;想要让自己的作品脱颖而出&#xff0c;不仅需要引人入胜的画面&#xff0c;还需要配上生动有趣的配音。 今…

nbcio-vue升级迁移flowable到最新的jeeg-boot-vue3的问题记录(一)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、vue3 jeeg-boot-vue3新版本的流程定义的页面&#xff0c;刷新出现下面问题&#xff0c;或第一次进去也一样 看着好像就一个警告的信息&#xff0c;不知道是什么原因引起的&#xff0c;应…

深度学习-序列模型

深度学习-序列模型 1. 定义2. 应用领域3. 典型模型4. 技术细节5. 总结 序列模型是一种处理序列数据的机器学习模型&#xff0c;其输入和/或输出通常为序列形式的数据。以下是关于序列模型的详细解释&#xff1a; 1. 定义 序列模型是输入输出均为序列数据的模型&#xff0c;它…

期货交易的雷区

一、做自己看不懂的行情做交易计划一样要做有把握的&#xff0c;倘若你在盘中找机会交易&#xff0c;做自己看不懂的行情&#xff0c;即便你做进去了&#xff0c;建仓时也不会那么肯定&#xff0c;自然而然持仓也不自信&#xff0c;有点盈利就想平仓&#xff0c;亏损又想扛单。…

建立SFTP服务器

文章目录 建立SFTP服务器1. 使用VMware安装CentOS 7虚拟机。2. 安装完虚拟机后&#xff0c;进入虚拟机&#xff0c;修改网络配置&#xff08;onboot改为yes&#xff09;并重启网络服务&#xff0c;查看相应IP地址&#xff0c;并使用远程连接软件进行连接。3. 配置yum源&#xf…

【C++练级之路】【Lv.22】C++11——右值引用和移动语义

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、右值引用1.1 左值和右值1.2 左值引用和右值引用的范围1.3 左值引用的意义 二、移动语义2.1 移动构造…

【基础算法总结】前缀和二

前缀和二 1.和为 K 的子数组2.和可被 K 整除的子数组3.连续数组4. 矩阵区域和 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.和为 K 的子数…

哇!数据中台竟是企业数字化转型的关键力量!

在当今数字化浪潮席卷的时代&#xff0c;数据中台正成为企业实现数字化转型的关键力量。那么&#xff0c;究竟什么是数据中台呢&#xff1f;它乃是一种持续让企业数据活跃起来的机制&#xff0c;能够将企业内各部分数据汇聚至一个平台&#xff0c;达成数据的统一化管理。 数据中…

六、Prometheus服务发现

目录 一、prometheus的服务发现 1、基于文件的服务发现 二、基于consul的服务发现 一、prometheus的服务发现 Prometheus默认是采用pull的方式拉取监控数据的&#xff0c;每一个被抓取的目标都要暴露一个HTTP接口&#xff0c;prometheus通过这个接口来获取相应的指标数据&…

LED屏控制卡是如何控制LED屏的?

LED屏控制卡是LED显示屏的关键组件之一&#xff0c;负责将输入的画面信息转换为LED屏能够显示的数据和控制信号。以下是LED屏控制卡的工作原理和功能的详细介绍&#xff1a; 1. LED显示屏控制器概述&#xff1a; LED显示屏控制器是LED显示屏的核心部件之一&#xff0c;也称为LE…

Alamofire常见GET/POST等请求方式的使用,响应直接为json

Alamofire 官方仓库地址&#xff1a;https://github.com/Alamofire/Alamofire xcode中安装和使用&#xff1a;swift网络库Alamofire的安装及简单使用&#xff0c;苹果开发必备-CSDN博客 Alamofire是一个基于Swift语言开发的优秀网络请求库。它封装了底层的网络请求工作&…

亚信安全:2024攻防演练利器之必修高危漏洞合集-百度网盘下载

亚信安全:2024攻防演练利器之必修高危漏洞合集-百度网盘下载. 90% ! 2023攻防演练期间 暴露的web漏洞占比90% 覆盖VPN、远程工具、办公软件 OA系统、聊天工具、安全产品等全路径 100% ! 隐藏在暗处的高危漏洞 一旦被利用&#xff0c;被攻陷率近100% 很多企业为此导致整…

解析新加坡裸机云多IP服务器网线路综合测评解析

在数字化高速发展的今天&#xff0c;新加坡裸机云多IP服务器以其卓越的性能和稳定性&#xff0c;成为了众多企业和个人用户的首选。源库主机评测将对新加坡裸机云多IP服务器的网线路进行综合测评&#xff0c;以帮助读者更深入地了解这一产品的优势。 一、性能表现 新加坡裸机云…

Facebook开户 | Facebook的CTR是什么?

在当今数字化的营销领域&#xff0c;了解和利用各种指标是成功的关键。其中一个关键指标是CTR&#xff0c;即点击率&#xff08;Click-Through Rate&#xff09;。 在Facebook广告中&#xff0c;CTR是一个至关重要的度量标准&#xff0c;它不仅可以衡量广告的效果&#xff0c;还…

OneForall工具的下载安装和使用(Windows和Linux)

目录 OneForall的介绍 OneForall的下载 OneForall的安装 安装要求 安装步骤&#xff08;git 版&#xff09; 安装&#xff08;kali&#xff09; OneForall的使用命令 在Windows 在Linux&#xff08;kali&#xff09; OneForall的结果说明 免责声明 本文所提供的文字和…

安全风险 - 切换后台时背景模糊处理

因为安全风险中提到当app处于后台卡片状态时&#xff0c;显示的卡片页面应该为模糊效果&#xff0c;否则容易泄露用户隐私&#xff0c;尤其当前页涉及个人信息、资产信息等&#xff0c;都会造成信息泄露&#xff01;基于这种场景&#xff0c;我研究了下这种业务下的模糊效果 找…

图像处理中的维度元素复制技巧

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、维度元素复制的基本概念 三、如何实现维度元素复制 1. 方法介绍 2. 代码示…

方正国际金融事业部副总经理白冰受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 方正国际软件&#xff08;北京&#xff09;有限公司金融事业部副总经理白冰先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“浅析多项目管理的成功因素”。大会将于6月29-30日在北京举办&#xff0c;敬请关注&#xf…

flinkcdc 3.0 源码学习之客户端flink-cdc-cli模块

注意 : 本文章是基于flinkcdc 3.0 版本写的 我们在前面的文章已经提到过,flinkcdc3.0版本分为4层,API接口层,Connect链接层,Composer同步任务构建层,Runtime运行时层,这篇文章会对API接口层进行一个探索.探索一下flink-cdc-cli模块,看看是如何将一个yaml配置文件转换成一个任务…