Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c6cf244

Browse files
新增最新面试资料
1 parent 4748d91 commit c6cf244

File tree

7 files changed

+12997
-1638
lines changed

7 files changed

+12997
-1638
lines changed

‎docs/dataStructures-algorithms/高频算法题目总结.md‎

Lines changed: 6106 additions & 1619 deletions
Large diffs are not rendered by default.

‎docs/database/MySQL面试题一.md‎

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ i++;
197197

198198
如果我们需要避免不可重复读的问题的发生,那么我们可以使用**Next-Key Lock算法**(设置事务的隔离级别为`READ REPEATABLE`)来避免,在MySQL中,不可重复读问题就是Phantom Problem,也就是**幻像问题**
199199

200+
#### 幻读
201+
202+
幻读本质上也属于不可重复读的情况,会话 A 读取某个范围的数据,会话 B 在这个范围内**插入**新的数据,会话 A 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。
203+
200204
#### 丢失更新
201205

202206
**丢失更新:** 指的是一个事务的更新操作会被另外一个事务的更新操作所覆盖,从而导致数据的不一致。在当前数据库的任何隔离级别下都不会导致丢失更新问题,要出现这个问题,在多用户计算机系统环境下有可能出现这种问题。
@@ -233,7 +237,37 @@ i++;
233237

234238
![](http://image.ouyangsihai.cn/Fh1arOgS78BnrjBXKwGw8NSP27uM)
235239

240+
### MVCC 实现原理
241+
242+
在理解 MVCC 的实现原理之前,需要先带大家了解一下 **版本链**
243+
244+
我们都知道,在 InnoDB 每个事务都有一个唯一的事务 ID(transaction id),该 ID 是在启动一个事务时申请的并且严格顺序递增。
245+
246+
另外,数据表中的每行数据都是有多个版本的,每次事务更新都会生成新的版本,并且把本次事务的 transaction id 赋值给这个数据版本的事务 ID(row trx_id)。
247+
248+
除此之外,还有一个 roll_pointer指针,该指针 ROLL_PTR 把一个数据行的所有快照版本记录连接起来。
249+
250+
undo log 的回滚机制也是依靠这个版本链,每次对记录进行改动,都会记录一条undo日志,每条undo日志也都有一个roll_pointer属性(INSERT操作对应的undo日志没有该属性,因为该记录并没有更早的版本),可以将这些undo日志都连起来,串成一个链表,所以现在的情况就像下图一样:
251+
252+
![](http://image.ouyangsihai.cn/Fidy__nsyaUj1N3MGfGlu1hjbYMM)
253+
254+
有了上面的知识储备,所谓的 MVCC(Multi-Version Concurrency Control ,多版本并发控制)指的就是在使用**读已提交(READ COMMITTD)****可重复读(REPEATABLE READ)** 这两种隔离级别的事务在执行普通的 SELECT 操作时访问记录的版本链的过程,这样子可以使不同事务的读-写、写-读操作并发执行,从而提升系统性能。
255+
256+
这两个隔离级别的一个很大不同就是:生成 ReadView 的时机不同,READ COMMITTD 在每一次进行普通 SELECT 操作前都会生成一个 ReadView,而 REPEATABLE READ 只在第一次进行普通 SELECT 操作前生成一个ReadView,数据的可重复读其实就是 ReadView 的重复使用。
236257

258+
#### **ReadView**
259+
260+
MVCC 维护了一个 ReadView 结构,主要包含了当前系统未提交的事务列表 TRX_IDs {TRX_ID_1, TRX_ID_2, ...},还有该列表的最小值 TRX_ID_MIN 和 TRX_ID_MAX。
261+
262+
在进行 SELECT 操作时,根据数据行快照的 TRX_ID 与 TRX_ID_MIN 和 TRX_ID_MAX 之间的关系,从而判断数据行快照是否可以使用:
263+
264+
- TRX_ID < TRX_ID_MIN,表示该数据行快照时在当前所有未提交事务之前进行更改的,因此可以使用。
265+
- TRX_ID > TRX_ID_MAX,表示该数据行快照是在事务启动之后被更改的,因此不可使用。
266+
- TRX_ID_MIN <= TRX_ID <= TRX_ID_MAX,需要根据隔离级别再进行判断:
267+
- 提交读:如果 TRX_ID 在 TRX_IDs 列表中,表示该数据行快照对应的事务还未提交,则该快照不可使用。否则表示已经提交,可以使用。
268+
- 可重复读:都不可以使用。因为如果可以使用的话,那么其它事务也可以读到这个数据行快照并进行修改,那么当前事务再去读这个数据行得到的值就会发生改变,也就是出现了不可重复读问题。
269+
270+
在数据行快照不可使用的情况下,需要沿着 Undo Log 的回滚指针 ROLL_PTR 找到下一个快照,再进行上面的判断。
237271
### 锁相关
238272

239273
> 数据库中锁机制,说说数据库中锁的类型
@@ -258,10 +292,17 @@ InnoDB存储引擎中存在着不同类型的锁,下面一一介绍一下。
258292

259293
为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB存储引擎支持一种额外的锁方式,就称为**意向锁**,意向锁在 InnoDB 中是**表级锁**,意向锁分为:
260294

261-
262295
- 意向共享锁:表达一个事务想要获取一张表中某几行的共享锁。
263296
- 意向排他锁:表达一个事务想要获取一张表中某几行的排他锁。
264297

298+
在存在行级锁和表级锁的情况下,事务 T 想要对表 A 加 X 锁,就需要先检测是否有其它事务对表 A 或者表 A 中的任意一行加了锁,那么就需要对表 A 的每一行都检测一次,这是非常耗时的。
299+
300+
意向锁在原来的 X/S 锁之上引入了 IX/IS,IX/IS 都是表锁,用来表示一个事务想要在表中的某个数据行上加 X 锁或 S 锁。有以下两个规定:
301+
302+
- 一个事务在获得某个数据行对象的 S 锁之前,必须先获得表的 IS 锁或者更强的锁;
303+
- 一个事务在获得某个数据行对象的 X 锁之前,必须先获得表的 IX 锁。
304+
305+
通过引入意向锁,事务 T 想要对表 A 加 X 锁,只需要先检测是否有其它事务对表 A 加了 X/IX/S/IS 锁,如果加了就表示有其它事务正在使用这个表或者表中某一行的锁,因此事务 T 加 X 锁失败。
265306

266307
另外,这些锁之间的并不是一定可以共存的,有些锁之间是不兼容的,所谓**兼容性**就是指事务 A 获得一个某行某种锁之后,事务 B 同样的在这个行上尝试获取某种锁,如果能立即获取,则称锁兼容,反之叫冲突。
267308

@@ -276,6 +317,8 @@ InnoDB存储引擎中存在着不同类型的锁,下面一一介绍一下。
276317

277318
![](http://image.ouyangsihai.cn/Fgf-Pg6JPVJ7CmPyrdcow_5q-VZm)
278319

320+
**注意:** 任意 IS/IX 锁之间都是兼容的,因为它们只表示想要对表加锁,而不是真正加锁。
321+
279322
> MySQL中锁的粒度
280323
281324
在数据库中,锁的粒度的不同可以分为表锁、页锁、行锁,这些锁的粒度之间也是会发生升级的,**锁升级**的意思就是讲当前锁的粒度降低,数据库可以把一个表的1000个行锁升级为一个页锁,或者将页锁升级为表锁,下面分别介绍一下这三种锁的粒度(参考自博客:https://blog.csdn.net/baolingye/article/details/102506072)。
@@ -696,5 +739,45 @@ MyISAM引擎会把表自增主键的最大id记录到数据文件中,做了持
696739

697740
关系型数据库的优势在于支持更加复杂的sql操作、事务支持和使用表结构更加易于维护。
698741

742+
> binlog、redo log和undo log
743+
744+
redo log(重做日志)是InnoDB存储引擎独有的,它让MySQL拥有了崩溃恢复能力。
745+
746+
比如 MySQL 实例挂了或宕机了,重启时,InnoDB存储引擎会使用redo log恢复数据,保证数据的**持久性与完整性**
747+
748+
redo log 记录的是数据的物理变化。
749+
750+
751+
binlog 记录了数据库表结构和表数据变更,比如update/delete/insert/truncate/create。它不会记录select(因为这没有对表没有进行变更),存储着每条变更的SQL语句(当然从下面的图看来看,不止SQL,还有XID「事务Id」等等)。
752+
753+
主要有两个作用:**复制和恢复数据**
754+
755+
- MySQL在公司使用的时候往往都是一主多从结构的,从服务器需要与主服务器的数据保持一致,这就是通过binlog来实现的
756+
757+
- 数据库的数据被干掉了,我们可以通过binlog来对数据进行恢复。
758+
759+
undo log主要有两个作用:**回滚和多版本控制(MVCC)**
760+
761+
在数据修改的时候,不仅记录了redo log,还记录undo log,如果因为某些原因导致事务失败或回滚了,可以用undo log进行回滚
762+
763+
undo log 主要存储的也是**逻辑日志**,比如我们要insert一条数据了,那undo log会记录的一条对应的delete日志。我们要update一条记录时,它会记录一条对应相反的update记录。
764+
765+
这也应该容易理解,毕竟回滚嘛,跟需要修改的操作相反就好,这样就能达到回滚的目的。因为支持回滚操作,所以我们就能保证**原子性**
766+
767+
> mysql 优化思路
768+
769+
https://mp.weixin.qq.com/s/jtuLb8uAIHJNvNpwcIZfpA
770+
771+
https://www.cnblogs.com/jay-huaxiao/p/12995510.html
772+
773+
> mysql 语法和复杂语句练习题
774+
775+
- 常用语法
776+
777+
https://www.jb51.net/article/156898.htm
778+
www.cyc2018.xyz/算法/基础/算法 - 排序.html
699779

780+
- 练习题
700781

782+
https://www.jianshu.com/p/476b52ee4f1b
783+
www.cyc2018.xyz/算法/基础/算法 - 排序.html

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /