[docs update]图片转存

This commit is contained in:
guide 2022-05-25 18:00:26 +08:00
parent 37e7a76f83
commit feca67f4fc
16 changed files with 26 additions and 27 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -74,7 +74,7 @@ private:
**事务可见性示意图**[图源](https://leviathan.vip/2019/03/20/InnoDB%E7%9A%84%E4%BA%8B%E5%8A%A1%E5%88%86%E6%9E%90-MVCC/#MVCC-1)
![trans_visible](https://leviathan.vip/2019/03/20/InnoDB%E7%9A%84%E4%BA%8B%E5%8A%A1%E5%88%86%E6%9E%90-MVCC/trans_visible.jpg)
![trans_visible](./images/mvvc/trans_visible.png)
### undo-log
@ -89,17 +89,17 @@ private:
**`insert` 时的数据初始状态:**
![](https://ddmcc-1255635056.file.myqcloud.com/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png)
![](./images/mvvc/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png)
2. **`update undo log`** `update` 或 `delete` 操作中产生的 `undo log`。该 `undo log`可能需要提供 `MVCC` 机制,因此不能在事务提交时就进行删除。提交时放入 `undo log` 链表,等待 `purge线程` 进行最后的删除
**数据第一次被修改时:**
![](https://ddmcc-1255635056.file.myqcloud.com/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png)
![](./images/mvvc/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png)
**数据第二次被修改时:**
![](https://ddmcc-1255635056.file.myqcloud.com/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png)
![](./images/mvvc/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png)
不同事务或者相同事务的对同一记录行的修改,会使该记录行的 `undo log` 成为一条链表,链首就是最新的记录,链尾就是最早的旧记录。
@ -107,9 +107,9 @@ private:
`InnoDB` 存储引擎中,创建一个新事务后,执行每个 `select` 语句前都会创建一个快照Read View**快照中保存了当前数据库系统中正处于活跃(没有 commit的事务的 ID 号**。其实简单的说保存的是系统中当前不应该被本事务看到的其他事务 ID 列表(即 m_ids。当用户在这个事务中要读取某个记录行的时候`InnoDB` 会将该记录行的 `DB_TRX_ID``Read View` 中的一些变量及当前事务 ID 进行比较,判断是否满足可见性条件
[具体的比较算法](https://github.com/facebook/mysql-8.0/blob/8.0/storage/innobase/include/read0types.h#L161)如下[图源](https://leviathan.vip/2019/03/20/InnoDB%E7%9A%84%E4%BA%8B%E5%8A%A1%E5%88%86%E6%9E%90-MVCC/#MVCC-1)
[具体的比较算法](https://github.com/facebook/mysql-8.0/blob/8.0/storage/innobase/include/read0types.h#L161)如下([图源](https://leviathan.vip/2019/03/20/InnoDB%E7%9A%84%E4%BA%8B%E5%8A%A1%E5%88%86%E6%9E%90-MVCC/#MVCC-1))
![](https://ddmcc-1255635056.file.myqcloud.com/8778836b-34a8-480b-b8c7-654fe207a8c2.png)
![](./images/mvvc/8778836b-34a8-480b-b8c7-654fe207a8c2.png)
1. 如果记录 DB_TRX_ID < m_up_limit_id那么表明最新修改该行的事务DB_TRX_ID在当前事务创建快照之前就提交了所以该记录行的值对当前事务是可见的
@ -138,13 +138,13 @@ private:
举个例子:
![](https://ddmcc-1255635056.file.myqcloud.com/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png)
![](./images/mvvc/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png)
### 在 RC 下 ReadView 生成情况
1. **`假设时间线来到 T4 ,那么此时数据行 id = 1 的版本链为`**
**1. 假设时间线来到 T4 ,那么此时数据行 id = 1 的版本链为:**
![](https://ddmcc-1255635056.file.myqcloud.com/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png)
![](./images/mvvc/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png)
由于 RC 级别下每次查询都会生成`Read View` ,并且事务 101、102 并未提交,此时 `103` 事务生成的 `Read View` 中活跃的事务 **`m_ids` 为:[101,102]** `m_low_limit_id`为104`m_up_limit_id`为101`m_creator_trx_id` 为103
@ -152,9 +152,9 @@ private:
- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是 101不可见
- 继续找上一条 `DB_TRX_ID`为 1满足 1 < m_up_limit_id可见所以事务 103 查询到数据为 `name = 菜花`
2. **`时间线来到 T6 ,数据的版本链为`**
**2. 时间线来到 T6 ,数据的版本链为:**
![markdown](https://ddmcc-1255635056.file.myqcloud.com/528559e9-dae8-4d14-b78d-a5b657c88391.png)
![](./images/mvvc/528559e9-dae8-4d14-b78d-a5b657c88391.png)
因为在 RC 级别下,重新生成 `Read View`,这时事务 101 已经提交102 并未提交,所以此时 `Read View` 中活跃的事务 **`m_ids`[102]** `m_low_limit_id`为104`m_up_limit_id`为102`m_creator_trx_id`为103
@ -162,9 +162,9 @@ private:
- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 为 101满足 101 < m_up_limit_id记录可见所以在 `T6` 时间点查询到数据为 `name = 李四`与时间 T4 查询到的结果不一致不可重复读
3. **`时间线来到 T9 ,数据的版本链为`**
**3. 时间线来到 T9 ,数据的版本链为:**
![markdown](https://ddmcc-1255635056.file.myqcloud.com/6f82703c-36a1-4458-90fe-d7f4edbac71a.png)
![](./images/mvvc/6f82703c-36a1-4458-90fe-d7f4edbac71a.png)
重新生成 `Read View` 这时事务 101 和 102 都已经提交,所以 **m_ids** 为空,则 m_up_limit_id = m_low_limit_id = 104最新版本事务 ID 为 102满足 102 < m_low_limit_id可见查询结果为 `name = 赵六`
@ -172,11 +172,11 @@ private:
### 在 RR 下 ReadView 生成情况
**在可重复读级别下,只会在事务开始后第一次读取数据时生成一个 Read Viewm_ids 列表)**
在可重复读级别下,只会在事务开始后第一次读取数据时生成一个 Read Viewm_ids 列表)
1. **`在 T4 情况下的版本链为`**
**1. 在 T4 情况下的版本链为:**
![markdown](https://ddmcc-1255635056.file.myqcloud.com/0e906b95-c916-4f30-beda-9cb3e49746bf.png)
![](./images/mvvc/0e906b95-c916-4f30-beda-9cb3e49746bf.png)
在当前执行 `select` 语句时生成一个 `Read View`,此时 **`m_ids`[101,102]** `m_low_limit_id`为104`m_up_limit_id`为101`m_creator_trx_id` 为103
@ -186,11 +186,11 @@ private:
- 根据 `DB_ROLL_PTR` 找到 `undo log` 中的上一版本记录,上一条记录的 `DB_TRX_ID` 还是 101不可见
- 继续找上一条 `DB_TRX_ID`为 1满足 1 < m_up_limit_id可见所以事务 103 查询到数据为 `name = 菜花`
2. **`时间点 T6 情况下`**
**2. 时间点 T6 情况下:**
![markdown](https://ddmcc-1255635056.file.myqcloud.com/79ed6142-7664-4e0b-9023-cf546586aa39.png)
![](./images/mvvc/79ed6142-7664-4e0b-9023-cf546586aa39.png)
在 RR 级别下只会生成一次`Read View`,所以此时依然沿用 **`m_ids` [101,102]** `m_low_limit_id`为104`m_up_limit_id`为101`m_creator_trx_id` 为103
在 RR 级别下只会生成一次`Read View`,所以此时依然沿用 **`m_ids` [101,102]** `m_low_limit_id`为104`m_up_limit_id`为101`m_creator_trx_id` 为103
- 最新记录的 `DB_TRX_ID` 为 102m_up_limit_id <= 102 < m_low_limit_id所以要在 `m_ids` 列表中查找发现 `DB_TRX_ID` 存在列表中那么这个记录不可见
@ -200,9 +200,9 @@ private:
- 继续找上一条 `DB_TRX_ID`为 1满足 1 < m_up_limit_id可见所以事务 103 查询到数据为 `name = 菜花`
3. **时间点 T9 情况下:**
**3. 时间点 T9 情况下:**
![markdown](https://ddmcc-1255635056.file.myqcloud.com/cbbedbc5-0e3c-4711-aafd-7f3d68a4ed4e.png)
![](./images/mvvc/cbbedbc5-0e3c-4711-aafd-7f3d68a4ed4e.png)
此时情况跟 T6 完全一样,由于已经生成了 `Read View`,此时依然沿用 **`m_ids` [101,102]** ,所以查询结果依然是 `name = 菜花`

View File

@ -11,7 +11,7 @@ tag:
**索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有: B 树, B+树和 Hash。**
索引的作用就相当于目录的作用。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。
索引的作用就相当于书的目录。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。
## 索引的优缺点
@ -179,8 +179,7 @@ SELECT id FROM table WHERE id=1;
如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称之为“覆盖索引”。我们知道在 InnoDB 存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值。最终还是要“回表”,也就是要通过主键再查找一次。这样就会比较慢覆盖索引就是把要查询出的列和索引是对应的,不做回表操作!
**覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了,
而无需回表查询。**
**覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了,而无需回表查询。**
> 如主键索引,如果一条 SQL 需要查询主键,那么正好根据主键索引就可以查到主键。
>

View File

@ -317,7 +317,7 @@ mysql> SELECT @@tx_isolation;
+-----------------+
```
关于 MySQL 事务的详细介绍,可以看看我写的这篇文章:[MySQL 事务隔离级别详解](https://javaguide.cn/database/mysql/transaction-isolation-level.html)。
关于 MySQL 事务隔离级别的详细介绍,可以看看我写的这篇文章:[MySQL 事务隔离级别详解](https://javaguide.cn/database/mysql/transaction-isolation-level.html)。
## MySQL 锁
@ -325,7 +325,7 @@ mysql> SELECT @@tx_isolation;
MyISAM 仅仅支持表级锁(table-level locking),一锁就锁整张表,这在并发写的情况下性非常差。
InnoDB 不光支持表级锁(table-level locking),还支持行级锁(row-level locking),默认为行级锁。行级锁的粒度更小,仅对相关的记录上锁即可(对一行或者多行记录加锁),所以对于并发写入操作来说 InnoDB 的性能更高。
InnoDB 不光支持表级锁(table-level locking),还支持行级锁(row-level locking),默认为行级锁。行级锁的粒度更小,仅对相关的记录上锁即可(对一行或者多行记录加锁),所以对于并发写入操作来说 InnoDB 的性能更高。
**表级锁和行级锁对比**

View File

@ -174,7 +174,7 @@ protostuff 基于 Google protobuf但是提供了更多的功能和更简易
Github 地址:[https://github.com/protostuff/protostuff](https://github.com/protostuff/protostuff)。
### hession
### hessian
hessian 是一个轻量级的,自定义描述的二进制 RPC 协议。hessian 是一个比较老的序列化实现了,并且同样也是跨语言的。