精华内容
下载资源
问答
  • The following example demonstrates...就像上面的例子,如果 Client B 不需要在获取独占锁前获取插入意向锁,而是直接获取独占锁,Client B 也会因为 Client A 已经拥有的间隙锁(90, 102)而等待。是我哪里理解错了吗?

    The following example demonstrates a transaction taking an insert intention lock prior to obtaining an exclusive lock on the inserted record. The example involves two clients, A and B.

    Client A creates a table containing two index records (90 and 102) and then starts a transaction that places an exclusive lock on index records with an ID greater than 100. The exclusive lock includes a gap lock before record 102:

    mysql> CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;

    mysql> INSERT INTO child (id) values (90),(102);

    mysql> START TRANSACTION;

    mysql> SELECT * FROM child WHERE id > 100 FOR UPDATE;

    +-----+

    | id |

    +-----+

    | 102 |

    +-----+

    Client B begins a transaction to insert a record into the gap. The transaction takes an insert intention lock while it waits to obtain an exclusive lock.

    mysql> START TRANSACTION;

    mysql> INSERT INTO child (id) VALUES (101);

    但是我不太理解插入意向锁存在的意义是什么?它的作用是什么呢?能够防止什么操作并发执行?就像上面的例子,如果 Client B 不需要在获取独占锁前获取插入意向锁,而是直接获取独占锁,Client B 也会因为 Client A 已经拥有的间隙锁(90, 102)而等待。是我哪里理解错了吗?

    展开全文
  • mysql插入意向锁测试

    2021-03-03 20:02:00
    3、两种尝试 下面两种方案都会造成阻塞,我理解都是事务1获取到了间隙锁,事务2获取插入意向锁阻塞,但是“show engine INNODB status\G;”输出结果不一样, 第一种方案 事务1 lock_mode X locks gap before rec 我...

    1、表结构

    CREATE TABLE `reno` (

    `id` int(11) NOT NULL AUTO_INCREMENT,

    `name` varchar(10) DEFAULT NULL,

    PRIMARY KEY (`id`)

    ) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8

    2、表数据

    insert into reno select 5, 'aa';

    insert into reno select 7, 'bb';

    insert into reno select 9, 'cc';

    insert into reno select 18, 'dd';

    insert into reno select 23, 'ee';

    insert into reno select 30, 'ff';

    insert into reno select 40, 'gg';

    insert into reno select 45, 'hh';

    insert into reno select 99, 'ii';

    3、两种尝试

    下面两种方案都会造成阻塞,我理解都是事务1获取到了间隙锁,事务2获取插入意向锁阻塞,但是“show engine INNODB status\G;”输出结果不一样,

    第一种方案

    事务1 lock_mode X locks gap before rec 我理解是间隙锁

    事务2 lock_mode X locks gap before rec insert intention waiting 我理解是获取插入意向锁

    第二种方案

    事务1  trx id 9821 lock_mode X 我理解是 Next key锁

    事务2 lock_mode X insert intention waiting 我理解是获取插入意向锁

    我的疑问 为什么两个方案,事务1获取的锁,以及事务2获取的锁都是不一样的呢

    35aef467c9ff

    35aef467c9ff

    第一种方案

    展开全文
  • :对 “某种范围” 的数据上 “某种” 1.“某种范围”:行、表 2.“某种” 2.1 共享Shared Locks(S) 1、兼容性:加了S的记录,允许其他事务再加S,不允许其他事务再加X 2、加锁方式:select…lock...

    目录

    锁:对 “某种范围” 的数据上 “某种锁”
    1.“某种范围”:行、表
    2.“某种锁”
    2.1 共享锁Shared Locks(S锁)
    2.2 排他锁Exclusive Locks(X锁)
    2.3 表锁:意向锁 Intention Locks,意向锁相互兼容
    2.4 行锁:记录锁(Record Locks)
    2.5 行锁:间隙锁(Gap Locks)
    2.6 *行锁:临键锁(Next-Key Locks)
    2.7 行锁:插入意向锁(Insert Intention Locks)
    2.8 锁的兼容性
    2.9 表锁:自增锁(AUTO-INC Locks)
    3.锁的选择
    帮助知识
    1.查看事务、锁的sql

    锁:对 “某种范围” 的数据上 “某种锁”

    1.“某种范围”:行、表 2.“某种锁”

    2.1 共享锁Shared Locks(S锁)

    1、兼容性:加了S锁的记录,允许其他事务再加S锁,不允许其他事务再加X锁

    2、加锁方式:select…lock in share mode

    2.2 排他锁Exclusive Locks(X锁)

    1、兼容性:加了X锁的记录,不允许其他事务再加S锁或者X锁

    2、加锁方式:select…for update

    2.3 表锁:意向锁 Intention Locks,意向锁相互兼容

    1、表明“某个事务正在某些行持有了锁、或该事务准备去持有锁”

    2、意向锁的存在是为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存,。

    3、例子:事务A修改user表的记录r,会给记录r上一把行级的排他锁(X),同时会给user表上一把意向排他锁(IX),这时事务B要给user表上一个表级的排他锁就会被阻塞。意向锁通过这种方式实现了行锁和表锁共存且满足事务隔离性的要求。

    4、1)意向共享锁(IS锁):事务在请求S锁前,要先获得IS锁
    2)意向排他锁(IX锁):事务在请求X锁前,要先获得IX锁

    q1:为什么意向锁是表级锁呢?
    当我们需要加一个排他锁时,需要根据意向锁去判断表中有没有数据行被锁定(行锁);

    (1)如果意向锁是行锁,则需要遍历每一行数据去确认;

    (2)如果意向锁是表锁,则只需要判断一次即可知道有没数据行被锁定,提升性能。

    q2:意向锁怎么支持表锁和行锁并存?
    (1)首先明确并存的概念是指数据库同时支持表、行锁,而不是任何情况都支持一个表中同时有一个事务A持有行锁、又有一个事务B持有表锁,因为表一旦被上了一个表级的写锁,肯定不能再上一个行级的锁。
    (2)如果事务A对某一行上锁,其他事务就不可能修改这一行。这与“事务B锁住整个表就能修改表中的任意一行”形成了冲突。所以,没有意向锁的时候,让行锁与表锁共存,就会带来很多问题。于是有了意向锁的出现,如q1的答案中,数据库不需要在检查每一行数据是否有锁,而是直接判断一次意向锁是否存在即可,能提升很多性能。

    5、下图表示意向锁和共享锁、排他锁的兼容关系。
    意思是 当事务A对某个数据范围(行或表)上了“某锁”后,另一个事务B是否能在这个数据范围上“某锁”。

    在这里插入图片描述

    意向锁相互兼容,因为IX、IS只是表明申请更低层次级别元素(比如 page、记录)的X、S操作。

    因为上了表级S锁后,不允许其他事务再加X锁,所以表级S锁和X、IX锁不兼容

    上了表级X锁后,会修改数据,所以表级X锁和 IS、IX、S、X(即使是行排他锁,因为表级锁定的行肯定包括行级速订的行,所以表级X和IX、行级X)不兼容。

    注意:上了行级X锁后,行级X锁不会因为有别的事务上了IX而堵塞,一个mysql是允许多个行级X锁同时存在的,只要他们不是针对相同的数据行。

    2.4 行锁:记录锁(Record Locks)

    (1)记录锁, 仅仅锁住索引记录的一行,在单条索引记录上加锁。
    (2)record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。
    所以说当一条sql没有走任何索引时,那么将会在每一条聚合索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。

    2.5 行锁:间隙锁(Gap Locks)

    (1)区间锁, 仅仅锁住一个索引区间(开区间,不包括双端端点)。
    (2)在索引记录之间的间隙中加锁,或者是在某一条索引记录之前或者之后加锁,并不包括该索引记录本身。

    比如在 1、2、3中,间隙锁的可能值有 (∞, 1),(1, 2),(2, ∞),
    (3)间隙锁可用于防止幻读,保证索引间的不会被插入数据

    2.6 *行锁:临键锁(Next-Key Locks)

    (1)record lock + gap lock, 左开右闭区间。
    (2)默认情况下,innodb使用next-key locks来锁定记录。select … for update
    (3)但当查询的索引含有唯一属性的时候,Next-Key Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,不是范围。
    (4)Next-Key Lock在不同的场景中会退化:

    在这里插入图片描述

    2.7 行锁:插入意向锁(Insert Intention Locks)

    (1)插入意向锁是一种Gap锁,不是意向锁,在insert操作时产生。
    (2)在多事务同时写入不同数据至同一索引间隙的时候,并不需要等待其他事务完成,不会发生锁等待。
    (3)假设有一个记录索引包含键值4和7,不同的事务分别插入5和6,每个事务都会产生一个加在4-7之间的插入意向锁,获取在插入行上的排它锁,但是不会被互相锁住,因为数据行并不冲突。

    (4)插入意向锁不会阻止任何锁,对于插入的记录会持有一个记录锁。

    本例子和插入意向锁无关:是Gap锁和排它锁的关系
    例如test表存在若干数据的数据,先开始一个事务A,插入一条n=5的数据;(图中步骤1)
    此时如果开始一个事务B,执行查询 select * from test where n > 4 for update,事务B会申请Gap锁(4, ∞),申请成功后,被事务A的x锁阻塞,直到x锁被释放。(图中步骤2)
    可以看到图中步骤3的信息,在等待事务释放X锁

    在这里插入图片描述
    在这里插入图片描述

    2.8 锁的兼容性

    在这里插入图片描述

    2.9 表锁:自增锁(AUTO-INC Locks)

    AUTO-INC锁是一种特殊的表级锁,发生涉及AUTO_INCREMENT列的事务性插入操作时产生。

    3.锁的选择

    1.如果更新条件没有走索引,例如执行”update test set name=“hello” where name=“world”;” ,此时会进行全表扫描,扫表的时候,要阻止其他任何的更新操作,所以上升为表锁。

    2.如果更新条件为索引字段,但是并非唯一索引(包括主键索引),例如执行“update test set name=“hello” where code=9;” 那么此时更新会使用Next-Key Lock。使用Next-Key Lock的原因:

    首先要保证在符合条件的记录上加上排他锁,会锁定当前非唯一索引和对应的主键索引的值;

    还要保证锁定的区间不能插入新的数据。

    如果更新条件为唯一索引,则使用Record Lock(记录锁)。

    帮助知识

    1.查看事务、锁的sql
    select from information_schema.innodb_locks;
    select from information_schema.innodb_lock_waits;
    select * from information_schema.innodb_trx;

    展开全文
  • 问题描述线上出现MySQL死锁报警,通过show engine innodb status命令查看死锁日志,结合异常代码,还原发生死锁的事务场景如下:环境: mysql5.7,事务隔离级别REPEATABLE-READ表结构CREATE TABLE `ta` (`id` int ...

    问题描述

    线上出现MySQL死锁报警,通过show engine innodb status命令查看死锁日志,结合异常代码,还原发生死锁的事务场景如下:

    环境: mysql5.7,事务隔离级别REPEATABLE-READ

    表结构

    CREATE TABLE `ta` (

    `id` int AUTO_INCREMENT,

    `a` int,

    `b` int , `c` int ,

    PRIMARY KEY (`id`),

    UNIQUE KEY `ux_a_b` (`a`,`b`)

    ) ENGINE=InnoDB

    数据:

    mysql> select * from ta;

    +----+------+------+------+

    | id | a | b | c |

    +----+------+------+------+

    | 1 | 1 | 10 | 100 |

    | 2 | 3 | 20 | 99 |

    | 3 | 5 | 50 | 80 |

    +----+------+------+------+

    并发事务

    T1

    T2

    begin;

    begin

    delete from ta where a = 4;//ok, 0 rows affected

    delete from ta where a = 4; //ok, 0 rows affected

    insert into ta(a,b,c) values(4, 11, 3),(4, 2, 5);//wating,被阻塞

    insert into ta(a,b,c) values(4, 11, 3),(4, 2, 5); //ERROR 1213 (40001): Deadlock found when trying to get lock;

    T1执行完成, 2 rows affected

    从上面可以看出,并发事务都成功执行delete后(影响行数为0),执行insert出现死锁。

    死锁分析

    等待锁分析

    查看死锁日志,显示事务T1的insert语句在等待插入意向锁,lock_mode X locks gap before rec insert intention waiting;事务T2持有a=4的gap lock,同时也在等待插入意向锁。另外,T1能执行delete,说明它也拿到了gap lock,所以,两个事务都持有gap lock,导致循环等待插入意向锁而发生死锁。

    加锁分析

    delete的where子句没有满足条件的记录,而对于不存在的记录 并且在RR级别下,delete加锁类型为gap lock,gap lock之间是兼容的,所以两个事务都能成功执行delete;关于gap lock可以参考文章加锁分析。这里的gap范围是索引a列(3,5)的范围。

    insert时,其加锁过程为先在插入间隙上获取插入意向锁,插入数据后再获取插入行上的排它锁。又插入意向锁与gap lock和 Next-key lock冲突,即一个事务想要获取插入意向锁,如果有其他事务已经加了gap lock或 Next-key lock,则会阻塞。

    场景中两个事务都持有gap lock,然后又申请插入意向锁,此时都被阻塞,循环等待造成死锁。

    锁兼容矩阵:

    死锁解决

    方案如下几种选择:

    不采用事务包装这部分逻辑,本文实际业务场景中可以不需要事务,所以直接取消事务包装即可,采用insert ON DUPLICATE KEY UPDATE的方式

    调整事务隔离级别为read commit,RC级别不会产生gap lock

    利用分布式锁

    附:排查过程

    查看死锁日志,注意这里并不会包含整个事务的相关sql,仅仅会把等待锁的SQL打印出来,死锁日志内容含义参考 :http://blog.itpub.net/22664653/viewspace-2145133/

    根据服务异常log定位到具体事务执行代码,找出该事务相关的sql

    根据积累的经验知识分析加锁、锁等待情况,找出死锁原因

    参考

    展开全文
  • MySQL锁的总结 和 一次插入意向锁的死锁还原分析锁总结为什么要加锁?有什么锁?常见的三种锁常见的五种锁模式锁的兼容性如何分析死锁已经发生死锁正在阻塞中,等待锁释放。记一次死锁还原分析死锁总结
  • mysql 意向锁的作用

    千次阅读 2021-02-03 07:02:23
    ①在mysql中有表锁,LOCK TABLE my_tabl_name READ; 用读锁锁表,会阻塞其他事务修改表数据。LOCK TABLE my_table_name WRITe; 用写锁锁表,会阻塞其他事务读和写。②Innodb引擎又支持行锁,行锁分为共享,一个...
  • MySQL 行锁 意向锁 间隙锁一、锁的分类共享锁:反正我就理解成读锁一个意思,事务A对某些数据加了共享锁,允许其他事务同时获取这些数据共享锁,但是不可以在这些数据上加排它锁。排它锁:理解成写锁吧,事务A对某些...
  • MySQL InnoDB插入意向锁

    2021-01-20 01:30:26
    INSERT INTENTION LOCK,翻译为插入意向锁,其实准确来说应该是 INSERT INTENTION GAP LOCK,属于 GAP LOCK 子类。这个锁类型在老版本的 InnoDB 中并不存在,后来是为了优化插入性能而设计的。在 INSERT 操作插入...
  • mysql innodb插入意向锁

    千次阅读 2015-06-07 10:32:17
    innodb中有插入意向锁,专门针对insert,如果插入前,该间隙已经由gap锁,那么Insert会申请插入意向锁。那么这个插入意向锁的作用是什么? 1、为了唤起等待。因为该间隙已经有锁,插入时必须阻塞。插入 意向锁的...
  • 插入意向锁(Insert Intention Lock)插入意向锁本质上可以看成是一个Gap Lock普通的Gap Lock 不允许 在 (上一条记录,本记录) 范围内插入数据插入意向锁Gap Lock 允许 在 (上一条记录,本记录) 范围内插入数据插入...
  • Mysql 插入意向锁与自增锁备份锁日志锁 插入意向锁Insert Intention Lock 插入意向锁Insert intention locks是记录级别的,它通过“INSERT”关键词来向其它的事务传达插入的意向。插入意向锁针对的是将要插入的...
  • 锁的粒度 A. 表锁(Table Lock) 对整个表加锁,影响标准的所有记录。通常用在DDL语句中,如DELETE TABLE,ALTER TABLE等。 B. 行锁(Row Lock) 对一行记录加锁,只影响一条记录。...- 意向锁(I
  • MySQL innodb意向锁介绍

    2021-03-14 12:26:53
    那么为什么需要引入意向锁呢?它能解决什么问题呢?假设,事务A获取了某一行的排它锁,尚未提交,此时事务B想要获取表锁时,必须要确认表的每一行都不存在排他锁,很明显效率会很低,引入意向锁之后,效率就会大为...
  • 间隙 间隙,如其名字,住的是索引值,如:delete from tableX where id ...在Repeatable read, 的隔离级别,id为唯一主键的条件下,将住 2到10之间的间隙,如果其他事务需要插入主键是2到10之间的记...
  • 前言InnoDB 支持多粒度锁(multiple granularity locking),它允许行级锁与表级锁共存,而意向锁就是其中的一种表锁。意向锁(Intention Locks)需要强调一下,意向锁是一种不与行级锁冲突表级锁,这一点非常重要。意向...
  • “某种”2.1 共享Shared Locks(S)1、兼容性:加了S的记录,允许其他事务再加S,不允许其他事务再加X2、加锁方式:select…lock in share mode2.2 排他Exclusive Locks(X)1、兼容性:加了X的记录,...
  • MySql,InnoDB,Repeatable-Read:users(id PK, name, age KEY) id name age 1 Mike 10 2 Jone 20 3 Tony 30 首先事务 A 插入了一行数据,并且没有 commit: INSERT INTO users SELECT 4, ...
  • innodb锁-插入意向锁

    千次阅读 2019-01-13 16:20:12
    Insert Intention Locks译称插入意向锁,首先强调插入意向锁是间隙锁的一种,本文参考官方文档进行学习说明 数据库版本: SELECT VERSION(); ±-----------+ | version() | ±-----------+ | 5.6.34-log | ...
  • 自增MySQL一种特殊的,如果表中存在自增字段,MySQL便会自动维护一个自增。 共享又称为读,简称S,顾名思义,共享就是多个事务对于同一数据可以共享一把,都能访问到最新数据。 排他又称为写...
  • InnoDB 存储引擎中使用的多种并发控制策略,按照的粒度划分,可以分成行锁和表锁。 1. 并发控制 并发控制保证数据一致性的常见手段有:(Locking)和数据多版本(Multi Versioning)。乐观和悲观其实都是...
  • 所以这个死锁是因为插入意向锁与gap锁不兼容导致的死锁冲突。即便插入的u_contract_number值不一样。 死锁过程猜测是如下这样 事务1 通过某种手段(比如说for update)获取heap no为244 的X gap锁 事务2 通过某种...
  • InnoDB的锁机制浅析(二)—探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意向锁) InnoDB的锁机制浅析(三)—幻读 InnoDB的锁机制浅析(四)—不同SQL的加锁状况 InnoDB的锁机制浅析(五)—死锁场景(Insert死锁) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,039
精华内容 2,815
关键字:

mysql插入意向锁

mysql 订阅