Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/database/mysql/innodb-implementation-of-mvcc.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ tag:
- MySQL
---

## 多版本并发控制 (Multi-Version Concurrency Control)
MVCC 是一种并发控制机制,用于在多个并发事务同时读写数据库时保持数据的一致性和隔离性。它是通过在每个数据行上维护多个版本的数据来实现的。当一个事务要对数据库中的数据进行修改时,MVCC 会为该事务创建一个数据快照,而不是直接修改实际的数据行。

1. 读操作(SELECT):
当一个事务执行读操作时,它会使用快照读取。快照读取是基于事务开始时数据库中的状态创建的,因此事务不会读取其他事务尚未提交的修改。具体工作情况如下:
* 对于读取操作,事务会查找符合条件的数据行,并选择符合其事务开始时间的数据版本进行读取。
* 如果某个数据行有多个版本,事务会选择不晚于其开始时间的最新版本,确保事务只读取在它开始之前已经存在的数据。
* 事务读取的是快照数据,因此其他并发事务对数据行的修改不会影响当前事务的读取操作。
2. 写操作(INSERT、UPDATE、DELETE):
当一个事务执行写操作时,它会生成一个新的数据版本,并将修改后的数据写入数据库。具体工作情况如下:
* 对于写操作,事务会为要修改的数据行创建一个新的版本,并将修改后的数据写入新版本。
* 新版本的数据会带有当前事务的版本号,以便其他事务能够正确读取相应版本的数据。
* 原始版本的数据仍然存在,供其他事务使用快照读取,这保证了其他事务不受当前事务的写操作影响。
3. 事务提交和回滚:
* 当一个事务提交时,它所做的修改将成为数据库的最新版本,并且对其他事务可见。
* 当一个事务回滚时,它所做的修改将被撤销,对其他事务不可见。
4. 版本的回收:
为了防止数据库中的版本无限增长,MVCC会定期进行版本的回收。回收机制会删除已经不再需要的旧版本数据,从而释放空间。

MVCC 通过创建数据的多个版本和使用快照读取来实现并发控制。读操作使用旧版本数据的快照,写操作创建新版本,并确保原始版本仍然可用。这样,不同的事务可以在一定程度上并发执行,而不会相互干扰,从而提高了数据库的并发性能和数据一致性。

## 一致性非锁定读和锁定读

### 一致性非锁定读
Expand Down
2 changes: 2 additions & 0 deletions docs/database/mysql/mysql-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ index = hash % array_size

为了减少 Hash 冲突的发生,一个好的哈希函数应该“均匀地”将数据分布在整个可能的哈希值集合中。

MySQL的InnoDB存储引擎不直接支持常规的哈希索引,但是,InnoDB存储引擎中存在一种特殊的“自适应哈希索引”(Adaptive Hash Index),自适应哈希索引并不是传统意义上的纯哈希索引,而是结合了B+Tree和哈希索引的特点,以便更好地适应实际应用中的数据访问模式和性能需求。自适应哈希索引的每个哈希桶实际上是一个小型的B+Tree结构。这个B+Tree结构可以存储多个键值对,而不仅仅是一个键。这有助于减少哈希冲突链的长度,提高了索引的效率。

既然哈希表这么快,**为什么 MySQL 没有使用其作为索引的数据结构呢?** 主要是因为 Hash 索引不支持顺序和范围查询。假如我们要对表中的数据进行排序或者进行范围查询,那 Hash 索引可就不行了。并且,每次 IO 只能取一个。

试想一种情况:
Expand Down