diff --git a/docs/database/mysql/images/mvvc/0e906b95-c916-4f30-beda-9cb3e49746bf.png b/docs/database/mysql/images/mvvc/0e906b95-c916-4f30-beda-9cb3e49746bf.png new file mode 100644 index 00000000..8f57daf4 Binary files /dev/null and b/docs/database/mysql/images/mvvc/0e906b95-c916-4f30-beda-9cb3e49746bf.png differ diff --git a/docs/database/mysql/images/mvvc/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png b/docs/database/mysql/images/mvvc/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png new file mode 100644 index 00000000..e483cd54 Binary files /dev/null and b/docs/database/mysql/images/mvvc/317e91e1-1ee1-42ad-9412-9098d5c6a9ad.png differ diff --git a/docs/database/mysql/images/mvvc/528559e9-dae8-4d14-b78d-a5b657c88391.png b/docs/database/mysql/images/mvvc/528559e9-dae8-4d14-b78d-a5b657c88391.png new file mode 100644 index 00000000..7bdfdd94 Binary files /dev/null and b/docs/database/mysql/images/mvvc/528559e9-dae8-4d14-b78d-a5b657c88391.png differ diff --git a/docs/database/mysql/images/mvvc/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png b/docs/database/mysql/images/mvvc/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png new file mode 100644 index 00000000..80db7703 Binary files /dev/null and b/docs/database/mysql/images/mvvc/6a276e7a-b0da-4c7b-bdf7-c0c7b7b3b31c.png differ diff --git a/docs/database/mysql/images/mvvc/6f82703c-36a1-4458-90fe-d7f4edbac71a.png b/docs/database/mysql/images/mvvc/6f82703c-36a1-4458-90fe-d7f4edbac71a.png new file mode 100644 index 00000000..d1806960 Binary files /dev/null and b/docs/database/mysql/images/mvvc/6f82703c-36a1-4458-90fe-d7f4edbac71a.png differ diff --git a/docs/database/mysql/images/mvvc/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png b/docs/database/mysql/images/mvvc/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png new file mode 100644 index 00000000..e6dc897c Binary files /dev/null and b/docs/database/mysql/images/mvvc/6fb2b9a1-5f14-4dec-a797-e4cf388ed413.png differ diff --git a/docs/database/mysql/images/mvvc/79ed6142-7664-4e0b-9023-cf546586aa39.png b/docs/database/mysql/images/mvvc/79ed6142-7664-4e0b-9023-cf546586aa39.png new file mode 100644 index 00000000..078ca7f6 Binary files /dev/null and b/docs/database/mysql/images/mvvc/79ed6142-7664-4e0b-9023-cf546586aa39.png differ diff --git a/docs/database/mysql/images/mvvc/8778836b-34a8-480b-b8c7-654fe207a8c2.png b/docs/database/mysql/images/mvvc/8778836b-34a8-480b-b8c7-654fe207a8c2.png new file mode 100644 index 00000000..cc95b4ae Binary files /dev/null and b/docs/database/mysql/images/mvvc/8778836b-34a8-480b-b8c7-654fe207a8c2.png differ diff --git a/docs/database/mysql/images/mvvc/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png b/docs/database/mysql/images/mvvc/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png new file mode 100644 index 00000000..240a64ad Binary files /dev/null and b/docs/database/mysql/images/mvvc/a3fd1ec6-8f37-42fa-b090-7446d488fd04.png differ diff --git a/docs/database/mysql/images/mvvc/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png b/docs/database/mysql/images/mvvc/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png new file mode 100644 index 00000000..7529d9ce Binary files /dev/null and b/docs/database/mysql/images/mvvc/c52ff79f-10e6-46cb-b5d4-3c9cbcc1934a.png differ diff --git a/docs/database/mysql/images/mvvc/cbbedbc5-0e3c-4711-aafd-7f3d68a4ed4e.png b/docs/database/mysql/images/mvvc/cbbedbc5-0e3c-4711-aafd-7f3d68a4ed4e.png new file mode 100644 index 00000000..f3608c42 Binary files /dev/null and b/docs/database/mysql/images/mvvc/cbbedbc5-0e3c-4711-aafd-7f3d68a4ed4e.png differ diff --git a/docs/database/mysql/images/mvvc/trans_visible.png b/docs/database/mysql/images/mvvc/trans_visible.png new file mode 100644 index 00000000..f0df5216 Binary files /dev/null and b/docs/database/mysql/images/mvvc/trans_visible.png differ diff --git a/docs/database/mysql/innodb-implementation-of-mvcc.md b/docs/database/mysql/innodb-implementation-of-mvcc.md index 96fa1f79..0f4877f9 100644 --- a/docs/database/mysql/innodb-implementation-of-mvcc.md +++ b/docs/database/mysql/innodb-implementation-of-mvcc.md @@ -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 View(m_ids 列表)** +在可重复读级别下,只会在事务开始后第一次读取数据时生成一个 Read View(m_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` 为 102,m_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 = 菜花` diff --git a/docs/database/mysql/mysql-index.md b/docs/database/mysql/mysql-index.md index 19911483..1c4b2ad2 100644 --- a/docs/database/mysql/mysql-index.md +++ b/docs/database/mysql/mysql-index.md @@ -11,7 +11,7 @@ tag: **索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有: B 树, B+树和 Hash。** -索引的作用就相当于目录的作用。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。 +索引的作用就相当于书的目录。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。 ## 索引的优缺点 @@ -179,8 +179,7 @@ SELECT id FROM table WHERE id=1; 如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称之为“覆盖索引”。我们知道在 InnoDB 存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值。最终还是要“回表”,也就是要通过主键再查找一次。这样就会比较慢覆盖索引就是把要查询出的列和索引是对应的,不做回表操作! -**覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了, -而无需回表查询。** +**覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了,而无需回表查询。** > 如主键索引,如果一条 SQL 需要查询主键,那么正好根据主键索引就可以查到主键。 > diff --git a/docs/database/mysql/mysql-questions-01.md b/docs/database/mysql/mysql-questions-01.md index 46a60f71..817e229c 100644 --- a/docs/database/mysql/mysql-questions-01.md +++ b/docs/database/mysql/mysql-questions-01.md @@ -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 的性能更高。 **表级锁和行级锁对比** : diff --git a/docs/java/basis/serialization.md b/docs/java/basis/serialization.md index de036ad1..bd7bc00a 100644 --- a/docs/java/basis/serialization.md +++ b/docs/java/basis/serialization.md @@ -174,7 +174,7 @@ protostuff 基于 Google protobuf,但是提供了更多的功能和更简易 Github 地址:[https://github.com/protostuff/protostuff](https://github.com/protostuff/protostuff)。 -### hession +### hessian hessian 是一个轻量级的,自定义描述的二进制 RPC 协议。hessian 是一个比较老的序列化实现了,并且同样也是跨语言的。