【MySQL进阶篇】锁:全局锁、表级锁以及行级锁

news2024/11/14 20:40:04

一、锁的概述

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须要解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。因此,锁对数据库尤为重要,也更加复杂。

1.1、分类

1、全局锁:锁定数据库中的所有表。

2、表级锁:每次操作锁住整张表。

3、行级锁:每次操作锁住对应的行数据。

二、全局锁

全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。

其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,从而保证数据的完整性。

加上全局锁:

2.1、语法结构 

加锁:

FLUSH TABLES WITH READ LOCK;

执行数据备份:

MYSQLDUMP  -uroot -p指定密码 数据库名称>数据库名称.sql; 

 解锁:

UNLOCK TABLES;

flush tables with read lock ;
update score set chines=92 where id=1;
#解锁
unlock tables;
#数据备份,可以在cmd命令行中输入
mysqldump -hlocalhost -uroot -p0219423 staff_data > D:/staff_data.sql

 2.2、全局锁特点

数据库中加全局锁是一个比较重的操作,存在以下问题:

1、如果在主库上备份,那么在备份期间都不能执行更新,就业基本上陷入停摆;

2、如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志,会导致主从延迟。

在InnoDB引擎中我们可以在备份时加上参数 --single -transaction 参数来完成不加锁的一致性数据备份。

三、表级锁

表级锁,每次操作锁住整张表。锁的力度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、DBD等存储引擎中。

3.1、分类

对于表级锁,主要分为以下三类:

1、表锁

2、元数据所

3、意向锁

3.1.1、表锁

对于表锁,又可以分为两类:

1、表共享读锁(read lock):客户端一可以读取表数据,但不能进行写入,客户端二也是如此。

2、表独占写锁(write lock):客户端既能读取数据也可以写入数据,客户端二既不能读数据也不能写入数据。

#语法:

#1、加锁:

lock tables 表名...read/write;

#2、释放锁:

unlock tables/客户端断开连接;

3.1.2、元数据锁(MDL)

MDL加锁过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上。MDL锁主要作用是为了维护表元数据的数据一致性,在表上有活动事务的时候,不可以队员数据进行写入操作。为了避免DDL与DML冲突,保证读写的正确性。 

在MySQL5.5中引入了MDL,当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构变更操作的时候,加上MDL写锁(排他)。

对应SQL锁类型说明
lock tables xxx read / write SHARED_READ_ONLY/SHARED_NO_READ_WRITE
select、select ... lock in share modeSHARED_READ与SHARED_READ、SHARED_WRITE兼容,与EXCLUSIVE互斥
insert、update、delete、select ... for updateSHARED_WRITE与SHARED_READ、SHARED_WRITE兼容,与EXCLUSIVE互斥
alter table ...EXCLUSIVE与其他的MDL都互斥
#客户端一执行select操作:
 begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from score;
+------+--------+--------+------+---------+
| id   | name   | chines | math | english |
+------+--------+--------+------+---------+
|    1 | 米老鼠 |     92 |   80 |      66 |
|    2 | 唐老鸭 |     67 |   88 |      91 |
|    3 | 杰瑞   |     76 |   71 |      77 |
|    4 | 汤姆   |     88 |   55 |      62 |
+------+--------+--------+------+---------+
4 rows in set (0.00 sec)
#客户端二执行修改表结构操作:
 begin;
Query OK, 0 rows affected (0.00 sec)

mysql> alter table score add java int;
#到这里会发生阻塞,直到客户端1执行事务提交操作

 查看元数据锁:

select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;

3.1.3、意向锁 

为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。

过程:

线程A在执行的时候先开启事务,对某一行加上行锁,然后对整张表加上一个意向锁,线程B则对这张表加上表锁,在加表锁时,会去检查这张表中意向锁的情况,通过意向锁的情况来决定加锁是否能够成功,如果意向锁和我们当前所加的表锁是兼容的,就可以加锁;反之线程B则会处于阻塞状态,直至线程A提交事务,行锁与意向锁释放。

意向锁的分类:

1、意向共享锁(IS):由语句select ... lock in share mode添加;与表锁共享锁(read)兼容,与表锁排他锁(write)互斥。

2、意向排他锁(IX):insert、update、delete、select ... for update添加;与表锁共享锁(read)及表锁排他锁(write)都互斥。意向锁之间不会互斥。

可以通过以下SQL来查看意向锁及行锁的加锁情况:

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
#客户端一:
 begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from score where id=1 lock in share mode;
#客户端二:
 select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
+---------------+-------------+-----------------+-----------+-----------+------------------------+
| object_schema | object_name | index_name      | lock_type | lock_mode | lock_data              |
+---------------+-------------+-----------------+-----------+-----------+------------------------+
| staff_data    | score       | NULL            | TABLE     | IS        | NULL                   |
| staff_data    | score       | GEN_CLUST_INDEX | RECORD    | S         | supremum pseudo-record |
| staff_data    | score       | GEN_CLUST_INDEX | RECORD    | S         | 0x00000000022E         |
| staff_data    | score       | GEN_CLUST_INDEX | RECORD    | S         | 0x00000000022F         |
| staff_data    | score       | GEN_CLUST_INDEX | RECORD    | S         | 0x000000000230         |
| staff_data    | score       | GEN_CLUST_INDEX | RECORD    | S         | 0x000000000231         |
+---------------+-------------+-----------------+-----------+-----------+------------------------+
6 rows in set (0.00 sec)

mysql> lock tables score write;
#此时由于IS是意向共享锁与写锁互斥,从而导致阻塞,直至客户端一事务提交

四、行级锁

行级锁,每次操作锁住对应的行数据,锁定力度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。

在InnoDB中数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。

4.1、行级锁的分类

 4.1.1、行锁(Record Lock)

锁定单个行记录的锁,防止其他事务对此行进行update和delete。在RC和RR隔离级别下都支持。

InnoDB引擎实现了以下两种类型的行锁:

1、共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

2、排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。

当前锁类型\请求锁类型S(共享锁)X(排他锁)
S(共享锁)兼容冲突
X(排他锁)冲突冲突
SQL行锁类型说明
INSERT...排他锁自动加锁
UPDATE...排他锁自动加锁
DELETE...排他锁自动加锁
SELECT(正常)不加任何锁
SELECT ... LOCK IN SHARE MODE共享锁需要在SELECT之后手动加 LOCK IN SHARE MODE
SELECT ... FOR UPDATE排他锁需要在SELECT之后手动加 FOR UPDATE

默认情况下,InnoDB在REPEATABLE READ事务隔离级别运行,InnoDB使用next-key锁进行搜索和扫描索引,以防止幻读。

1、针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁。 

 2、InnoDB的行锁是针对索引加的锁不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁。

#客户端一:
 begin;
Query OK, 0 rows affected (0.00 sec)
 select * from student where id=1;
+----+--------+------------+
| id | name   | no         |
+----+--------+------------+
|  1 | 黛丽丝 | 2000100101 |
+----+--------+------------+
1 row in set (0.00 sec)
#此时还未加上锁
mysql> select * from student where id=1 lock in share mode;
+----+--------+------------+
| id | name   | no         |
+----+--------+------------+
|  1 | 黛丽丝 | 2000100101 |
+----+--------+------------+
1 row in set (0.00 sec)
#客户端二:
 select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
Empty set (0.00 sec)

mysql> select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
+---------------+-------------+------------+-----------+---------------+-----------+
| object_schema | object_name | index_name | lock_type | lock_mode     | lock_data |
+---------------+-------------+------------+-----------+---------------+-----------+
| test          | student     | NULL       | TABLE     | IS            | NULL      |
| test          | student     | PRIMARY    | RECORD    | S,REC_NOT_GAP | 1         |
+---------------+-------------+------------+-----------+---------------+-----------+
2 rows in set (0.00 sec)
mysql> update student set name='lily' where id=1;
#执行update语句会处于阻塞状态(共享锁与排他锁互斥)
#客户端一:
 begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update student set name='lily' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
#客户端二:
 begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update student set name='lily' where id=1;
#排他锁与排他锁互斥,处于阻塞状态,直至客户端一的事务提交
#客户端一:
 begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update student set name='lili' where name='黛丽丝';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
#客户端二:
 update student set name='lei' where id=2;
#因为name字段无索引,会对所有记录加锁

4.1.2、间隙锁(Gap Lock)

锁定索引记录间隙(不含该记录),确保索引间隙记录不变,防止其他事务在这个间隙进行insert,产生幻读。在RR级别下支持。

默认情况下,InnoDB在REPEATABLE READ 事务隔离级别运行,InnoDB使用next-key进行搜索和扫描索引,以防止幻读。

1、索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。

2、索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时Next-Key Lock退化为间隙锁。

3、索引上的范围查询(唯一索引)--会访问到不满足条件的第一个值为止。

#客户端一:
 select * from student;
+----+--------+------------+
| id | name   | no         |
+----+--------+------------+
|  1 | 黛丽丝 | 2000100101 |
|  2 | 谢逊   | 2000100102 |
|  3 | 殷天正 | 2000100103 |
|  4 | 韦一笑 | 2000100104 |
|  8 | lei    | 2000100108 |
+----+--------+------------+
5 rows in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update student set name ='lili' where id=5;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
#客户端二:
 select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
+---------------+-------------+------------+-----------+-----------+-----------+
| object_schema | object_name | index_name | lock_type | lock_mode | lock_data |
+---------------+-------------+------------+-----------+-----------+-----------+
| test          | student     | NULL       | TABLE     | IX        | NULL      |
| test          | student     | PRIMARY    | RECORD    | X,GAP     | 8         |
+---------------+-------------+------------+-----------+-----------+-----------+
2 rows in set (0.00 sec)
 begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into student values(7,'ruby',null);
#5和8之间存在间隙锁,插入数据会阻塞

注意:间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一个间隙上采用间隙锁。 

4.1.3、临键锁(Next-Key Lock)

行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下都、支持。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1950342.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apache Doris + Paimon 快速搭建指南|Lakehouse 使用手册(二)

湖仓一体(Data Lakehouse)融合了数据仓库的高性能、实时性以及数据湖的低成本、灵活性等优势,帮助用户更加便捷地满足各种数据处理分析的需求。在过去多个版本中,Apache Doris 持续加深与数据湖的融合,已演进出一套成熟…

java学习--枚举

问题引入: 当需要解决一个季节类的问题,我们使用学到的类与对象,创建一个季节的类然后添加构造器在进行分装就可以实现,但问题也随之而来,这样不仅可以有正常的四季还可以添加其他不存在的四季以及可以更改四季的属性…

ElasticSearch学习篇15_《检索技术核心20讲》进阶篇之TopK检索

背景 学习极客实践课程《检索技术核心20讲》https://time.geekbang.org/column/article/215243,文档形式记录笔记。 相关问题: ES全文检索是如何进行相关性打分的?ES中计算相关性得分的时机?如何加速TopK检索?三种思路 精准To…

广州数据中心机房服务器搬迁规划原则

数据中心机房搬迁,需要各个技术团队的紧密配合,制定详细周密的搬迁方案和实施流程,分批实施。作为华南地区主流的数据中心服务商,友力科技(广州)有限公司,专注数据中心机房服务器搬迁&#xff0…

[数据集][目标检测]蝗虫检测数据集VOC+YOLO格式1501张1类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):1501 标注数量(xml文件个数):1501 标注数量(txt文件个数):1501 标注…

Python服务器和客户端功能库之websockets使用详解

概要 WebSockets 是一种在单个 TCP 连接上进行全双工通信的协议,特别适用于需要低延迟和高频率数据传输的实时应用,例如在线游戏、聊天应用和实时数据流。websockets 是一个基于 asyncio 的 Python 库,旨在提供简单易用的 WebSockets 服务器…

Linux进程信号详解【下】

🌎 Linux进程信号详【下】 文章目录: Linux信号详解 核心转储 信号保存       信号的三种状态       信号集操作函数         sigset_t类型接口         sigprocmask接口         sigpending接口         …

会员信息管理系统-计算机毕业设计源码38258

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3开发技术 1.3.1 Spring Boot框架 1.3.2 Java语言 1.3.3 MySQL数据库 1.4论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 登录流程 2.2.2数据删除流程 2.3 系统功能分析 2.4 系统用例分析…

我的世界!

每位冒险家在《我的世界》中的出生点都各不相同, 有的出生在桦木森林,有的出生在草原, 还有的出生在临近海洋的沙滩。 这些环境叫做生物群系,也常被称为生态系统。 在《我的世界》中的不同生物群系具有不同的地域特色—— 不…

TDS传感器

目录 一、实物图 二、原理图 引脚定义 模块特性 三 、简介 四、注意事项 源文件下载 可访问底部联系方式也可前往电子校园网官网搜索关键词 关键词: TDS传感器 一、实物图 二、原理图 引脚定义 …

稳定、低成本、兼容性强的无线串口通信选择-适用于多场景的高性能无线串口模块

LoRa610Pro是思为无线的一款无线串口通讯模块采用了先进的LoRa扩频调制跳频技术,高效的接收灵敏度,具有超强的抗干扰性,还增强了通信的穿透能力和距离,相较于传统的FSK和GFSK产品有明显的优势。 高效的接收灵敏度 由于采用了LoRa…

学习记录day19——数据结构 查找算法

概念 在给定数据元素的某个值,在查找表中确定一个其关键字等于给定值的数据元素的操作,叫做查找 查找的分类 顺序查找:将待查找数据,进行全部遍历一遍,直到找到要查找的元素 折半查找:每次都去除一半的查找范围的查找方式&#x…

【C++高阶】哈希之美:探索位图与布隆过滤器的应用之旅

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C “ 登神长阶 ” 🤡往期回顾🤡:模拟实现unordered 的奥秘 🌹🌹期待您的关注 🌹🌹 ❀哈希应用 &#x1f4…

PyQt5 + selenium,自动票务工具,演唱会门票,学习使用

PyQt5 selenium;在damai工具的基础上加入了UI界面,并将应用做了打包工作,主要是方便不会/不想折腾环境的用户使用,抢票的核心代码来自由于原作者不再维护,自己修改了部分代码。 安装教程 解压安装包到任意位置&…

U盘损坏无法访问?解锁两大高效数据恢复秘籍

U盘损坏之痛:数据失联的困境 在日常生活中,U盘作为数据交换与存储的重要工具,其便捷性无可替代。然而,当U盘遭遇损坏,无法被计算机正常访问时,存储在其中的宝贵数据仿佛一夜之间变得遥不可及,这…

关键词查找【Boyer-Moore 算法】

1、【Boyer-Moore 算法】 【算法】哪种算法有分数复杂度?- BoyerMoore字符串匹配_哔哩哔哩_bilibili BM算法的精华就在于BM(text, pattern),也就是BM算法当不匹配的时候一次性可以跳过不止一个字符。即它不需要对被搜索的字符串中的字符进行逐一比较,而…

云盘高速检测的秘密:密封圈外观检测全解析!

密封圈是一种用于填塞、隔离或密封两个相互连接部件之间空隙的圆形密封装置。密封圈通常由橡胶、塑料、金属等材料制成,具有弹性并能在压力作用下填充间隙,防止液体、气体或固体物质泄漏。 密封圈可根据具体应用选择不同材料,如橡胶密封圈适…

UDP网口(3)逻辑组包(下)

文章目录 1.ARP应答验证2.UDP实现思路3.UDP接收验证4.UDP发送验证5.总结与思考6.传送门 1.ARP应答验证 创建一个ARP应答工程,当PC发出ARP请求的时候,手动按下板卡指定按键,将会响应ARP应答。以此验证phy芯片的配置正常,硬件链路正…

node+mysql实现(账户密码,阿里云短信验证,QQ邮箱注册登录,短信验证密码重置,邮箱密码重置)之注册,登录密码重置总篇

node+mysql实现账户登录 注意效果图项目插件代码参数说明短信验证模块邮箱验证模块注册方式登录方式密码重置前端页面部分登录页面账户登录页面(login.html)短信验证登录页面(smsLogin.html)邮箱登录页面(emailLogin.html)注册部分页面短信验证注册页面(register.html)邮…

Profinet 转 EtherCAT 主站网关

一、功能概述 1.1 设备简介 本产品是 PN(Profinet)和 ECAT(EtherCAT)网关,通过数据映射方式工作。 本产品在 PN 侧作为 PN IO 从站,接西门子 PLC 的 Profinet 口;在 ECAT 侧 做为 ECAT 主站,接 ECAT 从站,如伺服驱…