为什么 InnoDB 中的 IX 锁与另一个 IX 锁兼容?

2023-11-26

根据innodb锁模式 锁类型兼容性矩阵

    X           IX          S           IS
X   Conflict    Conflict    Conflict    Conflict
IX  Conflict    Compatible  Conflict    Compatible
S   Conflict    Conflict    Compatible  Compatible
IS  Conflict    Compatible  Compatible  Compatible

IX兼容于IX,但事实是如果我们获得一个IX lock by

select c1 from z where c1 = 1 for update

在会话 1 中,尝试获取IX by

select c1 from z where c1 = 1 for update

会在会话2中被阻止,所以我认为它们不兼容。我在这里错过了什么吗?


最后解释:

之所以

select ... for update

在一个会话块中

select ... for update

另一方面是他们不仅要求IX还可以锁定表级别X锁定行级别。这一切都是因为X lock.


https://dev.mysql.com/doc/refman/5.6/en/innodb-lock-modes.html says:

因此,意向锁不会阻止除全表请求(例如,LOCK TABLES ... WRITE)之外的任何内容。 IX 和 IS 锁的主要目的是表明有人正在锁定一行,或者将要锁定表中的一行。

这意味着多个线程可以获取 IX 锁。这些锁位于表级,而不是行级。 IX 锁意味着持有它的线程打算更新某些行某处在表中。 IX 锁仅用于阻止全表操作。

如果您考虑到它是双向的,那么它可能会有所启发——如果正在进行全表操作,则该线程具有阻止 IX 锁的表级锁。

DML 操作必须首先获取 IX 锁,然后才能尝试行级锁。原因是您不希望在ALTER TABLE正在进行中,或者当其他线程已经完成时LOCK TABLES...WRITE.

行级更改如UPDATE, DELETE, SELECT..FOR UPDATE不被 IX 锁阻止。它们被其他行级更改或实际的全表锁阻止(LOCK TABLES,或某些 DDL 语句)。但除了这些表操作之外,运行 DML 的多个线程可能可以并发工作,只要它们各自处理一组不重叠的行即可。


回复您的评论:

第二SELECT...FOR UPDATE不会阻塞等待 IX 锁,而是阻塞等待已被另一个线程中的 X 锁锁定的行上的 X(行级)锁。

我刚刚尝试过这个然后我就跑了SHOW ENGINE INNODB STATUS这样我就可以看到被阻止的交易:

---TRANSACTION 71568, ACTIVE 12 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 10, OS thread handle 140168480220928, query id 288 localhost root statistics
select * from test where id=1 for update
------- TRX HAS BEEN WAITING 12 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 802 page no 3 n bits 72 index `PRIMARY` of table `test`.`test` 
trx id 71568 lock_mode X locks rec but not gap waiting

看?它说它正在等待被授予 lock_mode X 上的锁主键索引表的test。那是行级锁。


回复您的困惑LOCK IN SHARE MODE:

你说的是three的水平SELECT.

  • SELECT不请求锁。没有锁阻止它,它也不会阻止其他锁。
  • SELECT ... LOCK IN SHARE MODE请求表上的 IS 锁,然后请求与索引扫描匹配的行上的 S 锁。多个线程可以持有表上的 IS 锁或 IX 锁。多个线程可以同时持有S锁。
  • SELECT ... FOR UPDATE请求表上的 IX 锁,然后请求与索引扫描匹配的行上的 X 锁。 X 锁是独家的这意味着他们不能让任何其他线程拥有 X 锁or同一行上有 S 锁。

但 X 锁和 S 锁都不关心 IX 锁或 IS 锁。

想想这个比喻:想象一个博物馆。

许多人,包括参观者和策展人,进入博物馆。参观者想要观看画作,因此他们佩戴了标有“IS”的徽章。策展人可能会更换画作,因此他们佩戴标有“IX”的徽章。博物馆内可以同时有很多人,同时持有两种类型的胸卡。他们不互相阻挡。

在参观期间,严肃的艺术爱好者将尽可能靠近这幅画,并进行长时间的研究。他们很高兴让其他艺术爱好者站在他们旁边,欣赏同一幅画。因此他们正在做SELECT ... LOCK IN SHARE MODE他们有“S”锁,因为他们至少不希望在研究这幅画时被替换。

策展人可以更换一幅画,但他们对严肃的艺术爱好者很有礼貌,他们会等到这些观众完成后继续前进。所以他们正在努力做SELECT ... FOR UPDATE(或者简单地UPDATE or DELETE)。他们此时将获得“X”锁,方法是悬挂一个小牌子,上面写着“展览正在重新设计”。严肃的艺术爱好者希望看到艺术以适当的方式呈现,有漂亮的灯光和一些描述性的匾额。他们会在接近之前等待重新设计完成(如果他们尝试,他们会得到锁定等待)。

此外,您可能去过博物馆,那里有更多休闲游客闲逛,试图避开其他人。他们从房间中间看画,而不是靠得太近。他们可以看到其他观众正在看的同样的画作,他们可以从严肃的艺术爱好者的肩膀上偷看,看看那些正在被观看的画作。他们甚至可能在策展人更换画作时呆呆地看着他们(他们不在乎是否看到一幅尚未正确安装和照明的画作)。所以这些偶然的访客不会阻挡任何人,也没有人阻挡他们的观看。他们只是在做SELECT并且他们不请求任何锁。

但也有一些建筑工人应该拆除墙壁和其他东西,但当建筑物里有人时他们不会工作。他们会等待所有人离开,一旦开始工作,他们就不会让任何人进来。这就是 IS 和 IX 徽章的存在如何阻止 DDL(建筑工作)的原因,反之亦然。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 InnoDB 中的 IX 锁与另一个 IX 锁兼容? 的相关文章

  • 如何导出带有数据的 MySQL 架构?

    我有一个完整的架构 其中有许多表 其中包含 MySQL 查询浏览器中的数据 现在我想将这个包含所有表 数据的完整数据库发送给我的同事 我怎样才能将其发送给我的同事 以便他可以将这个完整的架构放入他的 MySQL 查询浏览器中 Thanks
  • MySQL集群启动失败

    这不是我第一次创建ndbcluster 但我没有收到这样的问题 我正在关注本手册 https hub docker com r mysql mysql cluster by mysql团队 我正在使用回显的默认配置在此 GitHub 存储库
  • 如何在不饥饿的情况下锁定 std::mutex

    在我的程序中 我有一个互斥体和两个线程 这些线程之一经常获取锁 另一个线程尝试获取但必须永远等待 难道释放锁后获取锁的速度太快 以至于其他线程没有机会获得锁 互斥体总是给每个人一个机会吗 如果没有 什么是一个好的解决方案 某种 FIFO 锁
  • 日期时间与时间戳字段

    我是 MySQL 数据库的新手 您是否建议在表创建中使用日期时间或时间戳字段以及原因 我正在使用 MySQL 5 7 和 innodb 引擎 Thanks 我会用TIMESTAMP对于任何需要自动管理的事情 因为它支持诸如ON UPDATE
  • mysql表中的数据非常大。即使 select 语句也需要很多时间

    我正在开发一个数据库 它是一个相当大的数据库 有 13 亿行和大约 35 列 这是我检查表状态后得到的结果 Name Table Name Engine InnoDB Version 10 Row format Compact Rows 1
  • MySQL 将表从 Latin1 转换为 utf8

    我需要将包含大量数据的表从 Latin1 转换为 utf8 以便它可以接受韩语字符 如何更改该表而不损坏其中的数据 我的 SQL 语句是什么 最好的方法是什么 ALTER TABLE database name table name CON
  • 如何在查询语句之外从mysql查询中获取值?

    这是下面的函数console log function quo value value connection query SELECT role from roles where id 1 function error results fi
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver
  • MySQL正则表达式:如何将字符串中的数字与\d匹配?

    我有一个专栏release date它以字符串格式存储日期 不是 DATETIME 格式 因为它们有时可以是任何其他字符串文字 我想根据给定的月份和年份查找任意日期的所有记录 尝试遵循但对我不起作用 gt Post find all con
  • “修改列”与“更改列”

    我知道 我们不能使用重命名列MODIFY COLUMN语法 但我们可以使用CHANGE COLUMN syntax 我的问题是 主要用途是什么modify syntax 例如 ALATER TABLE tablename CHANGE co
  • 针对约 225 万行的单表选择查询的优化技术?

    我有一个在 InnoDB 引擎上运行的 MySQL 表 名为squares大约有 2 250 000 行 表结构如下 squares square id int 7 unsigned NOT NULL ref coord lat doubl
  • 使用用户定义函数 MySql 时出错

    您好 请帮我解决这个问题 提前致谢 我在数据库中定义了这些函数 CREATE FUNCTION levenshtein s1 VARCHAR 255 s2 VARCHAR 255 RETURNS INT DETERMINISTIC BEGI
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User
  • rake db 问题:迁移 -

    我无法为 Ruby on Rails 设置 MySQL 数据库 设置数据库并确保 config database yml 文件匹配后 我遇到了以下错误消息 U Rails alpha gt rake db migrate trace in
  • 如何对 SQL 进行多次查询

    我正在尝试创建一个表 并在 PHP 脚本的帮助下在数据库中插入一些值 虽然只插入 1 行 但效果很好 当我尝试输入更多行数时 出现错误 我需要为每个查询编写完整的插入语句 因为我正在使用在线 Excel 到 SQL 查询转换器
  • MySQL InnoDB 约束不起作用

    我偶然发现 innoDB 约束的奇怪行为 但找不到原因 我有包含数据的表格 下面列出了它们的结构 CREATE TABLE contents id int 10 unsigned NOT NULL AUTO INCREMENT title
  • Google Cloud SQL 上的故障转移如何运作?

    我打算将 PHP 应用程序 从 Google Cloud Platform 外部的服务器 连接到 Google Cloud SQL 我想知道如何设计应用程序以正确地对其数据库进行故障转移 根据manual https cloud googl
  • 重写 URL,将 ID 替换为查询字符串中的标题

    我对 mod rewrite 很陌生 但我做了一些搜索 但找不到这个问题的答案 我有一个网站 它只有一个 PHP 页面 根据查询字符串中传递给它的 ID 提供数十页内容 我想重写 URL 以便此 ID消失并替换为从数据库中提取的页面标题 例
  • 奇怪的 MySQL Python mod_wsgi 无法连接到 'localhost' (49) 上的 MySQL 服务器问题

    StackOverflow上也有类似的问题 但我还没有发现完全相同的情况 这是在使用 MySQL 的 OS X Leopard 机器上 一些起始信息 MySQL Server version 5 1 30 Apache 2 2 13 Uni
  • 对象锁定私有类成员 - 最佳实践? (爪哇)

    I asked 类似的问题 https stackoverflow com questions 10548066 multiple object locks in java前几天 但对回复不满意 主要是因为我提供的代码存在一些人们关注的问题

随机推荐

  • 如何在 Hibernate 查询语言中执行左连接?

    这是我的 HQL 查询 但它不起作用并且抛出错误 Hql查询 SELECT FROM TABLEA A LEFT JOIN A TABLEB B WHERE A COLUMNNAME B COLUMNAME 它会导致此错误 org hibe
  • 到底什么是“objc_msgSend_fixup”?

    我正在摆弄 Objective C 运行时 尝试编译 Objective C 代码而不将其链接到libobjc 并且我的程序遇到了一些分段错误问题 因此我从中生成了一个汇编文件 我认为没有必要显示整个汇编文件 在我的某个时刻main函数 我
  • 模块依赖于 Dagger 中的另一个模块

    我正在尝试使用Dagger在我正在构建的应用程序上进行依赖注入 当我有一个包的模块依赖于注入器提供的值 可能是由另一个模块提供 时 在构建正确的 DAG 时遇到了麻烦 如果我有一个用于某些可配置变量的简单模块 例如 我可能想将其换成测试环境
  • LINQ 有多快?

    我需要操作 100 000 200 000 条记录 我正在考虑使用 LINQ 到 SQL 来做到这一点 根据我的经验 我知道过滤数据视图非常慢 那么 LINQ 有多快呢 您能否告诉我您的经验以及它是否值得使用 或者我使用 SQL 存储过程
  • 从 YouTube 链接捕获特定时间范围内的缩略图

    1 有没有一种API方法可以捕获 存储YouTube视频在3 59处的缩略图 该缩略图不是自动生成的缩略图或原始上传者上传的封面缩略图 似乎没有任何确定的答案SO 2 如果 1 不可能 那么我下载原始视频 在所需时间范围内抓取缩略图并在我的
  • 如何忽略合并冲突?

    我有下一个合并冲突 lt lt lt lt lt lt lt Updated upstream my c name shift shift my name defined name name gt name merged common an
  • 块注释开头的感叹号的作用是什么? (那是, ”/*! … */”)

    我刚刚在一些 xcode 示例项目中发现了这个注释声明 property masterVolume abstract Sets the master volume property float masterVolume 注释像往常一样是绿色
  • 轴刻度标记

    我的折线图的 x 轴代表金钱 有没有办法在每个刻度的开头附加一个 符号 目前它们的值只有 2000000 250000 300000 我希望他们显示 2000000 250000 300000 我尝试将 添加到我的 CSV 文件中 但当我尝
  • 使用 ng-transclude 似乎在表格中效果不佳

    我创建了一个简单的指令 用于在 td 当没有表数据时 即 未找到结果 会占用表的整行 在我只有静态文本之前 td 但现在我希望能够将任何 DOM 放入其中 我尝试添加ng transclude按照我的指令 但现在它以一种奇怪的方式渲染元素
  • 如何在Android中使用Web视图访问本地主机服务器

    我有一个 Android 应用程序 我需要访问我的网络服务器并将我的 Android 应用程序连接到网络上的另一个程序 我的网络程序正在工作 当我将其 IP 地址放在 Android FIrefox 或浏览器上时 它正在工作 但是当我用我的
  • 如何在 Angular 2 中解释 MVC 模式?

    找到了一个有用的博客Angular MVC 实现但仍在寻找好的解释角2 General 我认为该模式确实与语言无关 也就是说 设计 架构模式是相当抽象的 并且用不同的语言实现它们遵循这种更抽象的表示 这并不是说我们不能通过示例语言 例如 C
  • 获取 PostgreSQL 中某个范围内的日期列表

    我想获取两个日期 包括它们 之间的天数列表PostgreSQL数据库 例如 如果我有 开始日期 2012年6月29日 结束日期 2012年7月3日 那么结果应该是 29 june 2012 30 june 2012 1 july 2012
  • 初始化大型 std::array 时编译器挂起

    我需要初始化一个非常大的多维std array数据的 class Thing class World public World space nullptr World default private static unsigned int
  • ASP.NET MVC 4 异步控制器回调

    我只是使用 MVC 4 中新的异步控制器功能 如此处所述http www asp net mvc tutorials mvc 4 using asynchronous methods in aspnet mvc 4 如果我有一个可能需要 1
  • Leaflet - 获取覆盖全屏的地图

    在传单和地图框中 我想去掉地图上方和下方的两个灰色条 如下图所示 我的 map DOM 元素占据全屏 并且当我放大时灰色条消失 例如 zoomLevel 3 因此 灰色条似乎是由于 ZoomLevel 具有给定的图块高度 以 px 为单位
  • 获取给定 ID 的最新行

    在下表中 我如何获得最近一行 with id 1基于signin列 而不是全部 3 行 id signin signout 1 2011 12 12 09 27 24 NULL 1 2011 12 13 09 27 31 NULL 1 20
  • 如何在 Xcode 11 中启动没有 Storyboard >= iOS 13 的新项目?

    现在 带有 iOS 13 的 Xcode 11 启动时的设置与之前略有不同 将 AppDelegate m 文件中的许多功能移动到名为 SceneDelegate m 的新文件中 删除 Main storyboard 并在 AppDeleg
  • WPF DataGrid ComboBox 导致 InvalidOperationException

    当我尝试编辑组合框列的值时 我从数据网格中收到 InvalidOperationException AddNew 或 EditItem 事务期间不允许 DeferRefresh 我显示的所有项目都引用了同一列表中的另一个项目 因此这就是我使
  • 将 NumPy 字符串数组转换为日期时间

    例如 我有一个字符串数组 import numpy as np foo np array b 2014 04 05 b 2014 04 06 b 2014 04 07 为了检查数组的数据类型 我用以下命令打印它 print foo dtyp
  • 为什么 InnoDB 中的 IX 锁与另一个 IX 锁兼容?

    根据innodb锁模式 锁类型兼容性矩阵 X IX S IS X Conflict Conflict Conflict Conflict IX Conflict Compatible Conflict Compatible S Confli