mysql————Innodb的可重复读的情况下如何避免幻读?

1.1 实现InnoDB下的快照读
然后,接下来说说,在READ-COMMITTED和REPEATABLE-READ级别下的InnoDB的非阻塞读是如何实现的。

实际上,在InnoDB存储数据的时候,还会额外存储三个不显示出来的字段:DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID,下面来简单介绍一下字段的含义。

DB_TRX_ID:最后一次修改本行记录的事务ID。
DB_ROLL_PTR:滚指针,指向这条记录的上一个版本(存储于rollback segment里)。
DB_ROW_ID:隐含的自增ID,如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引。
然后再额外解释一下什么是undo日志:

undo日志:逻辑日志,其记录时间点为修改缓冲中页面之前

2. 内在:next-key锁(行锁+gap锁)
行锁
所谓行锁,就是对行上锁

Gap锁
Gap:索引树中,插入新纪录的空隙
Gap锁:指一段距离,将插入的索引占用的空隙用锁包住。Gap锁的目的是,防止事务因为两次当前读出现幻读的情况。但是READ-COMMITTED及以下的级别都没有Gap锁,所以无法避免幻读。

而在REPEATABLE-READ级别下,无论是删改查,如果我们要使用到主键索引或者唯一索引,会需要到gap锁吗?

其实是视情况而定的,如果where条件全部命中,就可以不用gap锁,否则,就得用gap锁。(命中:比如我们where id in (1,3,5),id是主键,1 3 5在table中都能查到东西,就是全部命中,只查到一部分,就是部分命中)

原文地址:https://www.cnblogs.com/ffdsj/p/12386382.html

时间: 2024-08-06 15:49:29

mysql————Innodb的可重复读的情况下如何避免幻读?的相关文章

mysql行锁+可重复读+读提交

行锁 innodb支持行锁,myisam只支持表锁,同一时刻每张表只能有一条数据被更新 在InnoDB事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放, 而是要等到事务结束时才释放.这个就是两阶段锁协议. 如果你的事务中需要锁多个行,要把最可能造成锁冲突.最可能影响并 发度的锁的申请时机尽量往后放. 例子:假设你负责实现一个电影票在线交易业务,顾客A要在影院B购买电影票.我们简化一点,这个业务需要涉及到以下操作: 从顾客A账户余额中扣除电影票价: 给影院B的账户余额增加这张电影票价

Openwrt上mysql innodb的使用及相关异常情况

首先在menuconfig中配置mysql,具体是在Utilities->database->mysql-server.这样直接编译就可以了,不过这样默认是不支持innodb存储引擎的,估计是考虑openwrt一般是运行的硬件有关,不需要这么复杂的存储引擎(占用空间也比MyISAM存储引擎大).但是,如果需要支持innodb存储引擎该怎么办?这类型的网上帖子不多,我是之前参照国外的论坛加自己测试得出的. Openwrt支持innodb存储引擎 修改feeds/oldpackages/libs/

PHP、MySQL、浏览器编码不统一的情况下如何保证正常解析?

最理想的情况是,把三者编码都统一成gbk或者utf-8,这样解析就一切正常.但如何不统一呢? 比如: --PHP的编码是utf-8 --MySQL的编码是utf-8 --浏览器的编码是gbk 这时,只要考虑PHP和浏览器之间即可,因为PHP和MySQL的编码是一致的,可以不考虑.而如何告诉浏览器,PHP返回给浏览器的东西是用utf-8,请用utf-8解析? 答案: (1)方法之一就是我们在PHP中用的那个header函数.header("Content-type:text/html;charse

mysql大量锁表,不重启的情况下处理办法

mysql -u root -e "show processlist"|grep -i "Locked" >> locklist.txt; for line in awk '{print $1}' locklist.txt do    echo "kill $line;">>lock_kill.sql done 查看mysql数据库表大小 #!/bin/bash database=cms user=root passwor

mysql事务隔离级别/脏读/不可重复读/幻读详解

一.四种事务隔离级别 1.1 read uncommitted 读未提交 即:事务A可以读取到事务B已修改但未提交的数据. 除非是文章阅读量,每次+1这种无关痛痒的场景,一般业务系统没有人会使用该事务隔离级别,标准实在太宽松了. 1.2 read committed 读已提交(简称RC) 即:事务A只能读取到事务B修改并已提交的数据. 这个级别相对要严格一些,至少是要等其它事务把变更提交到db,才能读取到,听上去蛮靠谱的.但是有些业务场景,比如会员系统中,如果要在一个事务中,多次读取用户身份,判

MySQL InnoDB中的事务隔离级别和锁的关系

前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过分析MySQL中InnoDB引擎的加锁机制,来抛砖引玉,让读者更好的理解,在事务处理中数据库到底做了什么. 一.一次封锁or两段锁因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会

MySQL innodb中各种SQL语句加锁分析

概要 Locking read( SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),UPDATE以及DELETE语句通常会在他扫描的索引所有范围上加锁,忽略没有用到索引的那部分where语句.举个例子: CREATE TABLE `test` ( `id` int(11) NOT NULL DEFAULT '0', `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE

事务隔离级别中可重复读与幻读

前言 中秋刚过,大家是不是还没充中秋的假日里缓过来?三天假期里,我深入窥探了Innodb中可重复读与幻读,非常有意思,分享给大家,作为大家工作前的开胃小菜,希望有所帮助. 每次谈到数据库的事务隔离级别,大家一定会看到这张表. 其中,可重复读这个隔离级别,有效地防止了脏读和不可重复读,但仍然可能发生幻读,可能发生幻读就表示可重复读这个隔离级别防不住幻读吗? 我不管从数据库方面的教科书还是一些网络教程上,经常看到RR级别是可以重复读的,但是无法解决幻读,只有可串行化(Serializable)才能解

事务隔离级别中可重复读与幻读的恩恩怨怨

前言 中秋刚过,大家是不是还没充中秋的假日里缓过来?三天假期里,我深入窥探了Innodb中可重复读与幻读,非常有意思,分享给大家,作为大家工作前的开胃小菜,希望有所帮助. 每次谈到数据库的事务隔离级别,大家一定会看到这张表. 其中,可重复读这个隔离级别,有效地防止了脏读和不可重复读,但仍然可能发生幻读,可能发生幻读就表示可重复读这个隔离级别防不住幻读吗? 我不管从数据库方面的教科书还是一些网络教程上,经常看到RR级别是可以重复读的,但是无法解决幻读,只有可串行化(Serializable)才能解