

MySQL之事务隔离级别和MVCC - 大队长11
source link: https://www.cnblogs.com/duizhangz/p/16333589.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

事务隔离级别
事务并发可能出现的问题
- 脏写 事务之间对增删改互相影响
- 脏读 事务之间读取其他未提交事务的数据
- 不可重复读 一个事务在多次执行一个select读到的数据前后不相同。因为被别的未提交事务修改,删除数据或数据被更新被当前事务读取到了。
- 幻读 一个事务在第一次读取正常数据,第二次读取到其他未提交事务的insert记录,导致读取一个不存在的记录。指一次读取读取到了之前未读取到的数据。
事务的4个隔离级别,以及解决的问题
- READ UNCOMMITTED 未提交读 解决脏写
- READ COMMITTED提交读 解决脏写、脏读
- REPEATABLE READ可重复读 解决脏写、脏读、不可重复读
- SERIALIAZBLE可串行化 解决脏写、脏读、不可重复读、幻读
四个隔离级别和可以解决的问题是SQL专门规定的,但是在Innodb引擎下,在可重复读的隔离级别的下就可以直接解决幻读的问题。
我们可以在启动时指定系统参数修改系统默认的隔离级别,默认为可重复读。
mysql> show variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name | Value |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set, 1 warning (0.00 sec)
我们在前面就讲过了undo日志,对于每次进行增删改就会产生undo日志,这时每个数据行的roll_pointer就会指向一个undo链表,我们就称其为版本链。我们在提一嘴,因为insert的undo日志在提交后是没有用的,所以在事务提交后insert的undo就会被释放。
可以到前面的文章了解一下undo日志。大概知道undo日志的类型和产生的过程就OK了感觉怎么存储undo日志的那一部分讲得云里雾里https://www.cnblogs.com/duizhangz/p/16333565.html
为什么没用?因为插入并不维护旧值,只是表明一个插入,并不需要存储什么信息。所以在事务提交时直接释放掉。因为事务在回滚时需要由一条insert语句类型的undo进行回滚。
这就是上面俩事务生成的版本链。
undo链表头存储的就是最新事务更新的记录信息。
ReadView
对于不同的事务隔离级别,我们可以读取的记录数据是不一样的。
-
对于未提交读的隔离级别来说,我们可以直接读到数据的最新版本。
-
对于提交读的隔离级别来说,我们需要可以读到的就是已经提交的事务的修改数据。
-
对于可重复读的隔离级别来说,我们需要可以读到在事务开启前已经提交的事务的数据。
-
对于串行读的隔离节别来说,Innodb采用加锁的方式来保证串行读。
对于中间两个隔离级别,就需要ReadView这个结构来实现MVCC。以下是ReadView的结构
- m_ids : 表示在生成ReadView时当前系统中活跃的读写事务ID的列表
- min_trx_id : 表示在生成ReadView时当前系统中活跃的读写事务ID的最小值即在m_ids中最小的事务ID。
- max_trx_id : 表示生成ReadView时系统中应该分配给下一个事务的ID。
- creator_trx_id : 表示生成该ReadView的事务ID。
有了ReadView这个结构,我们在就可以对事务进行控制。
- 当被访问的记录行的事务ID大于等于max_trx_id,说明当前数据行不可见。
- 当被访问的记录行的事务ID小于min_trx_id,可以直接获得数据。
- 当被访问的记录行的事务ID等于creator_trx_id,说明是当前事务修改的记录,可以直接访问。
- 当被访问的记录行的事务ID大于min_trx_id且小于max_trx_id,我们需要判断一下这个事务ID是不是在m_ids列表中,因为由可能是一个很早的事务很久还执行不介绍,导致中间的事务都结束了,如果在m_ids列表中,说明是活跃的,当前记录行不能访问,否则可以访问数据行。
当前情况在版本链中从头到尾遍历,直到获得到数据。
上面提到的提交读和可重复读,因为是两个隔离级别有区别的,两个隔离级别的实现只要在ReadView的时机上进行把控,就可以实现。
- 提交读,我们只要保证当前事务的每个语句能读到已经提交的事务的数据。就可以在每个查询数据进行前,事务就会创建一个ReadView。
- 可重复读,我们只要保证当前事务每个语句能读到事务开启前的数据,就可以在事务第一次读取数据时会创建ReadView,然后整个事务只会使用这个ReadView去判断能读取的数据行。
仔细品一品,一下就可以恍然大悟。
这个MVCC只会在我们使用普通select查询才会生效。
__EOF__
Recommend
-
74
事务及其特性 IBM Compose for MySQL IBM Cloud 上提供的 Compose for M...
-
34
mysql事务原理及MVCC 事务是数据库最为重要的机制之一,凡是使用过数据库的人,都了解数据库的事务机制,也对ACID四个 基本特性如数家珍。但是聊起事务或者ACID的底层实现原理,往往言之不详,不明所以。在MySQL中
-
12
SQL 事务隔离级别说明 SQL 标准定义了 4 类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。 Read Uncom...
-
9
一、前提 时过一年重新拾起博文记录,希望后面都能坚持下来。 接着之前MySql的学习,先记录下这篇。 以下都是基于mysql8 innodb存储引擎进行分析的。 二、事务的ACID特性 A(Atomicity) 原子性...
-
6
MySQL版本:8.0.27一、事务并发执行面临的问题1. 脏读(Dirty Read)如果事务A读到了未提交的事务B修改过的数据,就意味着发生了脏读现象。2. 不可重复读(Non-Repeatable Read)如果事务B...
-
12
理解mysql的事务隔离级别发布于 今天 10:49 考研分数落定,今年无缘,着手准备春招。说到今年考研,分数可谓水涨船高,去年本校专硕270就能进,今年一舍友考了270,...
-
4
提到数据库,你多半会联想到事务,进而还可能想起曾经背得滚瓜乱熟的ACID,不知道你有没有想过这个问题,事务有原子性、隔离性、一致性和持久性四大特性,为什么偏偏给隔离性设置了级别?
-
10
MySQL M...
-
7
MySQL之事务和redo日志 - 大队长11 - 博客园 事务的四个ACID特性。 Atomicity 原子性 Consistency 一致性 Isola...
-
10
大家好,我是melo,一名大三后台练习生,死去的MVCC突然开始拷打我🤣🤣🤣! MVCC,非常顺口的一个词,翻译起来却不是特别顺口:多版本并发控制。 其中多版本是指什么呢?一条记录的多个版本。 并发控制?如何...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK