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 6a41900

Browse files
committed
增加锁,日志等内容
1 parent 778503f commit 6a41900

File tree

5 files changed

+50
-0
lines changed

5 files changed

+50
-0
lines changed

‎index.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ include::high-performance-index.adoc[leveloffset=+1]
2121

2222
include::query-optimization.adoc[leveloffset=+1]
2323

24+
include::redo-log.adoc[leveloffset=+1]
25+
26+
include::undo-log.adoc[leveloffset=+1]
27+
2428
include::locks.adoc[leveloffset=+1]
2529

2630
include::sharding.adoc[leveloffset=+1]

‎locks.adoc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,31 @@ AUTO_INCREMENT 有两种实现方式:
4848

4949
=== Record Lock
5050

51+
Record Lock 即是常说的行锁,仅仅把一条记录锁上。
52+
53+
Record Lock 有 S 锁 和 X 锁之分。
54+
55+
[NOTE]
56+
====
57+
S 锁 和 X 锁类似 Java 中的 `ReadWriteLock`,其行为和 `ReentrantReadWriteLock` 几乎一模一样:读读并发、读写互斥、写写互斥。
58+
====
59+
5160
=== 间隙锁 Gap Lock
5261

62+
间隙锁主要是为了解决插入时的幻读问题。由于插入时,还没有数据记录,所以,无法创建该数据对应的 Record Lock。所以,提出了 Gap Lock 锁。
63+
64+
Gap Lock 的作用仅仅是为了防止插入幻影记录而已。
65+
66+
给一条记录加 Gap 锁,则不允许其他事务向这条记录前面的插入新记录。为了解决之后可能插入新记录的问题,可以在索引中最后一条记录所在页面的 `Supremum` 记录(表示该页中最大的记录)上加 Gap 锁,这样就可以阻止其他事务插入新记录了。
67+
5368
=== Next-Key Lock
5469

5570
Next-Key Lock = Record Lock + Gap Lock。
5671

5772
=== 插入意向锁 Insert Intention Lock
5873

74+
在内存中生成的一个锁结构,表示有事务想在某个间隙插入新记录,但是现在处于等待状态。
75+
76+
插入意向锁并不会阻止别的事务继续获取该记录上的任何类型的锁,非常鸡肋。
77+
5978
=== 隐式锁

‎redo-log.adoc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[#redo]
2+
= redo 日志,说到做到
3+
4+
每条记录修改到具体数据表空间,页号,以及每个具体的值(可以是具体的指针地址,也可以是指定字段)。
5+
6+
一批 redo 日志组成一个不可分割的组;多个组对应一条 SQL 语句(比如需要页分裂的悲观插入);多个语句组成一个事务。
7+
8+
对底层页面的一次原子访问过程称为一个 Mini-Transaction,简称 MTR。多个 MTR 组成一个 block;内存中若干个连续的 block,组成一个 log buffer。
9+
10+
11+
12+

‎transaction.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@
1616

1717
在 Read Uncommitted 级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为**脏读(Dirty Read)**。性能不会好太多,但是问题却一大堆,实际应用中一般很少使用。
1818

19+
直接读取记录的最新版本,可能出现脏读、不可重复读和幻读等现象。
20+
1921
=== Read Committed(提交读)
2022

2123
大多数数据库系统的默认隔离级别都是 Read Committed。Read Committed 满足前面提到的隔离性的简单定义:一个事务开始时,只能"看见"已经提交的事务所做的修改。换句话说:一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。有时也叫不可重复读(Nonrepeatable Read)。
2224

25+
在每次执行 `SELECT` 时都生成一个 ReadView,可以避免脏读,但是无法避免不可重复读和幻读。
26+
2327
=== Repeatable Read(可重复读)
2428

2529
Repeatable Read 解决了脏读的问题。但是还是无法解决领一个**幻读(Phantom Read)**问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。InnoDB 和 XtraDB 存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)解决了幻读的问题。
2630

31+
只在第一次执行 `SELECT` 语句时,生成一个 ReadView,可以避免出现脏读、不可重复读和幻读。
32+
2733
=== Serializable(可串行化)
2834

2935
Serializable 是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读问题。简单来说,Serializable 会在读取的每一行数据上都加锁,所以导致大量的超时和锁争用的问题。实际中,极少使用。

‎undo-log.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[#undo]
2+
= undo 日志,后悔药
3+
4+
在更新操作时,会把旧版本写入到 undo 中,最新的记录有一个 `roll_pointer` 指针执行旧版本,各个版本的记录依次用指针链接,组成一个版本链。
5+
6+
查询时生成 ReadView,根据其中的事务 ID 去查找 undo 版本链中的数据,这就是 MVCC 的原理。
7+
8+
删除操作,是先打标;事务提交后,会有专门的清理线程来把记录删除掉。
9+

0 commit comments

Comments
(0)

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