记录锁Record Lock与间隔锁GAP Lock

记录锁Record Lock

记录锁Record Locks又称为行锁,它同时包含索引和间隔锁。记录锁可以是共享锁也可能是排他锁。可以通过performance_schema.data_locks表的LOCK_TYPE和LOCK_MODEL来查看。

示意案例

-- Step1 开始事务,更新city的Population字段,这里更新时通过辅助索引里的字段CountryCode。
START TRANSACTION;
UPDATE city
SET Population = Population + 1
WHERE CountryCode = 'LUX';-- Step2 查看锁情况。
mysql> SELECT * FROM performance_schema.data_locks \G
*************************** 1. row ***************************ENGINE: INNODBENGINE_LOCK_ID: 139740117241856:1067:139740049392448
ENGINE_TRANSACTION_ID: 38181THREAD_ID: 49EVENT_ID: 130OBJECT_SCHEMA: worldOBJECT_NAME: cityPARTITION_NAME: NULLSUBPARTITION_NAME: NULLINDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 139740049392448LOCK_TYPE: TABLELOCK_MODE: IXLOCK_STATUS: GRANTEDLOCK_DATA: NULL
*************************** 2. row ***************************ENGINE: INNODBENGINE_LOCK_ID: 139740117241856:6:20:344:139740049389536
ENGINE_TRANSACTION_ID: 38181THREAD_ID: 49EVENT_ID: 130OBJECT_SCHEMA: worldOBJECT_NAME: cityPARTITION_NAME: NULLSUBPARTITION_NAME: NULLINDEX_NAME: CountryCode
OBJECT_INSTANCE_BEGIN: 139740049389536LOCK_TYPE: RECORDLOCK_MODE: XLOCK_STATUS: GRANTEDLOCK_DATA: 'LUX', 2452
*************************** 3. row ***************************ENGINE: INNODBENGINE_LOCK_ID: 139740117241856:6:23:104:139740049389880
ENGINE_TRANSACTION_ID: 38181THREAD_ID: 49EVENT_ID: 130OBJECT_SCHEMA: worldOBJECT_NAME: cityPARTITION_NAME: NULLSUBPARTITION_NAME: NULLINDEX_NAME: PRIMARY
OBJECT_INSTANCE_BEGIN: 139740049389880LOCK_TYPE: RECORDLOCK_MODE: X,REC_NOT_GAPLOCK_STATUS: GRANTEDLOCK_DATA: 2452
*************************** 4. row ***************************ENGINE: INNODBENGINE_LOCK_ID: 139740117241856:6:20:326:139740049390224
ENGINE_TRANSACTION_ID: 38181THREAD_ID: 49EVENT_ID: 130OBJECT_SCHEMA: worldOBJECT_NAME: cityPARTITION_NAME: NULLSUBPARTITION_NAME: NULLINDEX_NAME: CountryCode
OBJECT_INSTANCE_BEGIN: 139740049390224LOCK_TYPE: RECORDLOCK_MODE: X,GAPLOCK_STATUS: GRANTEDLOCK_DATA: 'LVA', 2434通过结果不难发现这里的意向锁是排他锁,状态是“GRANTED”,第二行里显示next-key锁在索引CountryCode上,LOCK_TYPE为记录。这里结合当前的WHERE条件对应的是锁定的数据为“’LUX’, 2452”,这里的2452对应的是主键的ID。
这里不难验证city表里CountryCode为’LUX’的主键即ID为2452。第三行显示的锁的主键信息,其中LOCK_TYPE为记录、LOCK_MODEL为X,REC_NOT_GAP即是个排他锁,但不是间隔锁。第四行显示的间隔锁的信息(主键或者索引里两个记录之间的间隔),详见间隔锁里的说明。-- Step3 验证完后还原事务。
Rollback

间隔锁Gap Lock

间隔锁Gap Locks会锁定两条记录之间的空间,这种锁往往出现在聚集索引(即主键)和辅助索引(非聚集索引的其它索引的统称)里。

在索引页的第一条记录之前和该页的最后一条记录之后,分别有伪记录,称为下界记录(infimum record)和上界记录(supremum record)。

回到记录锁(Record Locks)里的例子,即将city表里CountryCode 是’LUX'的记录(仅有1条)里的Population字段进行更新,加1。如果在执行这个操作的时候,往表city里插入了一条或多条CountryCode 是’LUX'的新记录,会出现什么问题呢?如果UPDATE先执行,INSERT后执行则没有问题,如果反过来过来则会出现不一致的情况。即新插入的数据在后面又被更新掉了(这和预期不符)。所以这时需要用到间隔锁(Gap Lock),它的作用就是锁定当前索引页和下一个索引页这段间隔记录,即如果有INSERT,那么必须得之前的UPDATE执行完了才能操作。

在记录锁的示意案例的第4行里,我们可以看到间隔锁的相关信息,这里锁定的是索引页的‘LVA’, 2434,通过查询可以知道索引CountryCode的LUX的下一个即是LVA,所以这里锁定的是索引里对应这条记录。即在“LUX”“LVA”之间的记录加了排他的间隔锁。当然插入CountryCode为LVA的记录是可以的。

和间隔锁相关的锁有next-key locks和predicate locks.next-key锁时记录锁和间隔锁的组合(详见记录锁里的示例案例)。

*************************** 2. row ***************************

ENGINE: INNODB

ENGINE_LOCK_ID: 139740117241856:6:20:344:139740049389536

ENGINE_TRANSACTION_ID: 38181

THREAD_ID: 49

EVENT_ID: 130

OBJECT_SCHEMA: world

OBJECT_NAME: city

PARTITION_NAME: NULL

SUBPARTITION_NAME: NULL

INDEX_NAME: CountryCode

OBJECT_INSTANCE_BEGIN: 139740049389536

LOCK_TYPE: RECORD

LOCK_MODE: X

LOCK_STATUS: GRANTED

LOCK_DATA: 'LUX', 2452

*************************** 3. row ***************************

ENGINE: INNODB

ENGINE_LOCK_ID: 139740117241856:6:23:104:139740049389880

ENGINE_TRANSACTION_ID: 38181

THREAD_ID: 49

EVENT_ID: 130

OBJECT_SCHEMA: world

OBJECT_NAME: city

PARTITION_NAME: NULL

SUBPARTITION_NAME: NULL

INDEX_NAME: PRIMARY

OBJECT_INSTANCE_BEGIN: 139740049389880

LOCK_TYPE: RECORD

LOCK_MODE: X,REC_NOT_GAP

LOCK_STATUS: GRANTED

LOCK_DATA: 2452

*************************** 4. row ***************************

ENGINE: INNODB

ENGINE_LOCK_ID: 139740117241856:6:20:326:139740049390224

ENGINE_TRANSACTION_ID: 38181

THREAD_ID: 49

EVENT_ID: 130

OBJECT_SCHEMA: world

OBJECT_NAME: city

PARTITION_NAME: NULL

SUBPARTITION_NAME: NULL

INDEX_NAME: CountryCode

OBJECT_INSTANCE_BEGIN: 139740049390224

LOCK_TYPE: RECORD

LOCK_MODE: X,GAP

LOCK_STATUS: GRANTED

LOCK_DATA: 'LVA', 2434

这里第2行即是next-key锁(InnoDB默认的锁类型),而第3行是在主键上的记录锁,第行是“LUX”到“LVA”之间的间隔锁。

predicate locks类似于间隔锁gap lock,它主要应用于使用坐标的空间场景里。通过使用该锁锁定查询中的最小边界矩形(minimum bounding rectangle)简称MBR,这样能防止对最小边界矩形内的数据进行更改已达到数据一致的目的。

示意案例

同记录锁。

Mysql 死锁过程及案例详解之记录锁与间隔锁Record Lock Gap Lock相关推荐

  1. Mysql 死锁过程及案例详解之用户自定义锁

    Mysql 用户自定义锁介绍 锁简介 当多个请求连接到数据库时,能保证同类查询执行时不相互冲突的机制即是锁.比如马路上的信号灯就是一个解决冲突的例子,在一定的时间内锁定了能通行的方向或者路线.MySQ ...

  2. Mysql 死锁过程及案例详解之插入意向锁与自增锁备份锁日志锁Insert Intention Lock Auto-increment Lock Backup Lock Log Lock

    Mysql 插入意向锁与自增锁备份锁日志锁 插入意向锁Insert Intention Lock 插入意向锁Insert intention locks是记录级别的,它通过"INSERT&q ...

  3. Mysql 死锁过程及案例详解之显式与隐式锁Explicit Table Lock Implicit Table Lock

    显式锁Explicit Table Lock与隐式锁Explicit Table Lock 显式锁Explicit Table Lock 显式表锁(Explicit Table Locks)即通过命令 ...

  4. Mysql 死锁过程及案例详解之元数据锁MetaData Lock

    Mysql数据锁MetaData Lock 元数据锁MetaData Lock 元数据锁MetaData Locks的主要作用是在执行查询或者发起事务时元数据结构受到保护,即不被修改. MetaDat ...

  5. Mysql 死锁过程及案例详解之清空缓存锁Flush Lock

    Mysql 清空缓存锁Flush Lock 清空缓存锁Flush Locks flush table的功能是关闭所有打开的表,强制关闭所有正在使用的表,并刷新准备好的语句缓存. 这种操作需要用户拥有  ...

  6. wow mysql dbc_DBC中悲观锁介绍附案例详解

    DBC中悲观锁介绍附案例详解 了解下DBC中悲观锁: 代码如下: BDUtils 工具类: package JDBC; import java.sql.*; public class BDUtils ...

  7. mysql 自动截断_MySql中关于超长自动截断的案例详解

    这篇文章主要介绍了MySql超长自动截断实例详解的相关资料,这里通过实例来说明如何实现自动截断的功能,需要的朋友可以参考下 MySql超长自动截断实例详解 小伙伴问到一个问题,为啥在项目中调用插入或者 ...

  8. 数据湖架构Hudi(五)Hudi集成Flink案例详解

    五.Hudi集成Flink案例详解 5.1 hudi集成flink flink的下载地址: https://archive.apache.org/dist/flink/ Hudi Supported ...

  9. 代码检查规则:Python语言案例详解

    在之前的文章中代码检查规则:Java语言案例详解学习了Java的检查规则.我们今天将学习<代码检查规则:Python语言案例详解>,内容主要分为两个部分:Python的代码检查规则和Pyt ...

最新文章

  1. STL Priority_Queue
  2. ajax请求挂起_Ajax请求内部循环挂起浏览器?
  3. 故障转移集群仲裁盘_windows 2012 标准版 集群 仲裁盘和共享盘无法转移
  4. GDOI2021划水记
  5. Mockito – JAXB的RETURNS_DEEP_STUBS
  6. 【Html】Html基本标记
  7. stm32双向可控硅调压程序_双向可控硅的工作原理
  8. 【推荐视频】分布式机器学习框架如何助力高维实时推荐系统
  9. caffe 源码阅读与运行流程
  10. 三菱PLC快速实现OPC UA
  11. jsp登陆界面链接mysql_用jsp实现网站登录界面的制作,并连接数据库
  12. 60著名条原则和定理
  13. 通过js实现单击显示隐藏图片
  14. C++中的RVO、NRVO与Copy Elision
  15. 动目标检测算法——高斯混合背景建模
  16. 累加器使用的注意点及自定义累加器
  17. LINUX新手入门及安装配置FAQ(http://bbs.blueidea.com/viewthread.php?tid=635906amp;page=)
  18. trans系列平移距离模型
  19. 三大传统招聘门户因商务社交网被迫谋变
  20. 前端利用Canvas+Video合并流实现截屏和录屏功能

热门文章

  1. JavaScript实现数乘以二multiplyByTwo算法(附完整源码)
  2. wxWidgets:wxDynamicLibrary类用法
  3. boost::swap_ranges相关的测试程序
  4. boost::range模块adjacent_filtered相关的测试程序
  5. 一个简单的你好,世界! 使用 Boost.MPI 消息传递的示例
  6. boost::boost::directed_graph用法的测试程序
  7. boost::geometry::svg用法的测试程序
  8. boost::array用法的测试程序
  9. QML中的定位器和布局
  10. Qt第三方Android库