Skip to content

Commit

Permalink
feat: update articles
Browse files Browse the repository at this point in the history
  • Loading branch information
wx-chevalier committed Jun 2, 2019
1 parent ae51332 commit 408839e
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 55 deletions.
7 changes: 3 additions & 4 deletions 数据库/MySQL/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# MySQL

针对不同的业务场景选择合适的 SQL/NoSQL/NewSQL 数据库,微服务,云原生的场景下,
针对不同的业务场景选择合适的 SQL/NoSQL/NewSQL 数据库,微服务,云原生的场景下,合理的数据建模,选择合理的字段,索引,外键等,这也是本章讨论的重点。

合理的数据建模,选择合理的字段,索引,外键等,这也是本章讨论的重点

对微服务化之后的应用进行读写分离,垂直/水平的分库分表,选择合适的数据库中间件,搭建分布式集群,参阅本篇的相关章节。
在本系列文章中我们使用官方的 [test_db](https://github.com/datacharmer/test_db) 以及标准的电商库 [mysql-mall-matrix https://url.wx-coder.cn/Lmzp3](https://url.wx-coder.cn/Lmzp3)
作为我们的测试数据库。

# 链接

Expand Down
12 changes: 6 additions & 6 deletions 数据库/MySQL/事务管理/锁.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,18 @@ mysql>insert into emp(empid,...) values(102,...);

InnoDB 的加锁过程比较复杂,将所有扫描到的记录都加锁,范围查询会加间隙锁,然后加锁过程按照两阶段锁 2PL 来实现,也就是先加锁,然后所有的锁在事物提交的时候释放。加锁的策略会和数据库的隔离级别有关,在默认的可重复读的隔离级别的情况下,加锁的流程还会和查询条件中是否包含索引,是主键索引还是普通索引,是否是唯一索引等有关。

譬如对于 `select * from trade_order where order_no = '201912102322' for update;` 这条 SQL 语句,在不同的索引情况下其加锁策略也不一致:
譬如对于 `select * from o_order where order_sn = '201912102322' for update;` 这条 SQL 语句,在不同的索引情况下其加锁策略也不一致:

![](https://i.postimg.cc/HW8Ys7Jm/image.png)

- order_no 是主键索引,这种情况将在主键索引上的 order_no = '201912102322' 这条记录上加排他锁。
- order_sn 是主键索引,这种情况将在主键索引上的 `order_sn = 201912102322` 这条记录上加排他锁。

- order_no 是普通索引,并且是唯一索引,将会对普通索引上对应的一条记录加排他锁,对主键索引上对应的记录加排他锁。
- order_sn 是普通索引,并且是唯一索引,将会对普通索引上对应的一条记录加排他锁,对主键索引上对应的记录加排他锁。

- order_no 是普通索引,并且不是唯一索引,将会对普通索引上 order_no = 201912102322 一条或者多条记录加锁,并且对这些记录对应的主键索引上的记录加锁。这里除了加上行锁外,还会加上间隙锁,防止其他事务插入 order_no = 201912102322 的记录,然而如果是唯一索引就不需要间隙锁,行锁就可以。
- order_sn 是普通索引,并且不是唯一索引,将会对普通索引上 `order_sn = 201912102322` 一条或者多条记录加锁,并且对这些记录对应的主键索引上的记录加锁。这里除了加上行锁外,还会加上间隙锁,防止其他事务插入 `order_sn = 201912102322` 的记录,然而如果是唯一索引就不需要间隙锁,行锁就可以。

- order_no 上没有索引,innoDB 将会在主键索引上全表扫描,这里并没有加表锁,而是将所有的记录都会加上行级排他锁,而实际上 innoDB 内部做了优化,当扫描到一行记录后发现不匹配就会把锁给释放,当然这个违背了 2PL 原则在事务提交的时候释放。这里除了对记录进行加锁,还会对每两个记录之间的间隙加锁,所以最终将会保存所有的间隙锁和 order_no = 201912102322 的行锁。
- order_sn 上没有索引,innoDB 将会在主键索引上全表扫描,这里并没有加表锁,而是将所有的记录都会加上行级排他锁,而实际上 innoDB 内部做了优化,当扫描到一行记录后发现不匹配就会把锁给释放,当然这个违背了 2PL 原则在事务提交的时候释放。这里除了对记录进行加锁,还会对每两个记录之间的间隙加锁,所以最终将会保存所有的间隙锁和 `order_sn = 201912102322` 的行锁。

- order_no = 201912102322 这条记录不存在的情况下,如果 order_no 是主键索引,则会加一个间隙锁,而这个间隙是主键索引中 order_no 小于 201912102322 的第一条记录到大于 201912102322 的第一条记录。试想一下如果不加间隙锁,如果其他事物插入了一条 order_no = 201912102322 的记录,由于 select for update 是当前读,即使上面那个事物没有提交,如果在该事物中重新查询一次就会发生幻读。
- `order_sn = 201912102322` 这条记录不存在的情况下,如果 order_sn 是主键索引,则会加一个间隙锁,而这个间隙是主键索引中 order_sn 小于 201912102322 的第一条记录到大于 201912102322 的第一条记录。试想一下如果不加间隙锁,如果其他事物插入了一条 `order_sn = 201912102322` 的记录,由于 select for update 是当前读,即使上面那个事物没有提交,如果在该事物中重新查询一次就会发生幻读。

- 如果没有索引,则对扫描到的所有记录和间隙都加锁,如果不匹配行锁将会释放只剩下间隙锁。回忆一下上面讲的数据页的结果中又一个最大记录和最小记录,Infimum 和 Supremum Record,这两个记录在加间隙锁的时候就会用到。
2 changes: 1 addition & 1 deletion 数据库/MySQL/存储管理/存储结构.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ system ls -lh /usr/local/var/mysql/test/t1.ibd

#

同大多数数据库一样,InnoDB 有页(page)的概念(也可以称为块),页是 InnoDB 磁盘管理的最小单位。与 Oracle 类似的是,Microsoft SQL Server 数据库默认每页大小为 8KB,不同于 InnoDB 页的大小(16KB),且不可以更改(也许通过更改源码可以)。常见的页类型有:数据页(B-tree Node),Undo 页(Undo Log Page),系统页(System Page),事务数据页(Transaction system Page),插入缓冲位图页(Insert Buffer Bitmap),插入缓冲空闲列表页(Insert Buffer Free List),未压缩的二进制大对象页(Uncompressed BLOB Page),压缩的二进制大对象页(Compressed BLOB Page)。
同大多数数据库一样,InnoDB 有页(Page)的概念(也可以称为块),页是 InnoDB 磁盘管理的最小单位。与 Oracle 类似的是,Microsoft SQL Server 数据库默认每页大小为 8KB,不同于 InnoDB 页的大小(16KB),且不可以更改(也许通过更改源码可以)。常见的页类型有:数据页(B-tree Node),Undo 页(Undo Log Page),系统页(System Page),事务数据页(Transaction system Page),插入缓冲位图页(Insert Buffer Bitmap),插入缓冲空闲列表页(Insert Buffer Free List),未压缩的二进制大对象页(Uncompressed BLOB Page),压缩的二进制大对象页(Compressed BLOB Page)。

InnoDB 的数据页由以下 7 个部分组成:

Expand Down
6 changes: 5 additions & 1 deletion 数据库/MySQL/性能优化/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# MySQL 性能优化

MySQL 的优化主要分为结构优化(Scheme optimization)和查询优化(Query optimization)。

# 链接

- https://www.itcodemonkey.com/article/14204.html
Expand All @@ -10,4 +12,6 @@

- https://www.imooc.com/learn/194

- https://www.itcodemonkey.com/article/13851.html
- https://www.itcodemonkey.com/article/13851.html

- http://blog.codinglabs.org/articles/theory-of-mysql-index.html 利用 test_db 分析索引的使用情况系列
Loading

0 comments on commit 408839e

Please sign in to comment.