首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MySQL 中的 INSERT 是怎么加锁的?

会出现这种情况?...于是我又去复习了一遍 MySQL 官方文档,Locks Set by Different SQL Statements in InnoDB 这篇文档对各个语句的加锁有详细的描述,其中对 insert加锁过程是这样说的...(这应该是网络上介绍 MySQL 加锁机制被引用最多的文档,估计也是被误解最多的文档): INSERT sets an exclusive lock on the inserted row....如果事务 A 插入记录且未提交,这时事务 B 尝试对这条记录加锁,事务 B 先去判断记录上保存的事务 id 是否活跃,如果活跃的话,那么就帮助事务 A 去建立一个锁对象,然后自身进入等待事务 A 状态...in share mode 就能查到 1 条记录,这岂不是还有幻读问题

10.4K51
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    INSERT...SELECT语句对查询的表加锁

    前言: insert into t2 select * from t1; 这条语句会对查询表 t1 加锁?不要轻易下结论。...加锁的目的是确保事务在读取数据时能够看到一个一致的数据快照。如果在执行 INSERT ... SELECT 时不加锁,那么可能会出现以下情况: 不可重复读:如果在 INSERT ......SELECT 执行期间,另一个事务修改了被查询的数据,那么 INSERT ... SELECT 可能读取到不同的数据,导致插入的数据不一致。...幻读:在某些情况下,另一个事务可能会在 INSERT ... SELECT 执行期间插入新的行,导致插入操作插入到不应该插入的行。 通过加锁,InnoDB 能够确保 INSERT ......结论: INSERT...SELECT语句是否对查询表加锁跟事务隔离级别有关,REPEATABLE-READ隔离级别下加共享读锁,此共享读锁属于Nextkey lock,影响其他事务对查询表的DML操作

    6910

    insert into select加锁规则补充

    insert into select加锁规则补充 昨天的文章中,针对insert into select语句的加锁情况进行了分析: insert into A select * from B; 形如这样的语句...row格式下的测试过程如下(下面分别是执行顺序和代码): 会话1: ----------------会话1--------------- mysql>>select * from table_log order...****************** id: 9999999 code: 9999999 time: 2020-06-04 12:57:42 2 rows in set (0.00 sec) mysql...into select返回结果前执行会话2中的update,发现update并没有阻塞 # -----------------会话2--------------- mysql>>update table_log...关于这个语句的加锁方法,可以参看percona官网的一篇博客和stackoverflow的一篇讨论,这里给出链接,有兴趣的同学可以继续研究: https://www.percona.com/blog/2006

    2K20

    insert语句的加锁情况分析

    // insert语句的加锁情况分析 // 今天分享的内容是MySQL里面insert语句的加锁情况,废话就不多说了,直接从线上的例子开始吧。...`table_log` trx id B1354DEF lock mode AUTO-INC waiting 为了解释这个现象,我们需要知道在MySQL中,对于insert into select这个语句是如何加锁的...01 insert into select的加锁情况 假如我们有一个表t,它有三个字段,id,c,d,其中id是主键,c是唯一索引,d是普通列,有4条记录: mysql> select * from...解释下我们的例子,也就是: 当对表table_log进行insert操作的时候,批量申请自增值,产生auto-inc的锁,由于MySQL不确定这个SQL插入多少数据,而且我们设置了innodb_autoinc_lock_mode...=1,所以这个锁是事务级别的,当满足select的where条件的值足够多的时候,其他事务要进行insert操作,产生table_log表上的auto inc锁等待。

    2.2K21

    面试题:INSERT...t...SELECT s会对s表加锁

    前言: insert into t2 select * from t1; 这条语句会对查询表 t1 加锁?不要轻易下结论。...加锁的目的是确保事务在读取数据时能够看到一个一致的数据快照。如果在执行 INSERT ... SELECT 时不加锁,那么可能会出现以下情况: 不可重复读:如果在 INSERT ......SELECT 执行期间,另一个事务修改了被查询的数据,那么 INSERT ... SELECT 可能读取到不同的数据,导致插入的数据不一致。...幻读:在某些情况下,另一个事务可能会在 INSERT ... SELECT 执行期间插入新的行,导致插入操作插入到不应该插入的行。 通过加锁,InnoDB 能够确保 INSERT ......结论: INSERT...SELECT语句是否对查询表加锁跟事务隔离级别有关,REPEATABLE-READ隔离级别下加共享读锁,此共享读锁属于Nextkey lock,影响其他事务对查询表的DML操作

    13110

    故障分析 | 从 Insert 并发死锁分析 Insert 加锁源码逻辑

    基于解决死锁问题存在的难点,本文以MySQL数据库一则并发Insert导致的死锁为例,从发现问题、重现问题、根因分析、解决问题4个步骤,期望能提供一套关于死锁的科学有效方案,供读者朋友参考。...至此,回答了最开始提出的问题Q1: Q1: T1为什么持有 ua中记录10 的锁?...Q7: 死锁发生后,由于MySQL死锁检测机制自动发现死锁,并会挑选事务进行回退。事务被回退了之后,就破坏了死锁的第一现场。...图片 2、最终死锁过程 以时间维度,结合以上的mysql加锁逻辑进行分析: A. T1、T2开启了一个事务,随后T1执行了插入(26,10)的insert语句 B....等待锁主要由于T2被堵塞后,创建锁(LOCK_S | LOCK_ORDINARY | LOCK_WAIT | LOCK_REC)。

    87111

    MySQL】说透锁机制(二)行锁 加锁规则 之 范围查询(你知道锁表?)

    前文回顾 在上文,我们介绍了 MySQL InnoDB行锁的: 2个模式:S锁和X锁 3种算法:Record Lock、Gap Lock、Next-key Lock 如何开启锁监视器 和 如何分辨3种锁...聚集索引 和 唯一索引: Record Lock 普通索引:Next-key Lock + Record Lock + Gap Lock 无匹配:全是Gap Lock 详细案例分析和总结,请见上文:行锁 加锁规则...你是不是怀疑我搞错了?...范围组合 说明:索引失效 锁表 的规则是通用的,所以这里就 统一 只演示 不锁表 的情况。...如果没走普通索引,那么就会把所有 聚集索引记录 和 间隙 都锁上,就是所谓的锁表,或叫行锁升表锁. ---- 总结 这里需要补充说明的是:因为对于范围查询,都会有个边界,所以如果没有任何匹配,就会只对边界加锁

    1.9K32

    insert唯一键冲突的加锁情况分析

    // insert唯一键冲突的加锁情况分析 // 今天分享的内容是MySQL里面insert语句在发生冲突的时候加锁情况,废话就不多说了,直接从例子开始吧。...首先创建表t,其中id为主键,c为唯一索引,然后插入5条数据, mysql> show create table t\G *************************** 1. row *****...UNIQUE KEY `c` (`c`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql...第二个insert操作因为重复的键值而报错,因为c=10的记录已经有了,按理说发生唯一键冲突之后,这条语句失败了,应该不对MySQL有影响才对,实际上,这个insert语句做了两件事情: 1、报唯一键冲突错误...thread id 5, OS thread handle 3124, query id 28 localhost ::1 root update insert into t values (12,9,9

    2.5K30

    MySQL加锁范围分析

    场景: 最近,遇到了一个关于mysql 加锁的问题,将当时的情形简化如下,有一个index_test表,表结构如下所示: mysql> CREATE TABLE `index_test` ( `priv_id...可重复读(Repeatable reads):产生幻读 授权读(Read committed):会出现“不可重复读” 未授权读(Read uncommitted):产生脏读 不同的DBMS默认隔离级别也不同...然后在网上搜索相关的资料,看看别人有没有遇到过这样的问题,在一篇关于MySQL加锁处理分析的blog中得到了启示,按照blog中组合七:id非唯一索引+RR的理论,gap锁的范围不仅跟被锁定的键有关,还跟主键有关...因此,在我们使用mysql加锁过程中,也首先需要搞清楚,我们的隔离级别是什么,是否开启了binlog等等,然后才能正确分析加锁的范围。...p=771 大神描述Mysql 加锁分析的blog http://hedengcheng.com/?

    6.1K72

    mysql语句加锁分析

    其实并不能完全解决幻读问题, 这里可以参考另一篇博客[mysql事务隔离级别与加锁分析] SERIALIZABLE隔离级别下,需要分为两种情况讨论: 在系统变量autocommit=0时,也就是禁用自动提交时...[](/images/mysql/ru_rc_table_scan.png) 2. `SELECT ... FOR UPDATE`进行加锁的情况与上边类似,只不过加的是+ XLock 3....这样极大的影响该表的并发事务处理能力,如果遇到这个情况,还是尽量对表建立合适的索引 另外可以通过设置innodb_locks_unsafe_for_binlog来提前释放锁 insert 语句 INSERT...INSERT 加锁分析整个流程 首先对插入的间隙加插入意向锁(Insert Intension Locks) 如果该间隙已被加上了 GAP 锁或 Next-Key 锁,则加锁失败进入等待 如果没有,...我们都是小青蛙 - MySQL加锁分析三部曲]

    1.7K10

    你的MySQL抖动

    你的MySQL抖动 1. 什么是MySQL 抖动 一条SQL语句正常执行的时候特别快,有时候变得特别慢。但是这种场景不是很常见。 2....MySQL 为什么抖动 2.1 脏页 内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存为脏页。 2.2 干净页 内存数据写入到磁盘后,内存和磁盘上的数据页的内容一致,称为干净页。...2.4 什么时候触发flush操作 InnoDB 的 redo log 写满了。 系统内存不够,需要新的内存页了,就需要淘汰一些内存页。 MySQL 认为系统空闲时候,开始flush。...这种情况尽量避免,一旦redo log 写满,系统拒绝更新操作,此时更新数为0。 2.5.2 系统内存不够。...2.5.3 MySQL空闲的时候 对性能基本无影响。 2.5.4 MySQL 关闭 对性能基本无影响。

    79620

    MySQL 加锁处理分析

    Insert操作稍微有些不同,简单来说,就是Insert操作可能触发Unique Key的冲突检查,也进行一个当前读。...我能想象到的一个答案是: SQL1:不加锁。因为MySQL是使用多版本并发控制的,读不加锁。 SQL2:对id = 10的记录加写锁 (走主键索引)。 这个答案对?说不上来。...有人可能问?为什么不是只在满足条件的记录上加锁呢?这是由于MySQL的实现决定的。...组合七:id非唯一索引+RR 还记得前面提到的MySQL的四种隔离级别的区别?RC隔离级别允许幻读,而RR隔离级别,不允许存在幻读。但是在组合五、组合六中,加锁行为又是与RC下的加锁行为完全一致。...Insert操作,如insert [10,aa],首先会定位到[6,c]与[10,b]间,然后在插入前,检查这个GAP是否已经被锁上,如果被锁上,则Insert不能插入记录。

    3.5K61

    mysql语句加锁分析

    其实并不能完全解决幻读问题, 这里可以参考另一篇博客[mysql事务隔离级别与加锁分析] SERIALIZABLE隔离级别下,需要分为两种情况讨论: 在系统变量autocommit=0时,也就是禁用自动提交时...这样极大的影响该表的并发事务处理能力,如果遇到这个情况,还是尽量对表建立合适的索引 另外可以通过设置innodb_locks_unsafe_for_binlog来提前释放锁 insert 语句 INSERT...INSERT 加锁分析整个流程 首先对插入的间隙加插入意向锁(Insert Intension Locks) 如果该间隙已被加上了 GAP 锁或 Next-Key 锁,则加锁失败进入等待 如果没有,...SessionB 和 SessionC 都试图继续执行插入操作, 都要加上 X 锁, 但两个Session都要等待对方的行锁, 所以出现了死锁 参考资料 [掘金小册-从根上理解MySQL] [公众号:...我们都是小青蛙 - MySQL加锁分析三部曲]

    87130

    MySQL InnoDB 加锁机制

    普通SELECT 时使用一致性非锁定读,MVCC, 不加锁; 锁定读SELECT 使用锁定读(当前读),加锁; 此外,DML(INSERT/UPDATE/DELETE)时,需要先查询表中的记录,此时也使用锁定读...,加锁; FOR SHARE 语法是 MySQL 8.0 时加入的,FOR SHARE 和 LOCK IN SHARE MODE 是等价的,但FOR SHARE 用于替代 LOCK IN SHARE MODE...例如, SELECT c1 FROM t WHERE c1 BETWEEN 1 AND 6 FOR UPDATE; 锁阻止其他事务将值2插入 c1的索引记录中,因为该范围内所有现有值之间的间隙都已锁定...Insert Intention Lock GAP Lock相互不会阻塞 Insert Intention Lock相互不会阻塞 Insert Intention Lock不会阻塞GAP Lock 存在一个情况...且由于MySQL会对锁的粒度做一定优化, 所以应以实际加锁为准. 1.

    3K00
    领券