草庐IT

mysql - 插入导致 InnoDB 中出现死锁。这怎么发生的?

coder 2023-10-23 原文

我的问题是:为什么事务1持有主锁,为什么事务2需要主锁?我在 mysql 手册中找不到有关此锁的任何信息。

关于这个死锁的信息:

事务 1:

1988266681 Query        BEGIN
1988266681 Query        INSERT IGNORE INTO `tab1`
                            (`sn`, `is_fetch`, `is_done`, `add_time`)
                            VALUES ('4287', 0, 0, 1403186277)
1988266681 Query        COMMIT

交易 2:

1988212988 Query        BEGIN
1988212988 Query        SELECT sn FROM tab1 WHERE is_fetch = 0
                            LIMIT 200 FOR UPDATE
1988212988 Query        UPDATE `tab1` SET `is_fetch` = 1
                            WHERE sn in ('4287', '4387', '4487', '4587', '4687',
                            '4787', '4887', '4987')
1988212988 Query        COMMIT

架构信息:

CREATE TABLE `tab1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sn` varchar(20) NOT NULL,
`is_fetch` tinyint(1) NOT NULL DEFAULT '0' ,
`is_done` tinyint(1) NOT NULL DEFAULT '0' ,
`add_time` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `sn` (`sn`),
KEY `is_fetch` (`is_fetch`),
KEY `is_done` (`is_done`)
) ENGINE=InnoDB AUTO_INCREMENT=4387619 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

死锁信息:

------------------------
LATEST DETECTED DEADLOCK
------------------------
140617 23:25:36
*** (1) TRANSACTION:
TRANSACTION 36E4099DA, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 1937033606, OS thread handle 0x2ae3b0040700, query id 18031163883 192.168.1.65 db1 update
INSERT IGNORE INTO `tab1` (`sn`, `is_fetch`, `is_done`, `add_time`) VALUES ('1887', 0, 0, 1403018736)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 625 page no 5 n bits 1616 index `is_fetch` of table `db1`.`tab1` trx id 36E4099DA lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 1476 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc  ;;
1: len 4; hex 80410669; asc  A i;;

*** (2) TRANSACTION:
TRANSACTION 36E4099D7, ACTIVE 0 sec fetching rows, thread declared inside InnoDB 458
mysql tables in use 1, locked 1
6 lock struct(s), heap size 3112, 51 row lock(s), undo log entries 7
MySQL thread id 1937007092, OS thread handle 0x2ae8b5a26700, query id 18031163880 192.168.1.130 db1 Updating
UPDATE `tab1` SET `is_fetch` = 1 WHERE sn in ('1187', '1287', '1387', '1487', '1587', '1687', '1787')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 625 page no 5 n bits 1616 index `is_fetch` of table `db1`.`tab1` trx id 36E4099D7 lock_mode X locks gap before rec
Record lock, heap no 1476 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 81; asc  ;;
1: len 4; hex 80410669; asc  A i;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 625 page no 3 n bits 440 index `PRIMARY` of table `db1`.`tab1` trx id 36E4099D7 lock_mode X waiting
Record lock, heap no 168 PHYSICAL RECORD: n_fields 7; compact format; info bits 0
0: len 4; hex 80411598; asc  A  ;;
1: len 6; hex 00036e4099da; asc   n@  ;;
2: len 7; hex e80000c0060110; asc        ;;
3: len 14; hex 3134303631373338343331383837; asc 1887;;
4: len 1; hex 80; asc  ;;
5: len 1; hex 80; asc  ;;
6: len 4; hex d3a05df0; asc   ] ;;

最佳答案

问:这是怎么发生的?

事务2获得了对'is_fetch`索引中记录的独占锁,并试图获得对表主键中记录的锁。

事务1获取了表PRIMARY key中记录的独占锁,并试图获取is_fetch索引中记录的锁。

InnoDB 自动检测到两个事务都无法继续,因为每个事务都持有另一个所需的资源。 InnoDB 终止其中一个事务,以便另一个事务可以继续。

请注意,INSERT 语句可以获得唯一索引中记录的“间隙”锁。导致死锁的不仅仅是 INSERT,它是并发运行的事务的组合。

InnoDB 记录锁定记录在 MySQL 引用手册中:

http://dev.mysql.com/doc/refman/5.5/en/innodb-record-level-locks.html

关于mysql - 插入导致 InnoDB 中出现死锁。这怎么发生的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24327317/

有关mysql - 插入导致 InnoDB 中出现死锁。这怎么发生的?的更多相关文章

  1. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

  2. ruby - 怎么来的(a_method || :other) returns :other only when assigning to a var called a_method? - 2

    给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R

  3. ruby-on-rails - 我该怎么办 :remote location validation with CarrierWave? - 2

    我在我的Rails3示例应用程序上使用CarrierWave。我想验证远程位置上传,因此当用户提交无效URL(空白或非图像)时,我不会收到标准错误异常:CarrierWave::DownloadErrorinImageController#createtryingtodownloadafilewhichisnotservedoverHTTP这是我的模型:classPaintingtrue,:length=>{:minimum=>5,:maximum=>100}validates:image,:presence=>trueend这是我的Controller:classPaintingsC

  4. ruby-on-rails - 启用 Rack::Deflater 时 ETag 发生变化 - 2

    在启用Rack::Deflater来gzip我的响应主体时偶然发现了一些奇怪的东西。也许我遗漏了一些东西,但启用此功能后,响应被压缩,但是资源的ETag在每个请求上都会发生变化。这会强制应用程序每次都响应,而不是发送304。这在没有启用Rack::Deflater的情况下有效,我已经验证页面源没有改变。我正在运行一个使用thin作为Web服务器的Rails应用程序。Gemfile.lockhttps://gist.github.com/2510816有没有什么方法可以让我从Rack中间件获得更多的输出,这样我就可以看到发生了什么?提前致谢。 最佳答案

  5. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. ruby - 使用 rbenv 和 ruby​​-build 构建 ruby​​ 失败,出现 undefined symbol : SSLv2_method - 2

    我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby​​2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby​​-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm

  8. ruby - 当 attr_accessor 在类方法中时会发生什么? - 2

    所以我想到了这个,想知道当下面的一些事情完成后会发生什么。classTestdefself.abcattr_accessor:Johnendendobject=Test.newputs"beforecallingclassmethodabc:#{object.class.instance_methods(false)}"Test.abcputs"aftercallingclassmethodabc:#{object.class.instance_methods(false)}"这里我检查的是,getter和setter方法是否以这种方式创建。如果是这样,是那些实例方法或类方法。首先我创

  9. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

  10. ruby - EventMachine - 你怎么知道你是否落后了? - 2

    我正在研究使用EventMachine支持的twitter-streamruby​​gem来跟踪和捕获推文。我对整个事件编程有点陌生。我如何判断我在事件循环中所做的任何处理是否导致我落后?有没有简单的检查方法? 最佳答案 您可以通过使用周期性计时器并打印出耗时来确定延迟。如果您使用的是1秒的计时器,您应该已经过了大约1秒,如果它更长,您就知道您正在减慢react器的速度。@last=Time.now.to_fEM.add_periodic_timer(1)doputs"LATENCY:#{Time.now.to_f-@last}"@

随机推荐