MySQL InnoDB中脏读引发的select查询原理思考

本文详细探讨了MySQL InnoDB的事务隔离级别,包括脏读、不可重复读、幻读等问题,并解释了MVCC如何解决幻读。在MVCC机制下,MySQL保证了事务的一致性和持久性。同时,文章介绍了select查询的原理,涉及查询计划缓存、语法和语义验证、权限检查以及执行计划的生成。此外,还概述了MySQL的重做日志(redo log)、回滚日志(undo log)和二进制日志(binlog)在事务操作中的作用。
摘要由CSDN通过智能技术生成

一、MySQL InnoDB事务隔离级别脏读、可重复读、幻读

MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLE READ)

·        1)未提交读(READUNCOMMITTED)。另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据(脏读)( 隔离级别最低,并发性能高 )。

·        2)提交读(READCOMMITTED)。本事务读取到的是最新的数据(其他事务提交后的)。问题是,在同一个事务里,前后两次相同的SELECT会读到不同的结果(不重复读)。会出现不可重复读、幻读问题(锁定正在读取的行)

·       3)可重复读(REPEATABLEREAD)。在同一个事务里,SELECT的结果是事务开始时时间点的状态,因此,同样的SELECT操作读到的结果会是一致的。会出幻读现象(锁定所读取的所有行)。

·        4)串行化(SERIALIZABLE)。读操作会隐式获取共享锁,可以保证不同事务间的互斥(锁表)。

 

并发操作带来的数据库不一致性可以分为四类:

         1)丢失或覆盖更新。当两个或多个事务选择同一数据,并且基于最初选定的值更新该数据时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。上面预定飞机票的例子就属于这种并发问题。事务1与事务2先后读入同一数据A=16,事务1执行A-1,并将结果A=15写回,事务2执行A-1,并将结果A=15写回。事务2提交的结果覆盖了事务1对数据库的修改,从而使事务1对数据库的修改丢失了。

·        2)脏读。另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据。

·        3)不重复读。解决了脏读后,会遇到,同一个事务执行过程中,另外一个事务提交了新数据,因此本事务先后两次读到的数据结果会不一致。

·        4)幻读。解决了不重复读,保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。但是,如果另一个事务同时提交了新数据,本事务再更新时,就会“惊奇的”发现了这些新数据,貌似之前读到的数据是“鬼影”一样的幻觉。

具体地:

    1) 脏读 

      首先区分脏页和脏数据

      脏页是内存的缓冲池中已经修改的page,未及时flush到硬盘,但已经写到redo log中。读取和修改缓冲池的page很正常,可以提高效率,flush即可同步。脏数据是指事务对缓冲池中的行记录record进行了修改,但是还没提交!!!,如果这时读取缓冲池中未提交的行数据就叫脏读,违反了事务的隔离性。脏读就是指,当事务1修改某一数据,并将其写回磁盘,事务2读取同一数据后,事务1由于某种原因被撤销,这时事务1已修改过的数据恢复原值,事务2读到的数据就与数据库中的数据不一致,是不正确的数据,称为脏读。例如,事务1将C值修改为200,事务2读到C为200,而事务1由于某种原因撤销,其修改作废,C恢复原值100,这时事务2读到的就是不正确的“脏“数据 

    2). 不可重复读 

     是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据,由于第二个事务的修改,并且第二个事务提交。那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。即事务1读取某一数据后,事务2对其做了修改,当事务1再次读数据时,得到的与第一次不同的值。 例如,事务1读取B=100进行运算,事务2读取同一数据B,对其进行修改后将B=200写回数据库。事务1为了对读取值校对重读B,B已为200,与第一次读取值不一致。

    3). 幻读 :

     当某个事务读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录.当之前的事务再次读取该范围时,会产生幻行.(与不可重复读的区别是,是由于新事务插入数据,导致的旧事务两次查询不一致,那为什么要将不可重复读和幻读区分呢?这因为两种并发问题所产生的原理不一样,具体可以查看另一篇博文 Innodb中的事务隔离级别实现原理。例如,事务1按一定条件从数据库中读取某些数据记录后未提交查询结果,事务2删除了其中部分记录,事务1再次按相同条件读取数据时,发现某些记录神秘地消失了;或者事务1按一定条件从数据库中读取某些数据记录后未提交查询结果,事务2插入了一些记录,当事务1再次按相同条件读取数据时,发现多了一些记录。

MVCC是如何解决幻读的:

      MySQL的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑&#

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值