一、事物的特性

原子性:通过undolog实现。

持久性:通过redolog实现。

隔离性:通过加锁(当前读)&MVCC(快照读)实现。

一致性:通过undolog、redolog、隔离性共同实现。

二、快照读和当前读

快照读: 读取的是记录数据的可见版本(有旧的版本)。不加锁,普通的select语句都是快照读,如:

select * from core_user where id > 2;当前读:读取的是记录数据的最新版本,显式加锁的都是当前读

select * from core_user where id > 2 for update; select * from account where id>2 lock in share mode;

三、Read View

Read View是什么呢? 它就是事务执行SQL语句时,产生的读视图。实际上在innodb中,每个SQL语句执行前都会得到一个Read View。

Read View有什么用呢? 它主要是用来做可见性判断的,即判断当前事务可见哪个版本的数据~

Read View是如何保证可见性判断的呢?我们先看看Read view 的几个重要属性

m_ids:当前系统中那些活跃(未提交)的读写事务ID, 它数据结构为一个List。

min_limit_id:表示在生成Read View时,当前系统中活跃的读写事务中最小的事务id,即m_ids中的最小值。

max_limit_id:表示生成Read View时,系统中应该分配给下一个事务的id值。

creator_trx_id: 创建当前Read View的事务ID

Read view 匹配条件规则如下:

1.      如果数据事务ID trx_id < min_limit_id,表明生成该版本的事务在生成Read View前,已经提交(因为事务ID是递增的),所以该版本可以被当前事务访问。

2.      如果trx_id>= max_limit_id,表明生成该版本的事务在生成ReadView后才生成,所以该版本不可以被当前事务访问。

3.      如果 min_limit_id =<trx_id< max_limit_id,需要分3种情况讨论

(1).如果m_ids包含trx_id,则代表Read View生成时刻,这个事务还未提交,但是如果数据的trx_id等于creator_trx_id的话,表明数据是自己生成的,因此是可见的。

(2)如果m_ids包含trx_id,并且trx_id不等于creator_trx_id,则Read View生成时,事务未提交,并且不是自己生产的,所以当前事务也是看不见的;

(3).如果m_ids不包含trx_id,则说明你这个事务在Read View生成之前就已经提交了,修改的结果,当前事务是能看见的。

四、什么是MVCC ? 

mvcc,也就是多版本并发控制,是为了在读取数据时不加锁来提高读取效率和并发性的一种手段。

数据库并发有以下几种场景:

读-读:不存在任何问题。

读-写:有线程安全问题,可能出现脏读、幻读、不可重复读。

写-写:有线程安全问题,可能存在更新丢失等。

mvcc解决的就是读写时的线程安全问题,线程不用去争抢读写锁。 

mvcc所提到的读是快照读,也就是普通的select语句。快照读在读写时不用加锁,不过可能会读到历史数据。

还有一种读取数据的方式是当前读,是一种悲观锁的操作。它会对当前读取的数据进行加锁,所以读到的数据都是最新的。主要包括以下几种操作:

select lock in share mode(共享锁)

select for update(排他锁)

update(排他锁)

insert(排他锁)

delete(排他锁)

五、mvcc如何实现RC和RR的隔离级别

(1)RC的隔离级别下,每个快照读都会生成并获取最新的readview。

(2)RR的隔离级别下,只有在同一个事务的第一个快照读才会创建readview,之后的每次快照读都使用的同一个readview,所以每次的查询结果都是一样的。

开始事物时创建readview, readview维护当前活动的事物id, 即未提交的事物id, 排序生成一个数组, 访问数据, 获得数据中的事物ID(获取的是事物id最大的记录), 对比readview

如果在readview的左边(比readview 小), 可以访问(在左边意味着事物已经提交)

如果在readview的右边(比readview大), 或者在readview 中, 不可以访问, 获取roll_pointer, 取上一版本重新对比(在右边意味着, 该事物在readview生成之后出现, 在readview中意味着该事物还未提交)

mysql 的MVCC(多版本并发控制)_加锁

mysql 的MVCC(多版本并发控制)_加锁_02

mysql 的MVCC(多版本并发控制)_数据_03