我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MySQL表级锁使用说明

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MySQL表级锁使用说明

表级锁

该锁会锁定整张表,它是mysql中最基本的锁策略,并不依赖于存储引擎(不管你是MySQL的什么存储引擎,对于表锁的策略都是一样的),并且表锁是开销最小的策略(因为粒度比较大)。由于表级锁一次会将整个表锁定,所以可以很好的避免死锁问题。当然,锁的粒度大所带来最大的负面影响就是出现锁资源争用的概率也会最高,导致并发率大打折扣。

1、表级别的S锁,X锁

InnoDB存储引擎

在对某个表执行SELECT、INSERT、DELETE、UPDATE 语句时,InnoDB存储引擎是不会为这个表添加表级别的S锁或者X锁的。

一般情况下,不会使用InnoDB存储引擎提供的表级别的S锁和X锁。只会在一些特殊情况下,比方说崩溃恢复过程中用到。

InnoDB存储引擎下,手动添加表t的S锁或X锁:

lock tables t read  -- S锁
lock tables t write  -- X锁

不过尽量避免在使用InnoDB存储引擎的表上使用LOCK TABLES这样的手动锁表语句,它们并不会提供什么额外的保护,只是会降低并发能力而已。

MyISAM存储引擎

MyISAM 的表级锁有2种模式,分别为:表共享读锁(S锁) 和 表独占写锁(X锁)。

表共享读锁(S锁):当开启事务A 获取表共享读锁, 则其他新开启事务只能读取数据,不能对操作的同张表进行更新或者插入操作,删除操作,

表独占写锁(X锁):当开启事务A 获取独占写锁,则其他新开启的事物 读取,新增,修改,删除 等操作会处于阻塞状态, 只到 事务A 主动释放锁。

MySQL表级锁使用说明

MyISAM存储引擎下,手动添加表t的S锁或X锁:

lock tables t read  -- S锁
lock tables t write  -- X锁

可通过 show status like 'tables%'; 命令来 查看 mysql 内部表级锁定的情况:

2、意向锁

意向锁概述

InnoDB支持多粒度锁(multiple granularity locking),它允许行级锁与表级锁共存,而意向锁就是其中的一种表锁。

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

意向锁是一种不与行级锁冲突的表级锁,这一点非常重要。

意向锁分为两种:

  • 意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁)
select column from table ... lock in share mode; -- 
  • 意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些行加排他锁(X锁)
select column from table ... for mode; -- 

申请意向锁的动作是数据库完成的,就是说,事务A申请一行的行锁的时候,数据库会自动先开始申请表的意向锁,不需要我们程序员使用代码来申请。

意向锁解决的问题

事务A锁住了表中的一行,让这一行只能读,不能写。之后,事务B申请整个表的写锁。

如果事务B申请成功,那么理论上它就能修改表中的任意一行,这与A持有的行锁是冲突的。

数据库需要避免这种冲突,就是说要让B的申请被阻塞,直到A释放了行锁。于是就有了意向锁。

事务B只需检查表上的意向锁,发现表上有意向共享锁IS,说明表中有些行被共享行锁锁住了,因此,事务B申请表的写锁会被阻塞。

在数据表的场景中,如果我们给某一行数据加上了排它锁,数据库会自动给更大一级的空间,比如数据页或数据表加上意向锁,告诉其他人这个数据页或数据表已经有人上过排它锁了,这样当其他人想要获取数据表排它锁的时候,只需要了解是否有人已经获取了这个数据表的意向排他锁即可。

  • 如果事务想要获得数据表中某些记录的共享锁,就需要在数据表上添加意向共享锁。
  • 如果事务想要获得数据表中某些记录的排他锁,就需要在数据表上添加意向排他锁。

意向锁的并发性

开启一个事务,并给查询记录加上X锁:此时针对查询的记录还加上了一个表级别的共享排它锁(IX)

MySQL表级锁使用说明

再开启一个事务,查询不同记录,并给查询记录加上X锁:表级别的 IX共享排它锁加锁成功,因为两次事务加的IX是针对不同的记录的

MySQL表级锁使用说明

结论:

  • InnoDB支持多粒度锁,特定场景下,行级锁可以与表级锁共存。
  • 意向锁之间互不排斥,但除了IS与S兼容外,意向锁会与共享锁/排他锁互斥。
  • lX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突。
  • 意向锁在保证并发性的前提下,实现了行锁和表锁共存且满足事务隔离性的要求。

3、自增锁(AUTO-INC锁)

自增锁是MySQL一种特殊的锁,如果表中存在自增字段,当向表中插入数据时,MySQL便会自动维护一个表级的自增锁。

在执行插入语句时就在表级别加一个AUTO-INC锁,然后为每条待插入记录的AUTO_INCREMENT修饰的列分配递增的值,在该语句执行结束后,再把AUTO-INC锁释放掉。

一个事务在持有AUTO-INC锁的过程中,其他事务的插入语句都要被阻塞,可以保证一个语句中分配的递增值是连续的。也正因为此,其并发性显然并不高,当我们向一个有AUTO_INCREMENT关键字的主键插入值的时候,每条语句都要对这个表锁进行竞争,这样的并发潜力其实是很低下的。

所以 innodb 引擎通过设置 innodb_autoinc_lock_mode 的值来提供不同的锁定机制,来显著提高sQL语句的可伸缩性和性能。

innodb_autoinc_lock_mode有三个取值:0,1,2

tradition(innodb_autoinc_lock_mode = 0) 模式:==传统==锁定模式

  • 它提供了一个向后兼容的能力
  • 在这一模式下,所有类型的insert语句都会在语句开始的时候得到一个表级的auto_inc锁,用于插入具有auto_inc列的表,在语句结束的时候才释放这把锁,注意,这里说的是语句级而不是事务级的,一个事务可能包涵有一个或多个语句。
  • 它能保证值分配的可预见性,与连续性,可重复性,这个也就保证了insert语句在复制到slave的时候还能生成和master那边一样的值(它保证了基于语句复制的安全)。
  • 由于在这种模式下auto_inc锁一直要保持到语句的结束,所以这个就影响到了并发的插入。因为是表级锁,当在同一时间多个事务中执行 insert 的时候,对于auto_inc锁的争夺会限制并发能力。

consecutive(innodb_autoinc_lock_mode = 1) 模式:==连续==锁定模式

  • 在MySQL8.0之前,==连续==锁定模式是默认的添加模式
  • 这一模式在simple insert (要插入的行数已知)做了优化,由于simple insert一次性插入值的个数可以立马得到确定,所以mysql可以一次生成几个连续的值,用于这个insert语句;总的来说这个对复制也是安全的 (它保证了基于语句复制的安全)
  • 这一模式也是mysql的默认模式,这个模式的好处是auto_inc锁不要一直保持到语句的结束,只要语句得到了相应的值后就可以提前释放锁

interleaved(innodb_autoinc_lock_mode = 2) 模式:==交错==锁定模式

  • 在MySQL8.0,==交错==锁定模式是默认的添加模式
  • 由于这个模式下所有insert语句都不回使用表级auto_inc锁,并且可以同时执行多个语句,这是最快和最可扩展的锁定模式,所以这个模式下的性能是最好的;但是它也有一个问题,由于多个语句可以同时生成数字,为任何给定语句插入的行生成的值可能是不连续的。

4、元数据锁(MDL锁)

在对某个表执行一些诸如ALTER TABLE、DROP TABLE 这类的 DDL 语句时,其他事务对这个表并发执行诸如 SELECT、INSERT、DELETE、UPDATE的语句会发生阻塞。

同理,某个事务中对某个表执行SELECT、INSERT、DELETE、UPDATE语句时,在其他会话中对这个表执行DDL语句也会发生阻塞。

这个过程其实是通过在server层使用一种称之为元数据锁(英文名: Metadata Locks,简称MDL)结构来实现的。

MySQL5.5引入了meta data lock,简称MDL锁,属于表锁范畴。MDL的作用是,保证读写的正确性。比如,如果一个查询正在遍历一个表中的数据,而执行期间另一个线程对这个表结构做变更,增加了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的。

因此,当对一个表做增删改查操作的时候,加MDL读锁;当要对表做结构变更操作的时候,加MDL写锁。

==读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。读锁和写锁之间、写锁和写锁之间是互斥的==,用来保证变更表结构操作的安全性,解决了 DML 和 DDL 操作之间的一致性问题。MDL锁不需要显式使用,在访问一个表的时候会被自动加上。

以上就是MySQL表级锁使用说明的详细内容,更多关于MySQL 表级锁的资料请关注我们其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MySQL表级锁使用说明

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Golang的锁机制使用及说明

这篇文章主要介绍了Golang的锁机制使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-02-16

vueantdForm表单的使用及说明

这篇文章主要介绍了vueantdForm表单的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-17

MySQL ifnull的嵌套使用说明

MySQL ifnull的嵌套使用 在网上查询ifnull有没有嵌套使用的方式,但是貌似没有人提到过这个用法:大都是简单的判断一个字段是否为空,然后用另外一个值代替的方式使用; 即是:select ifnull(a,b) from A ;但
2022-05-26

MySQL的全局锁和表级锁的具体使用

目录前言全局锁表级锁表锁元数据锁(Metadata Locking,简称:MDL锁)总结参考资料前言在真实的企业开发环境中使用MySQL,MySQL肯定不会只有我一个人使用,而是一个团队显式的使用MySQL,或者是业务隐式的使用MySQL,
2022-05-13

window.dialogArguments 使用说明

window.dialogArguments 使用说明,需要的朋友可以参考下。
2022-11-21

说明如何使用javascript提交表单

随着Web技术的不断进步,动态Web网站的开发越来越受到人们的关注,JavaScript作为一种客户端脚本语言,为Web应用程序提供了很好的交互和响应能力。其中,提交表单是JavaScript最基础的功能之一。本文将为您讲解如何使用JavaScript提交表单,主要从以下几个方面进行讲解:1.表单的基本结构和属性2.使用JavaScript获取表单数据3.修改表单数据并提交表单
2023-05-22

LayUI树形表格treetable使用及说明

这篇文章主要介绍了LayUI树形表格treetable使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

z3py使用说明

http://z3prover.github.io/api/html/z3.html http://www.cs.tau.ac.il/~msagiv/courses/asv/z3py/guide-examples.htm 学习
2023-01-31

MySQL 的CASE WHEN 语句使用说明

在MySQL中,CASE WHEN语句用于对一系列条件进行判断,并根据不同的条件返回不同的结果。语法如下:```CASEWHEN condition1 THEN result1WHEN condition2 THEN result2...W
2023-08-17

MySQL的表级锁,行级锁,排它锁和共享锁

目录前言一、表级锁&行级锁二、排它锁&共享锁1. 测试不同事务之间排它锁和共享锁的兼容性2. 测试行锁加在索引项上三、串行化隔离级别测试前言如果我们和面试官聊到事务的问题,怎么回答呢?先说下事务是什么,因为我们业务是比较复杂的,不可能一
2022-07-14

Android ContentResolver使用说明

Android是如何实现应用程序之间数据共享的?一个应用程序可以将自己的数据完全暴露出去,外界更本看不到,也不用看到这个应用程序暴露的数据是如何存储的,或者是使用数据库还是使用文件,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这
2022-06-06

Xilinx URAM使用说明

Xilinx URAM(Ultra RAM)是一种高性能、低延迟的存储器资源,用于在Xilinx FPGA器件中实现大容量的存储和高带宽的存储访问。以下是使用Xilinx URAM的一般步骤:1. 在Vivado设计工具中创建一个新的工程,
2023-09-23

Python sys 使用说明

获取linux下python的路径,以及执行python时使用的参数。代码如下: #!/usr/bin/python # -*- encoding:utf-8 -*- # time:2012-07-06 import sys;   prin
2023-01-31

编程热搜

目录