auto commit
This commit is contained in:
parent
60e5002cde
commit
34c15646cc
|
@ -14,7 +14,10 @@
|
||||||
* [版本号](#版本号)
|
* [版本号](#版本号)
|
||||||
* [Undo 日志](#undo-日志)
|
* [Undo 日志](#undo-日志)
|
||||||
* [实现过程](#实现过程)
|
* [实现过程](#实现过程)
|
||||||
* [六、间隙锁](#六间隙锁)
|
* [六、Next-Key Locks](#六next-key-locks)
|
||||||
|
* [Record Locks](#record-locks)
|
||||||
|
* [Grap Locks](#grap-locks)
|
||||||
|
* [Next-Key Locks](#next-key-locks)
|
||||||
* [七、关系数据库设计理论](#七关系数据库设计理论)
|
* [七、关系数据库设计理论](#七关系数据库设计理论)
|
||||||
* [函数依赖](#函数依赖)
|
* [函数依赖](#函数依赖)
|
||||||
* [异常](#异常)
|
* [异常](#异常)
|
||||||
|
@ -211,21 +214,21 @@ lock-x(A)...unlock(A)...lock-s(B)...unlock(B)...lock-s(c)...unlock(C)...
|
||||||
|
|
||||||
# 五、多版本并发控制
|
# 五、多版本并发控制
|
||||||
|
|
||||||
(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,它的基本思想是通过保存每个数据行的多个版本,在并发操作控制多个事务访问某个版本,从而保证多个事务对同一个数据行读取的结果是一致的。
|
(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,它的基本思想是通过保存每个数据行的多个版本,一个事务对数据行做修改时,其它事务可以读取之前的一个版本,并且都是读取相同的版本,从而保证多个事务对同一个数据行读取的结果是一致的。
|
||||||
|
|
||||||
InnoDB 的 MVCC 在读取和修改数据行时无需加锁,这属于乐观锁的一种实现。正因为无需加锁,因此性能上也会更好。
|
InnoDB 的 MVCC 在读取和修改数据行时无需加锁,这属于乐观锁的一种实现。正因为无需加锁,因此性能上也会更好。
|
||||||
|
|
||||||
InnoDB 的 MVCC 可以用于实现提交读和可重复读。未提交读总是读取最新的数据行,无需使用 MVCC;而可串行化需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。
|
InnoDB 的 MVCC 可以用于实现提交读和可重复读这两种隔离级别。而对于未提交读隔离级别,它总是读取最新的数据行,无需使用 MVCC;可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。
|
||||||
|
|
||||||
## 版本号
|
## 版本号
|
||||||
|
|
||||||
- 系统版本号:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。
|
- 系统版本号:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。
|
||||||
- 事务版本号:事务开始时的系统版本号。
|
- 事务版本号:事务开始时的系统版本号。
|
||||||
|
|
||||||
InooDB 的 MVCC 在每行记录后面都保存着两个隐藏的列,用来存储来个版本号:
|
InooDB 的 MVCC 在每行记录后面都保存着两个隐藏的列,用来存储两个版本号:
|
||||||
|
|
||||||
- 创建版本号:指示创建一个数据行的快照时的系统版本号;
|
- 创建版本号:指示创建一个数据行的快照时的系统版本号;
|
||||||
- 删除版本号:如果该快照的删除版本号大于当前事务版本号表示该快照有效,否则该快照无法读取。
|
- 删除版本号:如果该快照的删除版本号大于当前事务版本号表示该快照有效,否则表示该快照已经被删除了。
|
||||||
|
|
||||||
## Undo 日志
|
## Undo 日志
|
||||||
|
|
||||||
|
@ -241,9 +244,9 @@ InnoDB 的 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回
|
||||||
|
|
||||||
当开始新一个事务时,该事务的版本号肯定会大于所有数据行快照的创建版本号,理解这一点很关键。
|
当开始新一个事务时,该事务的版本号肯定会大于所有数据行快照的创建版本号,理解这一点很关键。
|
||||||
|
|
||||||
把没对一个数据行做修改的事务称为 T<sub>1</sub>,T<sub>1</sub> 所要读取的数据行快照的创建版本号必须小于当前事务的版本号,因为如果大于或者等于当前事务的版本号,那么该数据行快照是其它事务的最新修改,因此不能去读取它。
|
把没对一个数据行做修改的事务称为 T<sub>1</sub>,T<sub>1</sub> 所要读取的数据行快照的创建版本号必须小于当前事务的版本号,因为如果大于或者等于当前事务的版本号,那么表示该数据行快照是其它事务的最新修改,因此不能去读取它。
|
||||||
|
|
||||||
除了上面的要求,T<sub>1</sub> 所要读取的数据行快照的删除版本号必须小于当前事务版本号,因为如果大于或者等于当前事务版本号,那么该数据行快照是已经被删除的,不应该去读取它。
|
除了上面的要求,T<sub>1</sub> 所要读取的数据行快照的删除版本号必须小于当前事务版本号,因为如果大于或者等于当前事务版本号,那么表示该数据行快照是已经被删除的,不应该去读取它。
|
||||||
|
|
||||||
### 2. INSERT
|
### 2. INSERT
|
||||||
|
|
||||||
|
@ -257,7 +260,49 @@ InnoDB 的 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回
|
||||||
|
|
||||||
将系统版本号作为更新后的数据行快照的创建版本号,同时将系统版本号作为作为更新前的数据行快照的删除版本号。可以理解为新执行 DELETE 后执行 INSERT。
|
将系统版本号作为更新后的数据行快照的创建版本号,同时将系统版本号作为作为更新前的数据行快照的删除版本号。可以理解为新执行 DELETE 后执行 INSERT。
|
||||||
|
|
||||||
# 六、间隙锁
|
# 六、Next-Key Locks
|
||||||
|
|
||||||
|
以下内容都是针对 MySQL 的 InnoDB 存储引擎来讨论的。
|
||||||
|
|
||||||
|
和 MVCC 一样,Next-Key Locks 也是一种实现隔离级别的一种方式。相比于 MVCC,它可以解决幻读问题。
|
||||||
|
|
||||||
|
## Record Locks
|
||||||
|
|
||||||
|
锁定的对象时索引,而不是数据。如果表没有设置索引,InnoDB 会自动在主键上创建隐藏的聚集索引,因此 Record Lock 依然可以使用。
|
||||||
|
|
||||||
|
## Grap Locks
|
||||||
|
|
||||||
|
锁定一个范围内的索引,例如当一个事务执行以下语句,其它事务就不能在 t.c1 中插入 15。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next-Key Locks
|
||||||
|
|
||||||
|
它是 Record Locks 和 Gap Locks 的结合。在 user 中有以下记录:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
| id | last_name | first_name | age |
|
||||||
|
|------|-------------|--------------|-------|
|
||||||
|
| 4 | stark | tony | 21 |
|
||||||
|
| 1 | tom | hiddleston | 30 |
|
||||||
|
| 3 | morgan | freeman | 40 |
|
||||||
|
| 5 | jeff | dean | 50 |
|
||||||
|
| 2 | donald | trump | 80 |
|
||||||
|
+------|-------------|--------------|-------+
|
||||||
|
```
|
||||||
|
|
||||||
|
那么就需要锁定以下范围:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
(-∞, 21]
|
||||||
|
(21, 30]
|
||||||
|
(30, 40]
|
||||||
|
(40, 50]
|
||||||
|
(50, 80]
|
||||||
|
(80, ∞)
|
||||||
|
```
|
||||||
|
|
||||||
# 七、关系数据库设计理论
|
# 七、关系数据库设计理论
|
||||||
|
|
||||||
|
@ -499,3 +544,5 @@ Entity-Relationship,有三个组成部分:实体、属性、联系。
|
||||||
- [三级模式与两级映像](http://blog.csdn.net/d2457638978/article/details/48783923)
|
- [三级模式与两级映像](http://blog.csdn.net/d2457638978/article/details/48783923)
|
||||||
- [Database Normalization and Normal Forms with an Example](https://aksakalli.github.io/2012/03/12/database-normalization-and-normal-forms-with-an-example.html)
|
- [Database Normalization and Normal Forms with an Example](https://aksakalli.github.io/2012/03/12/database-normalization-and-normal-forms-with-an-example.html)
|
||||||
- [The basics of the InnoDB undo logging and history system](https://blog.jcole.us/2014/04/16/the-basics-of-the-innodb-undo-logging-and-history-system/)
|
- [The basics of the InnoDB undo logging and history system](https://blog.jcole.us/2014/04/16/the-basics-of-the-innodb-undo-logging-and-history-system/)
|
||||||
|
- [MySQL locking for the busy web developer](https://www.brightbox.com/blog/2013/10/31/on-mysql-locks/)
|
||||||
|
- [浅入浅出 MySQL 和 InnoDB](https://draveness.me/mysql-innodb)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user