innodb不同场景下加锁分析总结

Mysql加锁分析 最近逛社区发现精华贴,转过来共同学习!   1    背景    1 1.1    MVCC:Snapshot Read vs Current Read    2 1.2    C... 阅读详情

Read-Uncommitted/Read-Committed隔离级别上锁过程

查询条件

SQL示例

加锁分析

查询条件为主键等值

SELECT … WHERE PK = XX FOR UPDATE;

1:如果有对应记录则对记录加LOCK_X|LOCK_REC_NOT_GAP锁

2:如果没有则不加锁,以下场景都相同处理

UPDATE … WHERE PK = XX;

1:如果未更新其他索引列。

只需要在主键记录上加X锁即可,加锁为LOCK_X|LOCK_REC_NOT_GAP。

2:更新包括其他索引列。

除了主键记录加X锁,还需要在涉及索引上加LOCK_X|LOCK_REC_NOT_GAP锁。

DELETE … WHERE PK = XX;

对主键、各个索引对应的记录都要加X锁,LOCK_X|LOCK_REC_NOT_GAP。

查询条件为主键范围

select * from t where c1 >= 20 for update;

会对所有满足条件的记录加锁,如果没有则不加锁

update t set c2 = c2 + 1 where c1 >= 20;

会依次对c1 >=20的主键记录行加X锁,对应的索引行做加X锁操作。

查询条件为唯一索引等值

SELECT … WHERE UK = XX FOR UPDATE;

需要在索引记录上加X锁:LOCK_X|LOCK_REC_NOT_GAP,同时还要在对应主键行上加X锁。

UPDATE … WHERE UK = XX;

1:未更新其他索引列

对唯一索引上数据加X锁(LOCK_X|LOCK_REC_NOT_GAP),然后对应的主键行也需要加X锁。

2:更新其他索引列

依次对唯一索引数据、主键行、索引数据加X锁。

DELETE … WHERE UK = XX;

会对唯一索引数据加X锁,根据唯一索引找到主键行后,会再依次对主键行、唯一索引、索引数据加X锁。

查询条件为唯一索引范围

SELECT … WHERE UK >= XX FOR UPDATE;

1: 如果是通过主键,则对主键行依次加X锁, 同时在加锁后,分析发现不满足条件会立即释放该行上的X锁。

2:如果是通过唯一索引,则依次对满足条件的唯一索引、主键记录加X锁。

UPDATE … WHERE UK <= XX FOR UPDATE;

会对唯一索引和对应主键行依次加X锁,然后判断不满足range条件,释放唯一索引和对应主键行上的X锁。

查询条件为非唯一索引

SELECT … WHERE IDX = XX FOR UPDATE;

非唯一索引情况与唯一索引情况加锁情况一致

查询条件上无索引

SELECT … WHERE COL = XX FOR UPDATE;

路径选择主键,会依次对主键行加锁,分析条件,不满足条件释放锁,满足条件持有锁。

多条件查询

select * from t where c2 = xx and c3 = xx for update;

当存在多个条件的时候,除了主键行上的锁,其他的加锁情况取决于选择的路径。

选择了走唯一索引,就会对满足条件的唯一索引行加X锁,然后对主键行加X锁。

主键路径,就会对所有行一次加X锁,分析条件,最终持有主键上c1 = 20的X锁。

Repeatable Read隔离级别上锁过程 

查询条件

SQL示例

加锁分析

查询条件为主键等值

SELECT … WHERE PK = XX FOR UPDATE;

1:如果有对应记录则对记录加LOCK_X|LOCK_REC_NOT_GAP锁

2:如果没有则会对后面的记录加GAP锁,(LOCK_X|LOCK_GAP),防止有其他语句插入pk=xx的行。

UPDATE … WHERE PK = XX;

1:如果未更新其他索引列。

只需要在主键记录上加X锁即可,加锁为LOCK_X|LOCK_REC_NOT_GAP。

2:更新包括其他索引列。

除了主键记录加X锁,还需要在涉及索引上加LOCK_X|LOCK_REC_NOT_GAP锁。

3:没有满足条件的记录则不加锁

DELETE … WHERE PK = XX;

1:如果有满足条件的记录对主键、各个索引对应的记录都要加X锁,LOCK_X|LOCK_REC_NOT_GAP。

2:没有则不加锁

查询条件为主键范围

select * from t where c1 >= 20 for update;

这里会对c1=20加X锁(LOCK_X|LOCK_REC_NOT_GAP),对c1>20对应的行加exclusive next-key lock(LOCK_X|LOCK_ORDINARY),同时会对表示记录上界的’supremum’加exclusive next-key lock。以阻塞其他事务对c1>=20的插入。

select * from t where c1 <= 20 for update;

这里会依次对c1<=20的主键记录加exclusive next-key lock(LOCK_X|LOCK_ORDINARY)锁。且在判断c1=30不符合查询条件后,虽然server层调用unlock_row,但对于RC隔离级别以上且没有设置innodb_locks_unsafe_for_binlog那么并不会释放锁。

update t set c2 = c2 + 1 where c1 >= 20;

1:未更新其他索引列。

加锁与上面SELECT… WHERE PK >= XX FOR UPDATE;一致。

2:更新包含索引列。

对主键c1=20加X锁,索引行加X锁,然后对后面的主键行加exclusive next-key lock(LOCK_X|LOCK_ORDINARY),同时对应的i_c2索引行加X锁,最后对表示记录上界的’supremum’加exclusive next-key lock。

UPDATE … WHERE PK <= 20;

1:未更新其他索引列。

加锁与SELECT… WHERE PK <= XX FOR UPDATE;一致

2:包含索引列。

对pk<=20的主键满足条件记录加exclusive next-key lock(LOCK_X|LOCK_ORDINARY),同时对应的索引行加X锁。然后对pk>20的第一条记录加exclusive next-key lock,因不满足条件,因此server层查询停止。同样并不会释放后面记录上的锁。

DELETE … WHERE PK >= 20;

会对pk=20加X锁,对pk=20对应的索引加X锁,然后依次对pk>20的主键记录加exclusive next-key lock(LOCK_X|LOCK_ORDINARY),同时对应的索引行加X锁,最后对’supremum’加LOCK_X|LOCK_ORDINARY。

查询条件为唯一索引等值

SELECT … WHERE UK = XX FOR UPDATE;

需要在索引记录上加X锁:LOCK_X|LOCK_REC_NOT_GAP,同时还要在对应主键行上加X锁。

UPDATE … WHERE UK = XX;

1:未更新其他索引列

对唯一索引上数据加X锁(LOCK_X|LOCK_REC_NOT_GAP),然后对应的主键行也需要加X锁。

2:更新其他索引列

依次对唯一索引数据、主键行、索引数据加X锁。

DELETE … WHERE UK = XX;

会对唯一索引数据加X锁,根据唯一索引找到主键行后,会再依次对主键行、唯一索引、索引数据加X锁。

查询条件为唯一索引范围

SELECT … WHERE UK >= XX FOR UPDATE;

1: 如果是通过主键,对满足条件的主键记录分别加exclusive next-key lock(LOCK_X|LOCK_ORDINARY),同时对上界’supremum’加exclusive next-key lock,锁住全部数据范围。

2:如果是通过唯一索引,那么会对满足条件的索引记录分别加exclusive next-key lock,对应主键行加X锁,同时对索引上的’supremum’ record加exclusive next-key lock。

SELECT … WHERE UN <= XX FOR UPDATE;

对索引上满足条件的记录加exclusive next-key lock,对对应的主键行加X锁,然后对大于xx的第一条记录加exclusive next-key lock,且并不会去释放。

UPDATE … WHERE UK >= XX;

1:未包含索引列。

等同上面指定走唯一索引的SELECT…FOR UPDATE语句加锁。

2: 包含索引列。除了之前提到的主键和唯一索引加锁之外,对应被涉及到的索引行也要加X锁。

UPDATE … WHERE UK <= XX FOR UPDATE;

1:未包含索引列。

会对索引上<xx的记录加exclusive next-key lock,对对应的主键行加X锁。因为没有ICP,这里>xx的第一条记录对应的索引行和主键行也会加X锁,同时不会释放。

2:包含索引列

会对索引上<xx的记录加exclusive next-key lock,对对应的主键行和索引加X锁。对>xx的第一条记录加exclusive next-key lock,对应主键行加X锁。

DELETE … WHERE UK >= XX;

走索引,会对>=xx的第一条记录加exclusive next-key lock,对应主键行加X锁,索引上数据行进行加X锁操作,对索引上’supremum’ record加exclusive next-key lock。

查询条件为非唯一索引等值

SELECT … WHERE IDX = XX FOR UPDATE;

会对=xx在索引上加exclusive next-key lock(LOCK_X|LOCK_ORDINARY),对应主键加X锁(LOCK_X|LOCK_REC_NOT_GAP),然后在下一条记录上加exclusive gap lock(LOCK_X|LOCK_GAP)。即该语句会锁定范围。

RR和RC隔离级别都要加的锁 

唯一二级索引(uk)更新或插入

UPDATE set uk=xxx… WHERE UK = XX;

insert into ...uk =xxx

如果UK原来存在,需要做去重判断,此时要对这个UK加S锁。比方说插入uk=1,表里已经有这个uk=1的记录,或者被删除还未被清理,需要先对uk=1这索引加S LOCK_ORDINARY锁再加X锁。更新UK,这等价于先删除再插入,一定有一条相同UK老记录,也需要先加S锁。

原因在于代码逻辑中 row_ins_scan_sec_index_for_duplicate 重复检查要加S LOCK_ORDINARY锁。

一个UK更新例子:


CREATE TABLE `t_test` (
  `a` bigint(20) NOT NULL COMMENT 'a',
  `b` varchar(32) NOT NULL COMMENT 'b',
  `c` varchar(32) DEFAULT NULL COMMENT 'c',
  `d` int(11) NOT NULL COMMENT 'd',
  `e` bigint(20) NOT NULL COMMENT 'e',
  PRIMARY KEY (`a`),
  UNIQUE KEY `uk_b_d` (`b`,`d`) USING BTREE,
  KEY `idx_b_e` (`b`,`e`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='test';

insert into t_test values(1,'1','1',1,1);
insert into t_test values(5,'5','5',5,5);
insert into t_test values(10,'10','10',10,10);
insert into t_test values(15,'15','15',15,15);
update t_test set a = 7, b = "5", c = "5",  d = 5, e = 7  where  b = "5" and d = 5;

锁情况:
TRANSACTIONS
======================
Trx id counter 1363
Purge done for trx's n:o < 1363 undo n:o < 0 state: running but idle
History list length 3
Total number of lock structs in row lock hash table 2
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421893635597552, not started
0 lock struct(s), heap size 1160, 0 row lock(s)
---TRANSACTION 421893635594896, not started
0 lock struct(s), heap size 1160, 0 row lock(s)
---TRANSACTION 1358, ACTIVE 6 sec
3 lock struct(s), heap size 1160, 2 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 140418654865152, query id 99 localhost 127.0.0.1 root
TABLE LOCK table `test`.`t_test` trx id 1358 lock mode IX
RECORD LOCKS space id 24 page no 4 n bits 72 index uk_b_d of table `test`.`t_test` trx id 1358 lock_mode X locks rec but not gap
RECORD LOCKS space id 24 page no 3 n bits 72 index PRIMARY of table `test`.`t_test` trx id 1358 lock_mode X locks rec but not gap
======================





AI智能体安全沙箱agentguard:为LLM代码执行筑起防火墙 在AI应用开发领域,大语言模型(LLM)驱动的智能体(Agent)能够自动生成并执行代码,极大地提升了自动化能力。然而,赋予AI直接执行系统命令的权限也带来了显著的安全风险,如恶意代码注入、敏感数据泄露和系统资源滥用。为了解决这一核心矛盾,安全沙箱技术应运而生,它通过在不可信代码与宿主系统之间建立隔离层,实现"默认拒绝、最小权限"的安全原则。agentguard项目正是这一理念的工程实践,它结合白名单机制与容器化隔离,为AI智能体提供了可配置、可审计的安全执行环境。该方案不仅适用于内部自动化工具开发,也为构 阅读详情

相关推荐

Unity类银河战士恶魔城学习总结(P103之前 Enemy相关 , 骷髅战士,状态机,敌人状态,)

udemy的Alex银河战士恶魔城,记录我自己的学习,代码会逐渐每一p更新,仅供参考学习。

suzh1qian的博客 1633

10个行锁、死锁案例⭐️24张加锁分析图彻底搞懂Innodb行锁加锁规则!

本篇文章通过大量案例、图例分析不同情况下的行锁加锁规则update、delete 先查再改,可以看成锁定读,insert则是有单独一套加锁规则锁定读加锁规则在RC及以下隔离级别,锁定读使用record锁;在RR及以上隔离级别,锁定读使用next key锁等值查询:如果找不到记录,该查询条件所在区间加GAP锁;如果找到记录,唯一索引临键锁退化为记录锁,非唯一索引需要扫描到第一条不满足条件的记录,最后临键锁退化为间隙锁(不在最后一条不满足条件的记录上加记录锁)

关注菜菜的后端私房菜,获取更多技术干货~ 2481

Agent框架系列:1-低代码智能体平台深度解析Dify、Coze、n8n

Dify、Coze 和 n8n 是三大主流低代码智能体平台,各有侧重。Dify 适合企业级 AI 应用,具备强大的 RAG 和知识库管理能力,技术栈为 Python + React。Coze 由字节推出,主打零代码和快速原型开发,集成 60+ 插件,极适合非技术用户。n8n 以工作流自动化和系统集成为核心,支持 400+ 外部应用,基于 Node.js + Vue,扩展性极强。选择建议:非技术团队选 Coze,AI 应用选 Dify,复杂自动化与集成选 n8n。可根据实际需求混合使用,最大化平台优势。

3090

Mysql(InnoDB)的SQL加锁分析

一、背景 工作经常遇到在编写并发场景sql时考虑欠缺,造成过一些bug和sql死锁。于是乎,笔者查阅了不少相关资料。 本文就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁场景,了解死锁产生的原因。 注:MySQL是一个支持插件式存储引擎的数据库系...

不能说的秘密的博客 1491

数据结构:五岔路口交通管理红绿灯设计

我们可以知道这是一个“图”的着色问题,首先要考虑,为什么可行路线是13条?当然可以通过穷举得出,如果用公式:则是: 或者 因为一条路线必须包括一出一进两个方向 第一种答案的解法: 一、固定E为入口,则有C_4^1=4的可能; 二、除去E(因为E只有一个入向),剩下ABCD四个路口,然后因为C只有一个出方向,所以从剩下 的ABD中选择一个入口,即C_3^1; 三、再从剩下的三个出口任选

潘猫猫的世界 1万+

保姆级教程:用R包ggpicrust2搞定PICRUSt2功能预测,从差异分析到热图PCA一键出图

本文提供了一份详细的ggpicrust2使用指南,帮助用户从零开始完成PICRUSt2功能预测数据的差异分析和可视化。通过安装配置、数据导入、差异分析到高级可视化(如热图和PCA)的全流程讲解,即使是初学者也能快速掌握发表级图表的生成技巧。

weixin_33712987的博客 386

MySQL 加锁处理分析

本文来自:何登成的技术博客   一、背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题。我在工作过程中,经常会有同事咨询这方面的问题。同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题。本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句...

baidu_33389767的博客 217

三、分区配置

rk3566/rk3568 修改分区

暮云星影的博客 514

MySQL的并发控制与加锁分析

MySQL的并发控制与加锁分析 本文主要是针对MySQL/InnoDB的并发控制和加锁技术做一个比较深入的剖析,并且对其中涉及到的重要的概念,如多版本并发控制(MVCC),脏读(dirty read),幻读(phantom read),四种隔离级别(isolation level)等作详细的阐述,并且基于一个简单的例子,对MySQL的加锁进行了一个详细的分析。本文的总结参考了何登成前辈的博客,并且...

weixin_42306440的博客 175

Goldwasser-Micali 公钥加密系统

1、二次剩余问题 对于整数n ,定义Zn∗={a∈Zn,gcd(a,n)=1}Z^*_n=\{ a∈Z_n,gcd(a,n) =1\}Zn∗​={a∈Zn​,gcd(a,n)=1} 。当存在d∈Znd \in Z_nd∈Zn​ ,使得 d2≡a mod nd^2 \equiv a \, mod \,nd2≡amodn ,称 a 为模 n 的二次剩余;否则称 a 为模 n的二次非剩余。判断 a 是否为模 n 的二次剩余的问题称为模n 的二次剩余问题。 \rule[-10pt]{14.3cm}{0.05em}

不染心的博客 4317

shader多图叠加变换

shader Shader "Paint3D/AddTexture" { Properties { _MainTex ("Main Texture", 2D) = "white" {} _MainColor("Main Color", Color)=(1,1,1,1) _AddTex0 ("Texture0", 2D) = "white" {} _AddTex1 ("Texture1", 2D) = "white" {} .

李长江的博客 909

mysql 联合主键 加锁_MySQL 加锁处理分析

背景MySQL/InnoDB的加锁分析,一直是一个比较困难的话题。我在工作过程中,经常会有同事咨询这方面的问题。同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题。本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁...

weixin_36271649的博客 661

Unity零基础到入门 ☀️| 近万字教程 对 Unity 中的 动画系统基础 全面解析+实战演练,你确定要错过吗?

Unity动画系统,Animation,Animator。 本文对Unity中的动画系统基础做了一个全面解析,还包括实战演练。近万字教程让你对Unity的动画系统有一个系统的了解,敬请品尝!

努力前行,总会成为自己心中的那道光 9万+

Mysql加锁过程详解

转载自:http://www.cnblogs.com/metoy/p/5545580.html 1、背景   MySQL/InnoDB的加锁分析,一直是一个比较困难的话题。我在工作过程中,经常会有同事咨询这方面的问题。同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题。本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一

天空之城 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

mysql加锁处理分析

1    背景    1 1.1    MVCC:Snapshot Read vs Current Read    2 1.2    Cluster Index:聚簇索引    3 1.3    2PL:Two-Phase Locking    3 1.4    Isolation Level    4 2    一条简单SQL的加锁实现分析    5 2.1    组合一:id主键+

hzllblzjily的专栏 822

mysql 加锁处理分析

转载http://blog.youkuaiyun.com/opensure/article/details/46227695 MySQL 加锁处理分析 标签:DatabaseDeadlockLockMySQL 2015-05-29 11:141101人阅读评论(0)收藏举报 分类: mysql(1) 目录(?)[+] 1...

dice0192的博客 104

【169期】面试官:同学,分析一下MySQL/InnoDB的加锁过程吧

程序员的成长之路互联网/程序员/技术/资料共享关注阅读本文大概需要 17 分钟。来自:cnblogs.com/crazylqy/p/7611069.htmlHello,大家好,我是良月柒...

良月柒 484

不在事务中能加锁吗_深入剖析 MySQL的并发控制与加锁分析(最全图文解析)

本文主要是针对MySQL/InnoDB的并发控制和加锁技术做一个比较深入的剖析,并且对其中涉及到的重要的概念,如多版本并发控制(MVCC),脏读(dirty read),幻读(phantom read),四种隔离级别(isolation level)等作详细的阐述,并且基于一个简单的例子,对MySQL的加锁进行了一个详细的分析。本文的总结参考了何登成前辈的博客,并且在前辈总结的基础上,进行了一些基...

weixin_39963830的博客 204

mysql 加锁 索引_MySQL 加锁处理分析

一、背景MySQL/InnoDB的加锁分析,一直是一个比较困难的话题。我在工作过程中,经常会有同事咨询这方面的问题。同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题。本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个...

weixin_30043767的博客 351

linux mysql 释放x锁_MySQL 加锁处理分析-转载

背景MySQL/InnoDB的加锁分析,一直是一个比较困难的话题。我在工作过程中,经常会有同事咨询这方面的问题。同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题。本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁...

weixin_39959569的博客 161

MySQL的并发控制与加锁分析(MVCC/LBCC)

原文:https://www.cnblogs.com/yelbosh/p/5813865.html本文主要是针对MySQL/InnoDB的并发控制和加锁技术做一个比较深入的剖析,并且对其中涉及到的重要的概念,如多版本并发控制(MVCC),脏读(dirty read),幻读(phantom read),四种隔离级别(isolation level)等作详细的阐述,并且基于一个简单的例子,对MySQL...

W.J.H. 5341

MySQL InnoDB加锁规则分析

1. 基础知识回顾1、索引的有序性,索引本身就是有序的2、InnoDB中间隙锁的唯一目的是防止其他事务插入间隙。间隙锁可以共存。一个事务取得的间隙锁并不会阻止另一个事务取得同一间隙上的间隙锁。共享和独占间隔锁之间没有区别。它们彼此之间不冲突,并且执行相同的功能。3、MySQL默认隔离级别是 REPEATABLE-READ4、加锁的对象是索引,加锁的基本单位是next-key锁,而行锁和间隙锁,是由next-key锁退化而来的5、记录锁,锁的是索引,而非数据本身。

weixin_62421895的博客 755
上一篇: MySQL 主从时间字段相差1秒深度揭密
下一篇: MySQL无cpu卡死故障深入分析
postgres20
博客等级 码龄10年 100粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值