4面试题--数据库(补充)

隔离性问题

若不考虑隔离性则会出现以下问题
1. 脏读:指⼀个事务在处理数据的过程中,读取到另⼀个 未提交 事务的数据
2. 不可重复读:指对于数据库中的某个数据(同⼀个数据项),⼀个事务内的多次查询却返回了不同
的结果。这是由于在查询过程中,数据被另外⼀个事务修改并 提交 了。可通过 锁⾏ 解决
3. 幻读:指事务⾮独⽴执⾏时发⽣的⼀种现象。例如事务T1对⼀个表中所有的⾏的某个数据做了修改,这时事务T2⼜向这个表中插⼊了⼀⾏数据项,⽽这个数据项的数据是以修改前的值 提交 到数据库的。⽽操作事务T1的⽤户如果查看刚刚修改的数据,会发现还有⼀⾏没有修改,其实这⾏是事务T2刚刚添加的,就好像产⽣幻觉⼀样,这就是幻读(针对⼀整批数据,即数据的个数)。可通过锁表 解决
Next-Key锁解决幻读
为了解决“当前读”中的幻读问题,MySQL事务使⽤了Next-Key锁。Next-Key锁是⾏锁和间隙锁的合并。间隙锁指的是锁加在不存在的空闲空间,可能是第⼀个索引记录之前或最后⼀个索引之后的空间。当InnoDB扫描索引记录的时候,会⾸先对选中的索引记录加上⾏锁,再对索引记录两边的间隙(向左扫描扫到第⼀个⽐给定参数⼩的值, 向右扫描扫描到第⼀个⽐给定参数⼤的值, 然后以此为界,构建⼀个区间)加上间隙锁。如果⼀个间隙被事务T1加了锁,其它事务是不能在这个间隙插⼊记录的。这样就 防⽌了幻读

隔离级别

1. 读未提交(Read uncommitted):这种事务隔离级别下,select 语句不加锁。可能读到不⼀致的数据,即脏读。这是并发最⾼,⼀致性最差的隔离级别。
2. 读已提交(Read committed):每次查询返回当前的快照。有不可重复读的问题。
3. 可重复读(Repeatable read):多次读取同⼀范围的数据会返回第⼀次查询的快照。MySQL默认隔离级别。
4. 串⾏化(Serializable):InnoDB 隐式地将全部的查询语句加上共享锁,解决了幻读的问题
读已提交、可重复读实现⽅式:MVCC。

4.7 数据库中的锁

按锁的粒度划分:
表级锁:表级锁分为表共享锁和表独占锁。表级锁开销⼩,加锁快,锁定粒度⼤,发⽣锁冲突最
⾼,并发度最低
⻚级锁:⻚级锁是MySQL中锁定粒度介于⾏级锁和表级锁中间的⼀种锁,⼀次锁定相邻的⼀组记录。
⾏级锁:⾏级锁分为共享锁和排他锁。⾏级锁是MySQL中锁定粒度最细的锁。InnoDB引擎⽀持⾏级锁和表级锁,只有在通过索引条件检索数据的时候,才使⽤⾏级锁,否就使⽤表级锁。⾏级锁开销⼤,加锁慢,锁定粒度最⼩,发⽣锁冲突的概率最低,并发度最⾼。
按锁级别划分:
共享锁:共享锁⼜叫读锁,如果事务T对A加上共享锁,则其他事务只能对A再加共享锁,不能加其他锁。共享锁的事务只能读数据,不能写数据。
排它锁:排他锁⼜叫写锁,如果事务T对A加上排它锁,则其他事务都不能对A加任何类型的锁。获得排它锁的事务既能读数据,⼜能写数据
意向锁:意向锁是⼀种不与⾏级锁冲突的表级锁。意向锁是由数据库引擎⾃⼰维护的,⽤户⽆法⼿动操作意向锁,在为数据⾏加共享 / 排他锁之前,InnoDB 会先获取该数据⾏所在数据表的对应意向锁。意向锁的⽬的是为了快速判断表⾥是否有记录被加锁。

意向锁(Intention Locks)

意向锁分为两种:
意向共享锁(intention shared lock, IS):事务有意向对表中的某些⾏加共享锁(S锁)。事务要获取某些⾏的 S 锁,必须先获得表的 IS 锁。
意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些⾏加排他锁(X锁)。事务要获取某些⾏的 X 锁,必须先获得表的 IX 锁。
注意
上图的排他 / 共享锁指的都是表锁!!!意向锁不会与⾏级的共享 / 排他锁互斥!!!
意向锁在保证并发性的前提下,实现了⾏锁和表锁共存且满⾜事务隔离性的要求。
事务 B 检测到事务 A 持有某表的意向排他锁,就可以得知事务 A 必然持有该表中某些数据⾏的排他锁,那么事务 B 对该表的加锁请求就会被排斥(阻塞),⽽⽆需去检测表中的每⼀⾏数据是否存在排他锁。

多版本并发控制(MVCC)

        

MySQL 的⼤多数事务型存储引擎实现的都不是简单的⾏锁。⽽是基于提升并发性能的考虑,实现了多版本并发控制(MVCC)。可以认为,MVCC是⾏锁的⼀个变种,但它在很多情况下避免了加锁操作,减少了开销。MVCC实现了⾮阻塞的读操作,写操作也只锁定必要的⾏。

MVCC 实现⽅式:Read View

Read View 有四个重要的字段:
creator_trx_id :指的是创建该 Read View 的事务的事务 id。
m_ids :指的是在创建 Read View 时,当前数据库中「活跃事务」的事务 id 列表,“活跃事务”指
的就是启动了但还没提交的事务。
min_trx_id :指的是在创建 Read View 时,当前数据库中「活跃事务」中事务 id 最⼩的事务,也
就是 m_ids 的最⼩值。
max_trx_id :这个并不是 m_ids 的最⼤值,⽽是创建 Read View 时当前数据库中应该给下⼀个事
务的 id 值,也就是全局事务中最⼤的事务 id 值 + 1;
对于使⽤ InnoDB 存储引擎的数据库表,它的聚簇索引记录中都包含下⾯两个隐藏列:
trx_id,当⼀个事务对某条聚簇索引记录进⾏改动时,就会把该事务的事务 id 记录在 trx_id 隐藏列
⾥;roll_pointer,每次对某条聚簇索引记录进⾏改动时,都会把旧版本的记录写⼊到 undo ⽇志中,然后这个隐藏列是个指针,指向每⼀个旧版本记录,于是就可以通过它找到修改前的记录。
在创建 Read View 后,⼀个事务去访问记录的时候,除⾃⼰的更新记录总是可⻅之外,还有如下情况:如果当前⾏的 trx_id 值⼩于 Read View 中的 min_trx_id 值,表示这个版本的记录是在创建 Read View 前已经提交的事务⽣成的,所以该版本的记录对当前事务可⻅。
如果当前⾏的 trx_id 值⼤于等于 Read View 中的 max_trx_id 值,表示这个版本的记录是在创建
Read View 后启动的事务⽣成的,所以该版本的记录对当前事务不可⻅。
如果当前⾏的 trx_id 值在 Read View 的 min_trx_id 和 max_trx_id 之间,需要判断 trx_id 是否
在 m_ids 列表中:- 如果当前⾏的 trx_id 在 m_ids 列表中,表示⽣成该版本记录的活跃事务依然活跃着(还没提交事务),所以该版本的记录对当前事务不可⻅。
- 如果当前⾏的 trx_id 不在 m_ids列表中,表示⽣成该版本记录的活跃事务已经被提交,所以该
版本的记录对当前事务可⻅。
当记录不可⻅时会通过roll_pointer指针找到可⻅的第⼀个记录读取。这种通过「版本链」来控制并发事务访问同⼀个记录时的⾏为就叫 MVCC(多版本并发控制)。
读已提交隔离级别是在每次读取数据时,都会⽣成⼀个新的 Read View。意味着,事务期间的多次读取同⼀条数据,前后两次读的数据可能会出现不⼀致,因为这期间另外⼀个事务可能修改了该记录,并提交了事务。 可重复读 隔离级别是在执⾏第⼀个查询语句后⽣成⼀个 Read View,然后整个事务期间都在⽤这个

Read View

快照读与当前读
1. 快照读:读取历史数据的⽅式,如普通的select语句。
2. 当前读:读取数据库当前版本数据的⽅式,是特殊的读操作。插⼊、更新、删除操作,都属于当前读,处理的都是当前的数据,需要加锁。不过 select .. for update 语句就不是快照读了,⽽是当
前读了。

4.8 查询优化⽅法

避免向数据库请求不需要的数据
在访问数据库时,应该只请求需要的⾏和列。请求多余的⾏和列会消耗MySql服务器的CPU和内存资源,并增加⽹络开销。避免使⽤ SELECT * 这种⽅式进⾏查询,应该只返回需要的列。例如在处理分⻚时,应该使⽤ LIMIT 限制MySql只返回⼀⻚的数据,⽽不是向应⽤程序返回全部数据后,再由应⽤程序过滤不需要的⾏。
优化查询数据的⽅式
查询数据的⽅式有全表扫描、索引扫描、范围扫描、唯⼀索引查询、常数引⽤等。这些查询⽅式,速度从慢到快,扫描的⾏数也是从多到少。可以通过 EXPLAIN 语句中的 type 列反应查询采⽤的是哪种⽅式。
通常可以通过添加合适的索引改善查询数据的⽅式,使其尽可能减少扫描的数据⾏,加快查询速
度。例如,当发现查询需要扫描⼤量的数据⾏但只返回少数的⾏,那么可以考虑使⽤覆盖索引,即
把所有需要⽤到的列都放到索引中。这样存储引擎⽆须回表获取对应⾏就可以返回结果了。
当⼀⾏数据被多次使⽤时可以考虑将数据⾏缓存起来,避免每次使⽤都要到MySql查询。
update 语句应使⽤索引查询,否则全表查询会对所有记录加锁(⾮表锁),甚⾄导致业务停滞。分解查询
可以将⼀个⼤查询切分成多个⼩查询执⾏,每个⼩查询只完成整个查询任务的⼀⼩部分,每次只返回⼀⼩部分结果
分解关联查询,即对每个要关联的表进⾏单表查询,然后将结果在应⽤程序中进⾏关联。优化 LIMIT 分⻚
● 处理分⻚会使⽤到 LIMIT,当翻⻚到⾮常靠后的⻚⾯的时候,偏移量会⾮常⼤,这时LIMIT的效率 ⾮常差。例如对于LIMIT 10000,20这样的查询,MySql需要查询10020条记录,将前⾯10000条记 录抛弃,只返回最后的20条。这样的代价⾮常⾼,如果所有的⻚⾯被访问的频率都相同,那么这样 的查询平均需要访问半个表的数据。优化此类分⻚查询的⼀个最简单的办法就是尽可能地使⽤索引 覆盖扫描,⽽不是查询所有的列。然后根据需要与原表做⼀次关联操作返回所需的列。对于偏移量 很⼤的时候,这样的效率提升⾮常⼤。
优化 UNION 查询
除⾮确实需要服务器消除重复的⾏,否则⼀定要 使⽤UNION ALL。如果没有ALL关键字,MySql会给临时表加上 DISTINCT 选项,这会导致对整个临时表的数据做唯⼀性检查。这样做的代价⾮常⾼。
group by 查询原理:
在MySQL 中,GROUP BY 的实现同样有多种(三种)⽅式,其中有两种⽅式会利⽤现有的索引信息来完成 GROUP BY,另外⼀种为完全⽆法使⽤索引的场景下使⽤。GroupBy会默认按照分组的字段进⾏排序;如果不需要排序,可使⽤order by null
使⽤松散(Loose)索引扫描实现 GROUP BY
MySQL 完全利⽤索引扫描来实现GROUP BY ,并不需要扫描所有满⾜条件的索引键即可完成操作得出结果。Extra信息中显示:Using index for group-by 要利⽤到松散索引扫描实现 GROUP BY,需要⾄少满⾜以下⼏个条件:
GROUP BY 条件字段必须在同⼀个索引中最前⾯的连续位置;
在使⽤GROUP BY 的同时,只能使⽤ MAX 和 MIN 这两个聚合函数;
如果引⽤到了该索引中 GROUP BY 条件之外的字段条件的时候,必须以常量形式存在; 松散索引扫描需要读取的键值数量与分组的数量⼀样多,尽可能读取最少数量的关键字。
使⽤紧凑(Tight)索引扫描实现 GROUP BY 和松散索引扫描的区别是需要读取所有满⾜条件的索引值,之后取数据完成操作。Extra中不显示for group-by,在 MySQL 中,⾸先会选择尝试通过松散索引扫描来实现 GROUP BY 操作,当发现某些情况⽆法满⾜松散索引扫描实现 GROUP BY 的要求之后,才会尝试通过紧凑索引扫描来实现。(⽐如GROUP BY 条件字段并不连续或者不是索引前缀部分的时候)使⽤临时表实现 GROUP BY 当⽆法找到合适的索引可以利⽤的时候,就不得不先读取需要的数据,然后通过临时表来完成 GROUP BY 操作。Extra:Using temporary; Using filesort。

union、join 区别

1. union 在数据库运算中会过滤掉重复数据,并且合并之后是根据⾏合并的;
2. union all 不对数据进⾏过滤重复数据处理;
3. union 之后列数不变(两张表 union 保证列数和列结构⼀样 join 是进⾏表关联运算的,两个表要有⼀定的关系(某列可连接)。根据某⼀列进⾏笛卡尔运算和条件过滤,如果A表有3列,B表有3列,join 之后可能是5列。

mysql 深度分⻚

mysql 分⻚查询是我们常⻅的需求,但是随着⻚数的增加查询性能会逐渐下降,尤其是到深度分⻚的情况。可以把分⻚分为两个步骤,1.定位偏移量,2.获取分⻚条数的数据。所以当数据较⼤⻚数较深时就涉及⼀次需要耗费较⻓时间的操作。所以mysql深度分⻚的问题该如何解决呢 ?
以结果作为条件,已查询条件的变化换取分⻚的不变。分⻚查询⼀般都是逐渐往后翻⻚的,那么可以很清晰的知道,在当前查询⻚的最后⼀条数据的位置,那么,以此位置再查询N条,以位置的推移换取⻚数的不变,减少其偏移量的计算。
采⽤⼦查询模式,其原理依赖于覆盖索引,当查询的列均是索引字段时,性能较快,因为其只⽤遍历索引本身。针对复杂的查询逻辑,⼀般从数据的 偏移量着⼿,减少偏移量的定位时间。
简单的查询逻辑,可以从索引覆盖的思想着⼿,先确定查询数据的主键id,再由id找相关的数据。

4.9 主从复制

具体详细过程如下:
MySQL 主库在收到客户端提交事务的请求之后,会先写⼊ binlog,再提交事务更新存储引擎中的数据,事务提交完成后,返回给客户端“操作成功”的响应。
从库会创建⼀个专⻔的 I/O 线程,连接主库的 log dump 线程,来接收主库的 binlog ⽇志,再把
binlog 信息写⼊ relay log 的中继⽇志⾥,再返回给主库“复制成功”的响应。
从库会创建⼀个⽤于回放 binlog 的线程,去读 relay log 中继⽇志,然后回放 binlog 更新存储引
擎中的数据,最终实现主从的数据⼀致性。
在完成主从复制之后,你就可以在写数据时只写主库,在读数据时只读从库,这样即使写请求会锁表或者锁记录,也不会影响读请求的执⾏。
从库是不是越多越好?不是的。因为从库数量增加,从库连接上来的 I/O 线程也⽐较多,主库也要创建同样多的 log dump 线程来处理复制的请求,对主库资源消耗⽐较⾼,同时还受限于主库的⽹络带宽。所以在实际使⽤中,⼀个主库⼀般跟 2~3 个从库(1 套数据库,1 主 2 从 1 备主),这就是⼀主多从的 MySQL 集群结构。MySQL 主从复制还有哪些模型?
同步复制:MySQL 主库提交事务的线程要等待所有从库的复制成功响应,才返回客户端结果。这种⽅式在实际项⽬中,基本上没法⽤,原因有两个:⼀是性能很差,因为要复制到所有节点才返回
响应;⼆是可⽤性也很差,主库和所有从库任何⼀个数据库出问题,都会影响业务。
118 119
异步复制(默认模型):MySQL 主库提交事务的线程并不会等待 binlog 同步到各从库,就返回客
户端结果。这种模式⼀旦主库宕机,数据就会发⽣丢失。
半同步复制:MySQL 5.7 版本之后增加的⼀种复制⽅式,介于两者之间,事务线程不⽤等待所有的从库复制成功响应,只要⼀部分复制成功响应回来就⾏,⽐如⼀主⼆从的集群,只要数据成功复制到任意⼀个从库上,主库的事务线程就可以返回给客户端。这种半同步复制的⽅式,兼顾了异步复制和同步复制的优点,即使出现主库宕机,⾄少还有⼀个从库有最新的数据,不存在数据丢失的⻛险。

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

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

相关文章

ICPC合肥退役小记

退役了。 现在我坐在合肥回济南的高铁上,外面天都黑了,刚刚刷小红书刷到一句话,“后来啊,一个清晨,大雾散尽,不止清晨,不止大雾”。 遗憾必然是有的。从大一开始每天熬夜刷题打cf…

电子学会C/C++编程等级考试2021年09月(三级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:余数相同问题 已知三个正整数 a,b,c。 现有一个大于1的整数x,将其作为除数分别除a,b,c,得到的余数相同。 请问满足上述条件的x的最小值是多少? 数据保证x有解。输入: 一行,三个不大于1000000的正整数a,b,c,两个整数…

Linux系统---僵尸进程、孤儿进程

顾得泉:个人主页 个人专栏:《Linux操作系统》 《C/C》 键盘敲烂,年薪百万! 有了上一篇博客的学习,我们已经简单了解了进程的基础知识,今天我们再来学习两个特殊的进程,僵尸进程和孤儿进程。 …

【虚拟机】在VM中安装 CentOS 7

1.2.创建虚拟机 Centos7是比较常用的一个Linux发行版本,在国内的使用比例还是比较高的。 大家首先要下载一个Centos7的iso文件,我在资料中给大家准备了一个mini的版本,体积不到1G,推荐大家使用: 我们在VMware《主页》…

【docker系列】docker高阶篇

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

主机怎么通过命令行方式向虚拟机传输文件

这是几个月前遇到的问题了,那时候想着要记录下来,但后来忙忘了,这次想起来了,于是记录一下。 之前打靶场的时候需要将netcat-win32-1.12放入虚拟机的/var/www/html下,但是我虚拟机无法上网,也就是说无法直…

【算法】装备合成(二分)

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 牛牛有x件材料a和y件材料b,用2件材料a和3件材料b可以合成一件装备,用4件材料a和1件材料b也可以合成一件装备。牛牛想要最大化合成的装备的数量,于是…

TPLink-Wr702N 通过OpenWrt系统打造打印服务器实现无线打印

最近淘到了一个TPLink-Wr702N路由器,而且里面已经刷机为OpenWrt系统了,刚好家里有一台老的USB打印机,就想这通过路由器将打印机改为无线打印机,一番折腾后,居然成功了,这里记录下实现过程,为后面…

【第二部分:结构】ARM Realm Management Monitor specification

目录 概念Realm概述Realm执行环境Realm寄存器Realm内存Realm处理器功能IMPDEF系统寄存器 Realm属性Realm活性Realm生命周期状态状态转换 Realm参数Realm描述符 颗粒Granule颗粒属性颗粒所有权颗粒生命周期状态状态转换颗粒抹除 Realm执行上下文概述REC属性REC指数和MPIDR值REC生…

8.前端--CSS-文本属性【2023.11.26】

CSS Text(文本)属性可定义文本的外观,比如文本的颜色、对齐文本、修饰文本、文本缩进、行间距等 1.文本颜色 color 属性用于定义文本的颜色。 语法: div { color: red; }属性: 2.文本对齐 text-align 属性用于设置元…

阿里云MQTT: 子设备上线流程

0. 背景 阿里云网关子设备上平台的资料很少。有些厂家直接配置每个子设备的DeviceSecret到网关里,显然太麻烦了!我经过阅读阿里文档,发现有些简化的方法,更便于客户使用,因此分享给大家。 1. 主要信息片段 子设备 $…

Spring RabbitMQ那些事(2-两种方式实现延时消息订阅)

目录 一、序言二、死信交换机和消息TTL实现延迟消息1、死信队列介绍2、代码示例(1) 死信交换机配置(2) 消息生产者(3) 消息消费者 3、测试用例 三、延迟消息交换机实现延迟消息1、安装延时消息插件2、代码示例(1) 延时消息交换机配置(2) 消息生产者(3) 消息消费者 3、测试用例 …

C语言:有一篇文章,共三行文字,每行有80个字符。要求分别统计出单词个数、空格数。

分析&#xff1a; #include<stdio.h>&#xff1a;这是一个预处理指令&#xff0c;将stdio.h头文件包含到程序中&#xff0c;以便使用输入输出函数。 int main()&#xff1a;这是程序的主函数&#xff0c;是程序执行的入口点。 char a[3][80];&#xff1a;定义了一个二维…

Java之API(上):Boolean

一、前言&#xff1a; 上次我们将到了 java.lang.* 下的包装类&#xff1a;Integer。这次我讲一下基本数据类型中的&#xff1a;布尔型&#xff08;boolean&#xff09;对应的包装类&#xff08;Boolean&#xff09;。注意&#xff1a;还有对包装类&#xff1a;Integer进行一些…

PCIE链路训练-状态机描述4

Recovery Recovery.RcvrLock &#xff08;1&#xff09;如果link是在8.0GT/s或以上的速率工作&#xff0c;那么rx只会认为当前lane获得Block alignment之后收到的TS0&#xff0c;TS1&#xff0c;TS2是有效的。如果进入当前状态是从L1或recovery.speed或L0s&#xff0c;获取Blo…

redis报错3

INFO: Initializing SpringDispatcherServletdispatcherServlet

Echarts title标题配置项的使用 更改颜色 副标题

title配置项主要是对图表的标题进行配置 title配置项所有属性文档 title&#xff1a; { ...... }设置标题 副标题 text: 简单创建柱形图,//图表标题 subtext: 副标题,如果想对副标题设置 超链接 边框 颜色 宽度…等 比如&#xff1a;设置超链接 sublink:‘…’, 设置标题位置…

nodejs+vue+python+PHP+微信小程序-婚纱摄影预约系统的设计与实现-安卓-计算机毕业设计

本婚纱摄影预约系统主要包括个人中心、套系风格管理、用户管理、摄影师管理、婚纱套系管理、婚纱套系订单管理、客片欣赏管理、客户样片管理、摄影咨询管理、客户选片管理、系统管理等多个模块。它帮助婚纱摄影预约实现了信息化、网络化&#xff0c;通过测试&#xff0c;实现了…

Vue+ElementUI+C#技巧分享:周数选择器

文章目录 前言一、周数的计算逻辑1.1 周数的定义1.2 年初周数的确定1.3 周数的计算方法 二、VueElementUI代码实现2.1 计算周数2.2 获取周的日期范围2.3 根据周数获取日期范围2.4 控件引用2.4.1 控件引用代码分析2.4.2 初始化变量代码分析 2.5 周数选择器完整代码 三、C#后端代…

Java8实战-总结49

Java8实战-总结49 CompletableFuture&#xff1a;组合式异步编程对多个异步任务进行流水线操作构造同步和异步操作将两个 CompletableFuture 对象整合起来&#xff0c;无论它们是否存在依赖 CompletableFuture&#xff1a;组合式异步编程 对多个异步任务进行流水线操作 构造同…