diff --git a/notes/数据库系统原理.md b/notes/数据库系统原理.md index 1e7520cd..cd13daa5 100644 --- a/notes/数据库系统原理.md +++ b/notes/数据库系统原理.md @@ -14,6 +14,7 @@ * [版本号](#版本号) * [Undo 日志](#undo-日志) * [实现过程](#实现过程) + * [快照读与当前读](#快照读与当前读) * [六、Next-Key Locks](#六next-key-locks) * [Record Locks](#record-locks) * [Grap Locks](#grap-locks) @@ -259,9 +260,7 @@ lock-x(A)...unlock(A)...lock-s(B)...unlock(B)...lock-s(c)...unlock(C)... (Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,它的基本思想是通过保存每个数据行的多个版本,一个事务对数据行做修改时,其它事务可以读取之前的一个版本,并且都是读取相同的版本,从而保证多个事务对同一个数据行读取的结果是一致的。 -InnoDB 的 MVCC 在读取和修改数据行时无需加锁,这属于乐观锁的一种实现。正因为无需加锁,因此性能上也会更好。 - -InnoDB 的 MVCC 可以用于实现提交读和可重复读这两种隔离级别。而对于未提交读隔离级别,它总是读取最新的数据行,无需使用 MVCC;可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。 +用于实现提交读和可重复读这两种隔离级别。而对于未提交读隔离级别,它总是读取最新的数据行,无需使用 MVCC;可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。 ## 版本号 @@ -303,11 +302,31 @@ InnoDB 的 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回 将系统版本号作为更新后的数据行快照的创建版本号,同时将系统版本号作为作为更新前的数据行快照的删除版本号。可以理解为新执行 DELETE 后执行 INSERT。 +## 快照读与当前读 + +快照读读指的是读取快照中的数据,而当前读指的是读取最新的数据。 + +当前读: + +```sql +select * from table ....; +``` + +快照读: + +```sql +select * from table where ? lock in share mode; +select * from table where ? for update; +insert; +update ; +delete; +``` + +引入当前读的目的主要是为了免去加锁操作带来的性能开销,但是快照读需要加锁。 + # 六、Next-Key Locks -以下内容都是针对 MySQL 的 InnoDB 存储引擎来讨论的。 - -MVCC 不能解决幻读问题,Next-Key Locks 就是为了解决这个问题而存在的。在可重复读隔离级别下使用 Next-Key Locks,就可以防止幻读的出现。 +Next-Key Locks 也是 MySQL 的 InnoDB 存储引擎的一种实现。MVCC 不能解决幻读的问题,Next-Key Locks 就是为了解决这个问题而存在的。在可重复读隔离级别下,MVCC + Next-Key Locks,就可以防止幻读的出现。 ## Record Locks @@ -589,3 +608,4 @@ Entity-Relationship,有三个组成部分:实体、属性、联系。 - [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) +- [fd945daf-4a6c-4f20-b9c2-5390f5955ce5.jpg](https://tech.meituan.com/innodb-lock.html)