首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MySQL 加锁死锁解析

产生死锁的必要条件 多个并发事务(2个或者以上) 每个事物都持有了锁(或者是已经在等待锁) 每个事务都需要再继续持有锁(为了完成事务逻辑,还必须更新更多的行) 事物之间产生加锁的循环等待,形成死锁...trx id 1101588 lock_mode X locks rec but not gap 根据普通索引查找-锁加在普通索引主键上 如 begin;select * from tt_copy...Read Committed (RC) ) :Unique Key 唯一约束检查;Purge操作; Repeatable Read (RC ):RC的基础上,所有需要加锁索引范围扫描索引查找(Update...,能够减少GAP锁导致的死锁(根据业务情况而定) • 原则之三 在MySQL 中,以不同索引的过滤条件, 来操作相同的记录(Update/Delete ),很容易产生死 锁。...-何登成 - 管中窥豹——MySQL(InnoDB)死锁分析之道》

99320
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    MySQL 主键索引在 RR RC 隔离级别下的加锁情况总结

    我今天抽时间给大家总结一个 MySQL InnoDB 存储引擎各种不同 SQL 情况下,加行锁、间隙锁、next-key lock 做一个总结。如果有错误的地方,请大家指正! ?...为了讲清楚相关加锁的情况,我们先来创建一个测试验证用的表。结构如下所示: ? 然后插入几条测试数据。注意,我是在 MySQL 5.7 版本上测试的 ? 在开始之前,我先来解释一下,RR RC。...搞明白 RR RC 后,我们先来看第一种情况。查询条件是聚簇索引,也就是主键索引的精确匹配情况。 ?...注意,行锁不是加在记录上的,而是加在索引上的! 第二种情况,如果是范围查询,那么在在 RC 隔离级别下,会在所有命中的行的聚簇索引上加 record locks(锁行)。...第三种情况,在 RR 隔离级别下,会在所有命中的行的聚簇索引上加 next-key locks(锁住行间隙)。最后命中的索引的后一条记录,也会被加上 next-key lock。 ?

    2K40

    MySQL加锁范围分析

    场景: 最近,遇到了一个关于mysql 加锁的问题,将当时的情形简化如下,有一个index_test表,表结构如下所示: mysql> CREATE TABLE `index_test` ( `priv_id...Locks: 相当于Record LocksGap Locks的组合 那么这3种锁在哪些场合下使用呢?...然后在网上搜索相关的资料,看看别人有没有遇到过这样的问题,在一篇关于MySQL加锁处理分析的blog中得到了启示,按照blog中组合七:id非唯一索引+RR的理论,gap锁的范围不仅跟被锁定的键有关,还跟主键有关...因此,在我们使用mysql加锁过程中,也首先需要搞清楚,我们的隔离级别是什么,是否开启了binlog等等,然后才能正确分析加锁的范围。...p=771 大神描述Mysql 加锁分析的blog http://hedengcheng.com/?

    6.1K72

    MySQL加锁实战分析

    加锁的基本单位是next-key lock(前开后闭区间) 查找过程中访问到的对象才会加锁 索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为行锁 索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候...,next-key lock退化为间隙锁 加锁的基本单位虽然是next-key lock,但是在具体执行的时候,是要分成间隙锁行锁两段来执行的。...lock,因此加锁范围是(0, 5] 索引c是普通索引,根据规则4,最终会退化成间隙锁(5, 10) 根据规则2,只有访问到的对象才会加锁,由于Session A的查询使用覆盖索引,并不需要访问主键索引...,因此主键索引上没有加任何锁 Session A加的锁为c=5的读锁(5,10)的间隙锁,因此Session B可以执行成功,但是Session C因为间隙锁会被阻塞。...注意我们这里加的是读锁,如果你使用的是for update,MySQL会认为你要更新数据,因此会给主键索引上满足条件的行加上行锁。

    1.1K30

    MySQL 加锁处理分析

    我能想象到的一个答案是: SQL1:不加锁。因为MySQL是使用多版本并发控制的,读不加锁。 SQL2:对id = 10的记录加写锁 (走主键索引)。 这个答案对吗?说不上来。...为什么不是只在满足条件的记录上加锁呢?这是由于MySQL的实现决定的。如果一个条件无法通过索引快速过滤,那么存储引擎层面就会将所有记录加锁后返回,然后由MySQL Server层进行过滤。...这样做,保证了最后只会持有满足条件记录上的锁,但是每条记录的加锁操作还是不能省略的。 结论:若id列上没有索引,SQL会走聚簇索引的全扫描进行过滤,由于过滤是由MySQL Server层面进行的。...组合七:id非唯一索引+RR 还记得前面提到的MySQL的四种隔离级别的区别吗?RC隔离级别允许幻读,而RR隔离级别,不允许存在幻读。但是在组合五、组合六中,加锁行为又是与RC下的加锁行为完全一致。...深入理解MySQL如何加锁,有两个比较重要的作用: 可以根据MySQL加锁规则,写出不会发生死锁的SQL; 可以根据MySQL加锁规则,定位出线上产生死锁的原因; 下面,来看看两个死锁的例子 (一个是两个

    3.5K61

    mysql语句加锁分析

    其实并不能完全解决幻读问题, 这里可以参考另一篇博客[mysql事务隔离级别与加锁分析] SERIALIZABLE隔离级别下,需要分为两种情况讨论: 在系统变量autocommit=0时,也就是禁用自动提交时...= 'cao曹操' WHERE number >= 8; 如果不需要更新二级索引,那么就和SELECT..FOR UPDATE一样 如果需要更新二级索引,对于聚簇索引加锁SELECT..FOR UPDATE...一样,然后再给对应的二级索引加上普通X锁 使用DELETE ...来为记录加锁的情况UPDATE一致 唯一二级索引 等值查询 使用SELECT ......FOR UPDATE语句来为记录加锁,这里上面过程一样,不过这里加的是 XLock 使用UPDATE ...来为记录加锁,这里与SELECT .....[掘金小册-从根上理解MySQL] [公众号:我们都是小青蛙 - MySQL加锁分析三部曲]

    87730

    mysql索引类型索引方式

    1.什么是索引MySQL中,索引(index)也叫做“键(key)”,它是存储引擎用于快速找到记录的一种数据结构。...2.索引的分类 在MySQL中,通常我们所指的索引类型,有以下几种: 主键索引(PRIMARY KEY) 也简称主键。它可以提高查询效率,并提供唯一性约束。一张表中只能有一个主键。...ADD PRIMARY KEY (`name`) USING BTREE; 全文索引(FULL TEXT) 旧版的MySQL的全文索引只能用在MyISAM表格的char、varchartext的字段上...不过新版的MySQL5.6.24上InnoDB引擎也加入了全文索引 添加全文索引 ADD FULLTEXT INDEX `idx_full`(`en_name`); 跟普通索引稍有不同 使用全文索引的格式...二是secondary index,其leaf node普通的BTREE差不多,只是还存放了指向主键的信息. 而在MyISAM里,主键其他的并没有太大区别。

    1K30

    MySQL语句加锁分析详解

    我们说语句一语句二是MySQL中规定的两种锁定读的语法格式,而语句三语句四由于在执行过程需要首先定位到被改动的记录并给记录加锁,也可以被认为是一种锁定读。...,加锁顺序上边语句中的加锁顺序类似,都是先对一条聚簇索引记录加锁后,再给对应的二级索引记录加锁。...对于使用二级索引进行等值查询的情况 小贴士:在READ UNCOMMITTEDREAD COMMITTED隔离级别下,使用普通的二级索引唯一二级索引进行加锁的过程是一样的,所以我们也就不分开讨论了。...LOCK IN SHARE MODE语句的加锁情况类似,都是给访问到的二级索引记录对应的聚簇索引记录加锁,只不过加的是X型正经记录锁罢了。...; 如果这两个语句采用二级索引来进行锁定读,那么它们的加锁情况更新带有二级索引列的UPDATE语句一致,就不画图了。

    1.3K40

    MySQL更新语句加锁

    最左前缀原则 也就是最左优先,这条原则针对的是组合索引前缀索引,理解: 1、在MySQL中,进行条件过滤时,是按照向右匹配直到遇到范围查询(>,<,between,like)就停止匹配,比如说a =...2、= in 可以乱序,比如 a = 1 and b = 2 and c = 3 建立(a, b, c)索引可以任意顺序,MySQL的查询优化器会优化索引可以识别的形式。...组合三、id不唯一索引+RC 该组合中,id列不在唯一,而是个普通索引,那么当执行sql语句时,MySQL又是如何加锁呢?...而MySQL又是如何给上述语句加锁呢?看下图: 该组合组合三看起来很相似,但差别很大,在改组合中加入了一个间隙锁(Gap锁)。这个Gap锁就是相对于RC级别下,RR级别下不会出现幻读情况的关键。...结论:在MySQL/InnoDB中,所谓的读不加锁,并不适用于所有的情况,而是隔离级别有关。在Serializable隔离级别下,所有的操作都会加锁

    2.1K20

    MySQL索引事务

    操作索引的 SQL 查看索引 show index from 表名; primary key 、forigen key unique 都能自动生成索引 索引都是针对列生成的 搜索创建了索引的列才会加快查询速度...创建索引 create index 索引名 on 表名(列名); 创建索引需要在最初创建表的时候规划好 危险操作 删除索引 drop index 索引名 on 表名; 只能删除自己创建的,...事务执行前后,数据库中的数据都是“合法状态”,不会出现非法的临时结果的状态 持久性 事务执行之后,就会修改硬盘上的数据,持久生效 隔离性(最常考) 事务并发执行的时候,相互之间产生的影响是 MySQL...(速度最快) read committed:读已提交 一个事物只能读取另一个事务提交后的数据(给写操作加锁了),此时可能会产生“不可重复读““幻读“问题。...相当于是给“写操作”“读操作”都加锁了。

    10610

    Mysql索引优化

    1、选择索引的数据类型 MySQL支持很多数据类型,选择合适的数据类型存储数据对性能有很大的影响。...在MySQL中,应该用内置的日期时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。 (3)尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。...在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。 1.1、选择标识符 选择合适的标识符是非常重要的。...选择时不仅应该考虑存储类型,而且应该考虑MySQL是怎样进行运算比较的。一旦选定数据类型,应该保证所有相关的表都使用相同的数据类型。...如果对多列进行索引(组合索引),列的顺序非常重要,MySQL仅能对索引最左边的前缀进行有效的查找。

    1.1K60

    Mysql 架构索引

    varbinary:保存二进制字符串,他们保存的是字节而不是字符,填充是\0而不是空格 blob text: 不能索引这些类型的完整长度,也不能为排序使用索引 排序时只按照max_sort_length..._2 = '123' 唯一索引的前缀匹配: NULL:MySQL在优化过程中分解语句,执行时甚至不用访问表或索引, 比如id=-1, min(id) max(id)????...Scan, MySQL将遍历全表以找到匹配的行 possible_keys 指出MySQL能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用 key 显示MySQL...在查询中实际使用的索引,若没有使用索引,显示为NULL key_len 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度, 此值可以告诉你在联合索引mysql会真正使用了哪些索引 key_len...Index) 利用索引返回select列表中的字段,而不必根据索引再次读取数据文件 Using where Using temporary 表示MySQL需要使用临时表来存储结果集,常见于排序分组查询

    1.4K90

    MySQL 创建索引索引效率验证

    连接数据库 先连接 mysql 数据库,进入到 MyDB_one 数据库中。 在 MyDB_one 中有一张表 Phone_table 。 ? 2....在上面的这张表中,现在还没有任何数据,所以也没有索引,查询结果为空 Empty 。 3. 批量插入数据 为了演示创建索引的方法索引的效果,需要先在数据表中添加数据。...conn = connect( host="localhost", port=3306, user="admin", password="Mysql...删除索引后,数据表的索引为空。 三、验证索引的效率 有索引没有索引的表查询效率差距是非常大的。在同一张表中,保持数据不变,查同一条数据,来对比有无索引的查询时间,就可以对比出效率的差异。 1....开启 MySQL 运行时间监测 使用 set profiling=1; 开启 MySQL 运行时间检测,通过运行时间来对比有无索引的效率。

    3K30

    MySQL唯一索引普通索引

    InnoDB; insert into t(id, name, k) values (1, 'Java', 100), (2, 'Python', 200), (3, 'Go', 300), (5, 'MySQL...', 500), (6, 'Spark', 600) 我们使用上节的SQL进行分析普通索引唯一索引的区别。...唯一索引普通索引的插入 假设我们在表中需要插入一条新的数据(4, 'Flink', 400),InnoDB对于唯一索引普通索引的处理有些区别: 假设记录要更新的目标页在内存中,处理流程如下: 如果是唯一索引...,找到300500之间的位置,判断没有冲突,插入该值,语句执行结束 如果是普通索引,找到300500之间的位置,插入该值,语句执行结束 假设记录要更新的目标页不在内存中,处理流程如下: 如果是唯一索引...唯一索引普通索引 唯一索引普通索引在查询性能上基本没有差别,但在更新上普通索引会快于唯一索引。所以在可以选择普通索引的前提下尽可能选择普通索引

    1.7K10

    Mysql索引原理(十一)」索引

    首先,虽然InnoDB的行锁效率很高,内存使用也很少,但是锁定行的时候仍然会带来额外的开销; 其次,锁定超过需要的行会增加锁争用并减少并发性; InnoDB,只有在访问行的时候才会对其加锁...如果索引无法过滤掉无效的行,那么在InnoDB检索到数据并返回给服务器层以后,MySQL服务器才能应用where子句。这时已经无法避免锁定行了,InnoDB已经锁住了这些行,到适当的时候才释放。...InnoDB会锁住第一行,这是因为Mysql为该查询选择的执行计划是索引范围扫描: explain select id from people where id1 for update...就像这个例子显示的,即使使用了索引,InnoDB也可能锁住一些不需要的数据。如果不能使用索引查找锁定行的话问题可能会更糟糕,MySQL会做全表扫描并锁住所有的行,而不管是不是需要。...关于InnoDB、索引锁有一些很少有人知道的细节:InnoDB在二级索引上使用共享锁。

    77020

    Mysql聚集索引非聚集索引

    首先要明确一个概念,在聚集索引的世界里索引就是数据,在最后的叶子索引键保存着对应的数据行。...* from TestNonclusteredIndex where ID = 3; SQL知道ID是聚集索引,因此就去聚集索引里去查找(查找扫描是有区别的),当找到对应的键值的时候里面保存的是 "...如果执行这条查询语句: select * from TestNonclusteredIndex where col1 = 6 SQL知道col1上有非聚集索引,去索引里查找,找到的是6的非聚集索引键值这条记录的聚集索引键值...,因为没有数据(3 6),SQL就用这个聚集索引查找,就上面的例子一样就找到(3 6)这条数据; 其次,你要知道聚集索引是顺序的,到最后的数据页的时候,你知道第一条记录聚集索引是1难道聚集索引为2的记录不是它下一条...,那么聚集索引为N的记录不是1之后的N-1条?

    2.4K50
    领券