目录

  • 产生死锁的必要条件

  • 常规锁模式

  • 锁的属性

  • 锁组合(属性+模式)

  • 锁冲突矩阵

  • 锁是加在那里的?

  • 操作与加锁的对照关系

    • 那些操作会加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 加锁和死锁解析相关推荐

  1. 瞎说系列——Mysql update的执行过程

    要了解mysql update语句的执行过程,首先要了解一下mysql是如何进行数据的操作的. 首先,数据库中的数据存在哪?肯定是文件系统,磁盘上对吧.那么思考一下,每次查询都从磁盘上去查找吗? 答案 ...

  2. mysql update 排他锁_Mysql 共享锁(lock in share mode),排他锁(for update)

    共享锁(lock in share mode) 简介 允许不同事务之前共享加锁读取,但不允许其它事务修改或者加入排他锁 如果有修改必须等待一个事务提交完成,才可以执行,容易出现死锁 共享锁事务之间的读 ...

  3. 坑爹的MySql update in subquery

    title: 坑爹的MySql update in subquery tags: mysql update in 子查询 subquery categories: mysql date: 2017-1 ...

  4. mysql update w3c_PHP MySQL Update

    PHP MySQL Update 对于 MySQL 数据库中的数据你可以根据需要进行更新! UPDATE 语句用于中修改数据库表中的数据. 更新数据库中的数据 UPDATE 语句用于更新数据库表中已存 ...

  5. mysql set 子表,mysql update set 更新表数据

    1.update ...set...where... 题目:修改students id=2的name为"yanxia" mysql>update  students  set ...

  6. PHP MySQL Update

    PHP MySQL Update UPDATE 语句用于中修改数据库表中的数据. 更新数据库中的数据 UPDATE 语句用于更新数据库表中已存在的记录. 语法 UPDATE table_name SE ...

  7. mysql菜鸟教程update_PHP MySQL Update

    PHP MySQL Update UPDATE 语句用于中修改数据库表中的数据. 更新数据库中的数据 UPDATE 语句用于更新数据库表中已存在的记录. 语法 UPDATE table_name SE ...

  8. mysql update delete_MySQL中UPDATE与DELETE语句的使用教程

    UPDATE 更新UPDATE SET 语法用于修改更新数据表中的数据. 语法: UPDATE tb_name SET column1 = new_value1,column2 = new_value ...

  9. mysql update中使用subquery

    首先,在mysql workbench内执行update时,缺省是使用安全更新模式的,如果在update sql内的where没有指定id等主键条件,会告警并推出执行.你可以关闭安全模式,执行如下语句 ...

最新文章

  1. 人工智能呼唤社会科学家
  2. php中函数的定义格式,在php中函数定义的格式
  3. 【iCore3 双核心板_ uC/OS-III】例程一:认识 uC/OS-III
  4. kaggle 房价预测经典文章
  5. Redis-13Redis发布订阅
  6. Android --- Android layout属性应有尽有
  7. python3 yield 大文件_详解Python3中yield生成器的用法
  8. android 如何使用SAX解析XML
  9. CodeForces - 1345E Quantifier Question(dfs实现拓扑序)
  10. CodeForces - 1265D Beautiful Sequence(贪心+构造+思维)
  11. 浅析正则表达式——柳暗花明又一村篇
  12. layui选项卡嵌套选项卡_在ProtoPie中使用嵌套组件构建选项卡栏
  13. html5的canvas动画,Canvas HTML5简介 · Canvas动画教程
  14. 肝火旺的人,哪些食物打死都不要碰?
  15. 做开发很久了 Remoting 一直没有碰过,正好最近的项目上面用,就拿出来给大家看看
  16. 中国行政划分代码(身份证号码前六位)
  17. SQL SERVER数据库中勒索病毒 SQL数据库中病毒恢复数据
  18. 【Linux安装】Win10安装Ubuntu双系统(含BIOS操作)
  19. 配置文件(properties类)
  20. 什么是用户代理样式表

热门文章

  1. invoke 数组_对于反射中的invoke()方法的理解
  2. 华为荣耀手机指令代码大全_双十二,华为/荣耀手机推荐选购指南,全系列横评推荐,那一款华为/荣耀手机最值得够买...
  3. androidstudio表格中填充 宽跟长一样_Excel表格的基本操作教程,覆盖表格制作的10大知识!...
  4. python基础入门:while 循环
  5. python中使用for循环,while循环,一条命令打印99乘法表
  6. python函数不定参数求和
  7. 【黑马程序员 C++教程从0到1入门编程】【笔记1】数据类型、运算符、程序流程结构、数组、函数、指针、结构体
  8. tensorflow tf.name_scope() 命名空间(用于规定对象和操作属于哪个区域)
  9. 为什么不使用volatile,其它线程也能得到当前线程修改后的值,不使用volatile也不存在可见性问题?原来解决可见性问题不一定需要volatile,println也可以
  10. Blue-Red Permutation 贪心,思维