一个死锁的case

联想服务器ThinkSystemRAID阵列设置教程 关注我不迷路,全是干货! 以联想ThinkSystemSR530为例子进行示范。 开机点按【F1】 点击——【UEFI设置】 依次点击——【系统设置】——【存储】 点击——【RAID卡】 PS:本次服务器配置的是730-8i 阵列卡,按实际情况选中需要设置的阵列卡即可。 点击——【Main Menu】 点击——【Configuration Management】 点击——【Create Virtual Drive】 点击——【Select RAID Leve.. 阅读详情

问题描述

今天线上流水的consumer出现了一个insert导致的死锁问题,这里通过一个DEMO复现一下case的整个过程,并进行详细的分析。

表结构如下:

mysql> show create table test_table;
| Table      | Create Table                                                                                
| test_table | CREATE TABLE `test_table` (
  `id` int NOT NULL AUTO_INCREMENT,
  `a` int NOT NULL,
  `b` int DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `test_table_a_uindex` (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |

1 row in set (0.00 sec)
复制代码

表数据:

mysql> select * from test_table;
+----+----+------+
| id | a  | b    |
+----+----+------+
|  1 |  1 |    1 |
| 20 | 20 |   20 |
| 50 | 50 |   50 |
+----+----+------+
3 rows in set (0.02 sec)
复制代码

事务中的代码是先update,如果记录不存在再去insert。

事务1:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update test_table set b = 1 where a = 30;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
复制代码

事务1开启事务,并update一条不存在的记录(此时会对a,[20,50]加间隙锁)。

事务2:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update test_table set b = 1 where a = 31;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
复制代码

事务2开启事务,并update一条不存在的记录(此时同样会对a,[20,50加间隙锁])。

事务1:

mysql> insert into test_table values(30,30,1);
mysql> waiting...
复制代码

事务1插入一条记录,此时会被阻塞...

事务2:

ysql> insert into test_table values(31,31,1);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
复制代码

事务2同样插入一条记录,此时会报错,死锁,并回滚事务。

事务1:

mysql> insert into test_table values(30,30,1);
Query OK, 1 row affected (12.58 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)
复制代码

事务2回滚后,事务1插入成功,事务提交成功。

问题分析

1.事务1、事务2中分别进行了一次update操作,并且操作的记录都不存在,此时,事务1、2分别会对a,[20,50]范围加一个间隙锁。

注:间隙锁与间隙锁之间可以兼容(共享锁)

2.事务1中进行了一次insert操作,此时由于事务2对a,[20,50]范围加了一个间隙锁,所以事务1的insert操作处于阻塞状态。

3.事务2中也进行了一次insert操作,同样被事务1的间隙锁阻塞。此时事务1在等事务2释放间隙锁,而事务2也在等事务1释放间隙锁,构成死锁,所以事务2报错“死锁”并进行事务回滚。

4.事务2回滚后,事务2的间隙锁被释放,事务1的insert操作执行成功,事务1提交成功。

解决方案

考虑了两种解决方案:

方案一

将事务中的插入操作提到事务之前执行,每次事务开始前先select一下,如果记录不存在插入一条空记录进去,在事务中只需要执行update操作。

缺点:多进行了一次select操作,可能对接口性能造成影响,需要重新进行压测判断。

方案二

降低mysql事务隔离级别,从RR下调到RC。

缺点:存在幻读问题

综合考虑,由于这个集群只用于流水和统计数据的存储,所以采用了 方案二:调低事务隔离级别。

知识扩展

InnoDB中RR隔离级别是否存在幻读问题?

回答这个问题前,我先假设你知道数据库隔离级别的定义针对的都是“当前读”。

首先我们来看一段InnoDB官方文档的话:

For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition. For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key locks to block insertions by other sessions into the gaps covered by the range.

大致意思就是,在 RR 级别下,如果查询条件能使用上唯一索引,或者是一个唯一的查询条件,那么仅加行锁,如果是一个范围查询,那么就会给这个范围加上 gap 锁或者 next-key锁 (行锁+gap锁)。

InnoDB 的 RR 隔离界别对范围会加上 GAP,不会存在幻读。

小结

  • 事务最好不要太长,否则容易出现锁等待、死锁等问题
  • insert操作最好不要放到事务里,否则容易引发死锁问题(相互等待)。

Transformer实战(39)——多模态生成式Transformer 能够理解多种类型输入的模型被称为多模态模型。多模态学习是人工智能 (Artificial Intelligence, AI) 领域的重要研究方向之一,长期受到众多研究人员的关注。本节将介绍使用多模态模型的生成式 AI,包括文本到图像 (text-to-image) 和文本到音乐 (text-to-music) 的生成模型。将介绍 Stable Diffusion 及其工作原理,同时也将介绍 MusicGen 和 AudioGen 模型。 阅读详情

相关推荐

UE4初学笔记_02_编辑器界面

不同版本可能不一样,这里是4.25 UE4编辑器主界面(也称为关卡编辑器)主要用于构建世界场景和关卡以及放置资源。 1.菜单栏 2.关卡编辑器(Level Editor)工具栏 3.“模式”(Modes)面板 4.“内容浏览器”(Content Browser)面板 5.“视口”(Viewport)面板 6.“世界大纲视图”(World Outliner)面板 7.“细节”(Details)面板 1.菜单栏 菜单栏包含“文件”(File) 、“编辑”(Edit) 、“窗口”(Win.

来自火星的猫 3092

sqlserver 在高并发的select,update,insert的时候出现死锁的解决办法

最近在使用过程中使用SqlServer的时候发现在高并发情况下,频繁更新和频繁查询引发死锁。通常我们知道如果两个事务同时对一个表进行插入或修改数据,会发生在请求对表的X锁时,已经被对方持有了。由于得不到锁,后面的Commit无法执行,这样双方开始死锁。但是select语句和update语句同时执行,怎么会发生死锁呢?看完下面的分析,你会明白的… 首先看到代码中使用的查询的方法Select [csh...

weixin_43490683的博客 9925

agv调度系统3.0技术介绍

agv调度系统,穿梭车调度系统,调度系统技术介绍,教你做调度

持续分享调度系统开发过程 4869

mysql case when 优化_SQL 逻辑优化 case when 转为 union all

通常数据库的优化从硬件层面去考虑可分为4个方面:CPU:即降低计算复杂度,如减少sql各类聚合函数,窗口函数,case when等。IO :(较少查询结果集过程中对数据的访问量。数据优化很大程度从这里入手网络 : 较少查询结果集的大小,去除不必要的查询字段数据库资源 : 这里讲的数据库资源主要是数据的一些参数设置,如索引、数据缓存。锁的争用,死锁,锁等。锁问题大部分从业务逻辑上去优化。如拆分事...

weixin_30420175的博客 1672

MATLAB MinGW-w64 C/C++ 编译器 手动安装配置

根据Matlab版本与MinGW版本对应关系,手动安装、配置并测试MinGW

zjh2883的博客 7342

实例讲解Simulink应用层开发CAN报文解包及CAN信号设置方法

本文通过讲解MCU CAN解包模块的模块设置、输入输出信号的设置及仿真测试验证,说明了CAN解包模块的设置方法、CAN解包模块输入输出信号的设置方法以及CAN解包模块的仿真测试及修正方法。在模型搭建过程中,建议养成一种搭建完成仿真测试验证的习惯,在模块阶段发现错误,解决错误,避免在后期模块集成之后报出大量错误,增加解决错误的工作量和难度。希望通过本文的介绍能给相关技术人员带来一些参考和帮助。

qq_43011586的博客 5681

update 语句会发生死锁?

90% 的程序员都认为 innodb 是行级锁,但实际上使用不当,它也是表级锁! 看过我博客的网友都知道,我之前写过一篇文章《 InnoDB 的 select 行锁还是表锁?》。拯救过不少人,今天我们再来一次大拯救! 最近生产上的 MySQL 数据库,是不是的就来一次 DeadLock,其中我做了故障排查,昨天做了相关的升级,导致昨天非常的忙,很多网友加我好友,都没有及时回应,直到晚上升级结束,我在群里做了相关的解释! 截了一段错误日志信息如下: 其中涉及到的更新语句如下: 很奇妙吧,执行一条 update

huaishuming的专栏 2864

1553B总线介绍及其硬件方案设计

军用1553B总线 1.简介 简单介绍可参考(https://blog.youkuaiyun.com/ScilogyHunter/article/details/108444231)博主写的很详细。 1553B总线是MIL-STD-1553总线的简称,其中B就是BUS,MIL-STD-1553B总线是飞机内部时分制命令/响应式多路复用数据总线。1553B数据总线标准是20世纪70年代由美国公布的一种串行多路数据总线标准。1553B总线能挂31个远置终端,1553B总线采用指令/响应型通信协议,它有三种终端类型: BC:

小幽余生不加糖 1万+

关于CASE WHEN造成的查询缓慢的生产问题思考

因为做的是类似SAAS的系统,关于同一个业务没会有不同的视角,有管理员,有类别分类的,有特别逻辑处理的。总而言之涉及到很多方面,再加上历史遗留问题导致导致的数据问题,这SQL写起来真的酸爽。 除了简单的关联,还要考虑到一个效率问题,最近就因为CASE WHEN导致了一个线上查询缓慢,差一点就要超过客户端设置的超时请求设置的一个问题。 问题详情: 现在有一个检查盘点资产的要求,之前只是要求在数据库有拿过资产的员工去发检查清单, 检查单表 check 检查详情(针对涉及到的资产每一个生成对应数据)check_d

FeiChangWuRao的博客 7618

基于Solidworks的三维光路结构示意图绘制实例演示-技术细节

基于Solidworks的三维光路结构示意图绘制实例演示-技术细节

简单光学 1万+

第八届传智杯WPS智能办公能力挑战赛练习题库

本文是关于WPS Office软件操作知识的选择题汇总,内容涵盖WPS文字、表格和演示三大组件的常用功能。主要包括:云文档协同编辑、文本框插入、幻灯片打印设置、数据排序与筛选、函数应用(如SUMIF、COUNT)、动画效果设置、格式刷使用、页眉页脚设置、单元格引用类型等基础操作要点。同时涉及计算机基础概念如二进制、ROM存储器等。题目以单选和多选形式呈现,附带详细答案解析,全面检验用户对WPS办公软件的功能掌握程度和实际操作能力,适用于办公软件技能培训和水平测试。

qq_73044452的博客 1432

Go select 竟然死锁了。。。

阅读本文大概需要 5 分钟。大家好,我是 polarisxu。前两天,火丁笔记发了一篇文章:《一个 select 死锁问题》[1],又是一个小细节。我将其中的问题改一下,更好理解:pack...

EDDYCJY的博客 698

魔改短线利器DPO指标,频繁交易也能盈利超30倍?手机同花顺可用!

昨天我们提示了一些高位风险板块,今天来看基本上都在跌幅前列。这一波由AIGC驱动的大行情,短期来看可能已经到了尾声。中期大家可以关注30日线和60日线是否有支撑,这种现象级的生产力变革主导的行情不可能直接就凉了——哪怕相关的企业距离从中获利还很遥远。在A股,当前是否盈利并不是当前股价的主要矛盾。保守的同学不妨关注下昨天的机会列表,里边全是一些超跌的板块,短期可能会延续弱势,但是一旦站上20日线,可能就会有一波超跌反弹的行情。AIGC中的资金外流,大概率会有一些低位板块得到临幸。

量化祛魅师 老Q。 1万+

GO语言-select语句

GO语-select语句

qq522044637的博客 904

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

go 多路复用

代码块中加入default后,因为case都没有准备就绪,因此会直接执行default下的代码块。我们在前面已经知道,除非有case执行,select语句就会一直阻塞着。等待信道中传递过来值,一旦其中一个信道接收到值就会运行case下的代码块。语句会一直阻塞,直到发送/接收操作准备就绪。如果有多个信道操作准备完毕,所以,多次运行,结果不会一模一样,如果是同时多个信道中接收到值,会。语句没有任何case,因此它会一直阻塞,导致死锁。类似,所不同的是,这里的每个。的信道,也同样会执行默认情况。...

go|Python的个人博客 776

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Go-Select

select 语句用于在多个发送/接收信道操作中进行选择。select 语句会一直阻塞,直到发送/接收操作准备就绪。如果有多个信道操作准备完毕,select 会随机地选取其中之一执行。该语法与 switch 类似,所不同的是,这里的每个 case 语句都是信道操作。 没有 case 准备就绪时,可以执行 select 语句中的默认情况(Default Case)。

huyuchaoheaven的专栏 190

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Go-select用法

简述select组成和编写、分支选择、与for语句连用

weixin_42430947的博客 337

二. go 常见控制结构实现原理之 select

对于空的select语句,程序会被阻塞,准确的说是当前协程被阻塞,同时Golang自带死锁检测机制,当发现当前协程再也没有机会被唤醒时,则会panic。所以上述程序会panic。

qq_29799655的博客 461

Golang中的channel详解(二):channel与select

select是Golang中的一个关键字,用来监听channel相关的IO操作,当IO操作发生时,触发相应的动作。

路多辛的所思所想 799

MySQL死锁case分析

死锁发现 2018-01-18 14:10:03 线上环境批量更新库存的地方出现了死锁 2018-01-25 16:50:03 线上环境批量更新库存的地方出现了死锁 org.springframework.dao.DeadlockLoserDataAccessException: PreparedStatementCallback; SQL [UPDATE goods_inventor

七夜 2964

记一次线上MySQL死锁case

existsAuditingRecordInLock的实现可以看到,使用了共享锁查询audit_process_record的行数,线上MySQL的事务级别使用RR,使用共享锁的目的,应该是希望避免快照读,而是使用当前读,并发场景下,可以查询到其他线程的最新数据,但问题也恰恰出在这里。线程A先获得记录1的排他锁,然后要获取所有记录(包括记录2)的共享锁。线程B先获得记录2的排他锁,然后要获取所有记录(包括记录1)的共享锁。使用其他的分布式锁,例如Redis或者ZK,代替MySQL的锁操作。

wtopps的专栏 467

mysql unique 锁_MySQL唯一键死锁总结分析

[TOC]1、没有锁CASE# 8.0.18# RCCREATE TABLE `t3` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(10) COLLATE utf8mb4_bin DEFAULT NULL,`age` int(11) NOT NULL DEFAULT '1',PRIMARY KEY (`id`)) ENGINE=Inno...

weixin_34281191的博客 717

PostgreSQL死锁表查询及杀死死锁进程命令

一、PostgreSQL中查询死锁的表 WITH t_wait AS ( SELECT a.mode,a.locktype,a.databASe,a.relation,a.page,a.tuple,a.clASsid,a.granted, a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fAStpath, b.state,b.query,b.xact_start,b.query_start,b.usen

qq_42674918的博客 2612

mysql 唯一索引 死锁_MySQL唯一键死锁总结分析

1、没有锁CASE# 8.0.18# RCCREATE TABLE `t3` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(10) COLLATE utf8mb4_bin DEFAULT NULL,`age` int(11) NOT NULL DEFAULT '1',PRIMARY KEY (`id`)) ENGINE=InnoDB2、唯...

weixin_33238848的博客 1911

FZU 1924 Problem 1924 死锁

题目来源: https://vjudge.net/contest/292206#problem/E http://acm.fzu.edu.cn/problem.php?pid=1924 Problem Description 在操作系统中存在着死锁问题。 进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,...

nuoyanli的博客 3728

一个线上SQL死锁异常分析:深入了解事务和锁

一 背景 最近线上消费MetaQ的服务频繁报SQL死锁异常,虽然最终可以基于事务自动回滚和逻辑重试保证最终正确性,但若一直放任不管,海量报警日志会掩盖真正需要紧急处理的异常,同时频繁回滚也会降低消费端的吞吐量。个人通过分析线上服务日志、MySQL死锁日志、梳理MySQL在RR级别下的锁机制,找到了真正的问题所在,并对业务处理逻辑进行了优化,特在此整理出来,互相学习提升,如果文中有错误的地方欢迎指正。 二 知识储备 正所谓“工欲善其事,必先利其器”,在具体介绍CASE背景和解决方案前,先对需要系统了..

怀素的专栏 507
上一篇: 快速无副作用搭建Java 17环境并玩转Record特性
下一篇: 用亿点时间重学部分Java基础
在酒吧写代码
博客等级 码龄7年 210粉丝 330原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值