mysql之事务隔离级别以及MVCC
1.事务特性:ACID
原子性:undolog--要么全部成功,要么全部失败
一致性:最核心和最本质的要求
隔离性:MVCC(多版本并发控制)
持久性:redo log
2.事务的隔离级别
事务的隔离级别有四种:读未提交、读已提交、可重复读、序列化
脏读:事务B读取到了事务A已修改但尚未提交的数据,还在这个数据基础上做了操作,此时,如果A事务回滚,B读取的数据无效,不符合一致性要求。
不可重复读:一个事务范围内两个相同的查询却返回了不同的数据 -----针对修改
幻读:事务A读取到了事务B的新增数据,不符合隔离性-------针对新增和删除
3.隔离性引出MVCC
MVCC:多版本并发控制、是为了在读取数据时不加锁来提高读取效率和并发性的一种手段。
数据库并发场景:
1.读读:不存在任何问题
2.读写:有线程安全问题、可能出现脏读、幻读、不可重复读
3.写写:有线程安全问题,可能存在更新丢失等。
MVCC解决的就是读写时的线程安全问题,线程不用去争抢读写锁。 Mysql两种读方式:
当前读:读取的是数据的最新版本,而且要保证其他并发事务不能修改当前记录,场景:lock in share mode,for update,updatedelete,insert
快照都:不加锁的非阻塞读,读取的是历史版本的数据,不是最新的记录,场景:不加锁的select
MVCC:multi-Version concurrency control:多版本并发控制,用来解决并发读写的问题,不需要通过加锁来解决 。
MVCC不同事务隔离级别的不同表现:
RC隔离级别下:当其他事务修改数据之后,可以看到修改之后的值
RR隔离级别下:当其他事务修改数据之后,看不到修改之后的值
MVCC实现原理:
MVCC模块在Mysql中的具体实现是由三个隐式字段、undo日志、read view三个组件来完成
三个隐藏字段:
DB_TRX_ID:6字节,最近修改事务id,记录创建这条记录或者最后一次修改该记录的事务id
DB_TOLL_PTR:7字节,回滚指针,指向这条记录的上一个版本,用于配合undolog,指向上一个旧版本
DB_ROW_ID:6字节,隐藏的主键,如果数据表没有主键,那么innodb会自动创建一个row_Id undo log:
undolog被称之为回滚日志,表示在进行insert,delete,update操作的时候产生的方便回滚的日志。
当进行insert操作的时候,产生的undolog只在事务回滚的时候需要,并且在事务提交之后可以被立刻丢弃。
当进行update和delete操作的时候,产生的undolog不仅仅在事务回滚的时候需要,在快照读的时候也需要,所以不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除(当数据发生更新和删除操作的时候都只是设置一下老记录的deleted_bit,并不是真正的将过时的记录删除,因为为了节省磁盘空间,innodb有专门的purge线程来清除deleted_bit为true的记录,如果某个记录的deleted_id为true,并且DB_TRX_ID相对于purge线程的read view可见,那么这条记录一定时可以被清除的)。
readview:最大作用用来做可见性判断
案例展示1:
案例展示2:
说明第二次select并没有生成新的readview,而是沿用了第一次快照时刻的readview。
RR隔离级别能否解决幻读问题?
不能,产生幻读的本质原因
如果事务中都是用快照读,那么是不会产生幻读问题的,但是当快照读和当前读一起使用的时候就产生了幻读问题
相关系列文章:
0.Mysql之如何插入数据剖析mysql各个技术点 :通过插入一条数据的过程引出mysql知识点:
1.mysql之事务隔离级别以及MVCC:ACID、事务级别以及产生问题、MVCC(三个隐藏字段、undolog、read_view详解)
2.Mysql之Innodb锁场景:锁分类、RC下各种加锁情况、RR下各种加锁情况
3.Mysql之主从复制原理:主从复制原理、二次提交、MTS、组提交、GTID
4.Mysql之数据结构 :hash、二叉树、AVL、平衡二叉树(红黑树)、B-Tree、B+Tree
5.Mysql之索引 :回表、索引覆盖、索引下推、MRR、FIC、索引方式、哈希索引
6.Mysql之其他知识 :日志、MyiSAM和InnoDB比较,基础知识体系