Innodb间隙锁实战

锁概念

InnoDB存储引擎包含了三种行锁的算法,分别如下所示:

  • Record Lock:行锁,针对的是单行记录;
  • Gap Lock:间隙锁,锁定的是一个范围,但是不包含记录本身;
  • Next-Key Lock:其实就是行锁+间隙锁,包含了记录本身和范围;

为什么需要间隙锁

数据库一般都有四种隔离级别,其中最常用的就是:已提交读(Read committed)和可重复读(Repeatable read);在已提交读隔离级别下会出现不可重复读的现象,而在可重复读隔离级别下会出现幻读(Phantom Read)的现象;

幻读:同一事务下,连续执行两次同样的SQL可能会导致不同的结果;

Innodb引擎在可重复读隔离级别下并不会出现幻读的现象,这主要是因为Innodb提供了多版本并发控制MVCC间隙锁;常见的快照读其实就是使用的MVCC,而当前读就使用了间隙锁;

以下实例有两点说明:

  • Innodb的可重复读隔离级别下,对当前读使用了间隙锁来解决幻读的问题,所以下面的实例都是基于默认隔离级别RR;
  • Innodb的锁机制都依赖索引,所以下面的实例围绕索引来展开;

实战

无索引的情况

首先创建一个无索引的表,并初始化数据:

mysql> create table t1(a int);
mysql> insert into t1 values(1),(3),(5);

启动事务1,执行当前读:

mysql> begin;
mysql> select * from t1 where a=3 for update;

以上事务没有提交,再启动事务2,以下语句都被阻塞:

mysql> select * from t1 where a=3 for update;
mysql> insert into t1 values(1);
mysql> insert into t1 values(2);
mysql> insert into t1 values(5);
mysql> insert into t1 values(7);

但是这时候去执行快照读还是可以的:

mysql> select * from t1 where a=3;

可以发现在没有索引的情况下,除了快照读什么都干不了,感觉像是表被锁住了,表锁分为读和写锁,在写锁的情况下快照读同样被锁住,而在读锁的情况下可以使用快照读,类似上面无索引的情况;

mysql> lock table t1 read;  ## 读锁
mysql> lock table t1 write;  ## 写锁
mysql> unlock tables;  ## 解锁

那是不是无索引的情况下就使用了表锁那,可以通过如下命令进行查看,首先看一下在表锁的情况下执行插入操作:

mysql> SHOW PROCESSLIST;
+-----+------+-----------------+------+---------+------+------------------------------+--------------------------+
| Id  | User | Host            | db   | Command | Time | State                        | Info                     |
+-----+------+-----------------+------+---------+------+------------------------------+--------------------------+
|  75 | ODBC | localhost:65316 | test | Query   |   98 | Waiting for table level lock | insert into t1 values(7) |
+
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
限时福利1:购课进答疑群专享柳峰(刘运强)老师答疑服务 为什么需要掌握高性能的MySQL实战? 由于互联网产品用户量大、高并发请求场景多,因此对MySQL的性能、可用性、扩展性都提出了很高的要求。使用MySQL解决大量数据以及高并发请求已经是程序员的必备技能,也是衡量一个程序员能力和薪资的标准之一。 为了让大家快速系统了解高性能MySQL核心知识全貌,我为你总结了「高性能 MySQL 知识框架图」,帮你梳理学习重点,建议收藏! 【课程设计】 课程分为四大篇章,将为你建立完整的 MySQL 知识体系,同时将重点讲解 MySQL 底层运行原理、数据库的性能调优、高并发、海量业务处理、面试解析等。 一、性能优化篇: 主要包括经典 MySQL 问题剖析、索引底层原理和事务与锁机制。通过深入理解 MySQL 的索引结构 B+Tree ,学员能够从根本上弄懂为什么有些 SQL 走索引、有些不走索引,从而彻底掌握索引的使用和优化技巧,能够避开很多实战中遇到的“坑”。 二、MySQL 8.0新特性篇: 主要包括窗口函数和通用表表达式。企业中的许多报表统计需求,如果不采用窗口函数,用普通的 SQL 语句是很难实现的。 三、高性能架构篇: 主要包括主从复制和读写分离。在企业的生产环境中,很少采用单台MySQL节点的情况,因为一旦单个节点发生故障,整个系统都不可用,后果往往不堪设想,因此掌握高可用架构的实现是非常有必要的。 四、面试篇: 程序员获得工作的第一步,就是高效的准备面试,面试篇主要从知识点回顾总结的角度出发,结合程序员面试高频MySQL问题精讲精练,帮助程序员吊打面试官,获得心仪的工作机会。
### 回答1: innodb行级锁是MySQL数据库中一种非常常用的锁机制,它可以实现对表中某一行数据的并发读写操作。但是在一些特定的情况下,例如在使用大量锁的情况下,innodb行级锁可能会升级为表锁。在这种情况下,对整个表的访问就会受到限制,可能会影响数据库的性能和并发能力。如果您需要进一步了解关于innodb行级锁和表锁的信息,建议您查看MySQL的官方文档或者咨询相关的数据库专业人士。 ### 回答2: InnoDB是MySQL数据库中一种常见的存储引擎,它支持行级锁,这意味着在事务中只锁定需要访问的行,而不是整个表。但有时,行级锁可能会升级为表锁。 当一条SQL语句需要锁定大部分或全部的表时,InnoDB会将行级锁升级为表锁。这种情况下,InnoDB会自动将当前锁升级为表级别的锁,以提高性能和减少开销。表锁可以更快地锁定整个表,而不需要为每一行加锁。 行级锁升级为表锁可能发生在以下情况下: 1. 使用不可重复读隔离级别的事务:当一个事务正在进行读操作时,如果另一个事务已经对该表进行了修改操作,那么为了保证数据的一致性,InnoDB会将行级锁升级为表级锁。 2. 查询锁:当一个查询使用了FOR UPDATE或LOCK IN SHARE MODE时,InnoDB会将行级锁升级为表级锁,以确保查询的结果不会被其他事务修改。 3. 大事务:当一个事务涉及到大量的行,或需要锁定多个表时,为了避免锁冲突和死锁,InnoDB可能会将行级锁升级为表级锁。 总的来说,InnoDB将行级锁升级为表级锁是为了保证事务的一致性和数据的完整性。虽然表级锁可能会降低并发性能,但可以减少锁冲突和死锁的概率。在设计数据库应用程序时,应该根据实际需求和性能需求来选择适当的锁策略。 ### 回答3: InnoDB是MySQL的一种存储引擎,它支持行级锁和表级锁。行级锁是指对于同一张表的不同行,可以同时进行读取和修改操作,而表级锁则是指对整张表进行操作时会对整张表加锁,其他事务无法同时进行读取和修改操作。 在某些情况下,InnoDB的行级锁可能会升级为表级锁。这种情况主要包括两种情况: 1. 锁冲突:当多个事务同时访问同一张表的不同行,并且存在锁冲突时,InnoDB会将行级锁升级为表级锁。这是为了避免锁冲突导致的死锁情况发生,通过使用表级锁可以减少锁冲突的概率。 2. 隐式锁升级:当某个事务执行一个需要全表扫描或大范围扫描操作时,InnoDB会自动将行级锁升级为表级锁。这是为了减少InnoDB的锁资源占用和提高性能,因为在全表扫描或大范围扫描时,涉及的行数较多,行级锁可能需要占用较多的内存资源。 行级锁升级为表锁的情况是自动发生的,并且开发者无法手动干预或控制。但是,表级锁的使用可能会对并发性能产生一定的影响。因此,为了避免行级锁升级为表级锁的情况发生,我们可以优化事务的操作,尽量减少锁冲突的可能性,使用合适的索引来减少全表扫描或大范围扫描操作的发生。 总而言之,InnoDB的行级锁可以在一定程度上提高并发性能,但在特定情况下会升级为表级锁。了解这些情况并采取优化措施可以更有效地利用锁资源,提高系统的并发性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值