mysql update用not in太慢了_MySQL 加锁和死锁解析
目录
产生死锁的必要条件
常规锁模式
锁的属性
锁组合(属性+模式)
锁冲突矩阵
锁是加在那里的?
操作与加锁的对照关系
那些操作会加GAP锁?
如何去掉GAP锁?
Insert
Delete
Update
GAP锁
什么时候加next-key lock?
Insert Intention Lock
总结
产生死锁的必要条件
多个并发事务(2个或者以上)
每个事物都持有了锁(或者是已经在等待锁)
每个事务都需要再继续持有锁(为了完成事务逻辑,还必须更新更多的行)
事物之间产生加锁的循环等待,形成死锁
常规锁模式
LOCK_S(读锁,共享锁)
LOCK_X(写锁,排它锁)
锁的属性
LOCK _REC_NOT_GAP(锁记录)
LOCK_GAP(锁记录前的GAP)
LOCK_ORDINARY(同时锁记录+记录前的GAP,Next key锁)
LOCK_INSERT_INTETION(插入意向锁)
锁组合(属性+模式)
可以任意组合
锁冲突矩阵
锁是加在哪里的?
根据主键查找-锁加在主键上
如 begin;select * from tt_copy where id=4 for update;加锁情况
index PRIMARY of table test.tt_copy trx id 1101588 lock_mode X locks rec but not gap
根据普通索引查找-锁加在普通索引和主键上
如 begin;select * from tt_copy force index(idx_a) where a=4 for update;加锁情况index idx_a of table test.tt_copy trx id 1101590 lock_mode X locks rec but not gap
index PRIMARY of table test.tt_copy trx id 1101590 lock_mode X locks rec but not gap操作与加锁的对照关系以下没特殊说明都为RC隔离级别Insert
无Unique key,插入后 :
无论RC或RR隔离级别都是对主键加 LOCK_X+LOCK_REC_NOT_GAP
有Unique key
插入前,唯一约束检查:LOCK_S+LOCK_ORDINARY
插入前,插入的位置有GAP锁:LOCK_INSERT_INTETION
插入后,新数据插入:LOCK_X+LOCK_REC_NOT_GAP
Delete
满足删除条件的所有记录:LOCK_X+LOCK_REC_NOT_GAP
Update
**Update操作分解 **
Step 1:
定位到 下一条满足查询条件的记录(查询过程,类似于Select/Delete)
Step 2:
删除当前定位到的记录(标记为删除状态)
Step 3:
拼装更新后项,根据更新后项定位到 新的插入位置
Step 4:
在新的插入位置,判断是否存在 Unique 冲突( 存在Unique Key 时)
Step 5:
插入更新后项(不存在Unique冲突时)
Step 6:
重复Step 1 到Step 5 的操作,直至扫描完整个查询范围
Update操作分析
Step 1,Step 2:
Delete
Step 3,Step 4,Step 5:
Insert
Update
无Unique key:
查询范围中的所有记录,LOCK_X + LOCK_REC_NOT_GAP
有Unique key:
查找满足条件的记录:
查询范围内的所有记录, LOCK_X + LOCK_REC_NOT_GAP
更新后项存在唯一性冲突:
冲突项上的加锁,LOCK_S + LOCK_ORDINARY
更新后项不存在唯一性冲突:
更新位置后项加锁,LOCK_S + LOCK_GAP (省略)
实际更新操作:
可看做插入了一条新纪录,LOCK_X + LOCK_REC_NOT_GAP
GAP锁那些操作会加GAP锁?
Read Committed (RC) ) :
Unique Key 唯一约束检查;
Purge操作;
Repeatable Read (RC ):
RC的基础上,所有需要加锁的索引范围扫描和索引查找(Update/Delete…)
还有一种会加GAP锁:
RR隔离级别下,对有唯一索引的表执行insert on duplicate update操作,除了会对新插入的记录加x not gap外,还会对相邻记录加x gap
如何去掉GAP锁?
change the transaction isolation level to READ COMMITTED or enable the innodb_locks_unsafe_for_binlog system variable (which is now deprecated)
什么时候加next-key lock?
By default, InnoDB operates in REPEATABLE READ transaction isolation level. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows
Insert Intention Lock
An insert intention lock is a type of gap lock set by INSERT operations prior to(在...之前) row insertion.
总结
• 原则之一
要分析一个死锁,必须深入业务,了解整个事务的逻辑(闭门无法造车)
• 原则之二`
GAP锁很复杂,为了减少GAP锁,减少GAP导致的死锁,尽量选择Read Committed隔离级别(RC + row based binlog,基本上能够解决所有问题,无需使用Repeatable Read)
适当的 减少Unique 索引,能够减少GAP锁导致的死锁(根据业务情况而定)
• 原则之三
在MySQL 中,以不同索引的过滤条件, 来操作相同的记录(Update/Delete ),很容易产生死
锁。
• 原则之四
RC隔离级别下,如果死锁中出现Next Key(Gap锁),说明表中一定存在unique索引
多语句事务产生的死锁,确保每条语句操作记录的顺序性,能够极大减少死锁
作者:jiaxin
出处:cnblogs.com/YangJiaXin/
mysql update用not in太慢了_MySQL 加锁和死锁解析相关推荐
- 瞎说系列——Mysql update的执行过程
要了解mysql update语句的执行过程,首先要了解一下mysql是如何进行数据的操作的. 首先,数据库中的数据存在哪?肯定是文件系统,磁盘上对吧.那么思考一下,每次查询都从磁盘上去查找吗? 答案 ...
- mysql update 排他锁_Mysql 共享锁(lock in share mode),排他锁(for update)
共享锁(lock in share mode) 简介 允许不同事务之前共享加锁读取,但不允许其它事务修改或者加入排他锁 如果有修改必须等待一个事务提交完成,才可以执行,容易出现死锁 共享锁事务之间的读 ...
- 坑爹的MySql update in subquery
title: 坑爹的MySql update in subquery tags: mysql update in 子查询 subquery categories: mysql date: 2017-1 ...
- mysql update w3c_PHP MySQL Update
PHP MySQL Update 对于 MySQL 数据库中的数据你可以根据需要进行更新! UPDATE 语句用于中修改数据库表中的数据. 更新数据库中的数据 UPDATE 语句用于更新数据库表中已存 ...
- mysql set 子表,mysql update set 更新表数据
1.update ...set...where... 题目:修改students id=2的name为"yanxia" mysql>update students set ...
- PHP MySQL Update
PHP MySQL Update UPDATE 语句用于中修改数据库表中的数据. 更新数据库中的数据 UPDATE 语句用于更新数据库表中已存在的记录. 语法 UPDATE table_name SE ...
- mysql菜鸟教程update_PHP MySQL Update
PHP MySQL Update UPDATE 语句用于中修改数据库表中的数据. 更新数据库中的数据 UPDATE 语句用于更新数据库表中已存在的记录. 语法 UPDATE table_name SE ...
- mysql update delete_MySQL中UPDATE与DELETE语句的使用教程
UPDATE 更新UPDATE SET 语法用于修改更新数据表中的数据. 语法: UPDATE tb_name SET column1 = new_value1,column2 = new_value ...
- mysql update中使用subquery
首先,在mysql workbench内执行update时,缺省是使用安全更新模式的,如果在update sql内的where没有指定id等主键条件,会告警并推出执行.你可以关闭安全模式,执行如下语句 ...
最新文章
- 人工智能呼唤社会科学家
- php中函数的定义格式,在php中函数定义的格式
- 【iCore3 双核心板_ uC/OS-III】例程一:认识 uC/OS-III
- kaggle 房价预测经典文章
- Redis-13Redis发布订阅
- Android --- Android layout属性应有尽有
- python3 yield 大文件_详解Python3中yield生成器的用法
- android 如何使用SAX解析XML
- CodeForces - 1345E Quantifier Question(dfs实现拓扑序)
- CodeForces - 1265D Beautiful Sequence(贪心+构造+思维)
- 浅析正则表达式——柳暗花明又一村篇
- layui选项卡嵌套选项卡_在ProtoPie中使用嵌套组件构建选项卡栏
- html5的canvas动画,Canvas HTML5简介 · Canvas动画教程
- 肝火旺的人,哪些食物打死都不要碰?
- 做开发很久了 Remoting 一直没有碰过,正好最近的项目上面用,就拿出来给大家看看
- 中国行政划分代码(身份证号码前六位)
- SQL SERVER数据库中勒索病毒 SQL数据库中病毒恢复数据
- 【Linux安装】Win10安装Ubuntu双系统(含BIOS操作)
- 配置文件(properties类)
- 什么是用户代理样式表
热门文章
- invoke 数组_对于反射中的invoke()方法的理解
- 华为荣耀手机指令代码大全_双十二,华为/荣耀手机推荐选购指南,全系列横评推荐,那一款华为/荣耀手机最值得够买...
- androidstudio表格中填充 宽跟长一样_Excel表格的基本操作教程,覆盖表格制作的10大知识!...
- python基础入门:while 循环
- python中使用for循环,while循环,一条命令打印99乘法表
- python函数不定参数求和
- 【黑马程序员 C++教程从0到1入门编程】【笔记1】数据类型、运算符、程序流程结构、数组、函数、指针、结构体
- tensorflow tf.name_scope() 命名空间(用于规定对象和操作属于哪个区域)
- 为什么不使用volatile,其它线程也能得到当前线程修改后的值,不使用volatile也不存在可见性问题?原来解决可见性问题不一定需要volatile,println也可以
- Blue-Red Permutation 贪心,思维