MySQL进阶知识:锁

news2024/10/5 14:06:01

目录

前言

全局锁

表级锁

表锁

元数据锁(MDL)

意向锁

行级锁

行锁

行锁演示

间隙锁/临界锁

演示


前言

MySQL中的锁,按照锁的粒度分,分为以下三类

  • 全局锁:锁定数据库中的所有表。
  • 表级锁:每次操作锁住整张表。
  • 行级锁:每次操作锁住对应的行数据。

全局锁

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

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

具体语句为

-- 添加全局锁
flush tables with read lock;
-- 开始备份
mysqldump -r用户名 -p密码 数据库名>保存文件名称.sql
-- 解锁
unlock tables;

全局锁特点

  • 如果没有做主从分离,那么在备份期间不能执行更新操作,业务基本停摆。
  • 做了主从分离后可以选择在从库上备份,在备份期间从库不能执行主库同步过来的二进制日志(binlog),导致主从延迟。

但也存在不阻塞而是基于快照就可以实现备份的语句

mysqldump --single-transaction -u用户名 -p密码 数据库名>保存的文件名称.sql

表级锁

每次操作所著整张表,锁定粒度大,发生所冲突的概率最高,并发度最低。

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

  • 表锁
  • 元数据锁
  • 意向锁

表锁

对于表锁又可以分为两类

  • 表共享读锁(read lock)
  • 表独占写锁(write lock)

基本语法

-- 加锁
lock tables 表名… read/write;
-- 释放锁
unlock tables / 客户端断开连接

读锁特点

  • 自身以及其他客户端的读操作可以正常执行。
  • 自身执行写操作会报错,其他客户端执行写操作会阻塞。

写锁特点

  • 自身既可以读也可以写。
  • 其他客户端不能读也不能写,会直接阻塞。

元数据锁(MDL)

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

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

对应SQL

锁类型

select

SHARED_READ

insert、update、delete

SHARED_WRITE

alter table

EXCLUSIVE

共享读与共享写都属于共享锁,他们两个互相兼容并于排他锁互斥。

查看数据库中元数据锁信息

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

意向锁

意向锁是为了避免DML数据库操作语句在执行过程中,出现行锁与表锁的冲突,通过意向锁可以在创建表锁时不需要去检查每行数据是否有行锁,从而减少表锁检查所带来的性能消耗。

没有使用意向锁之前,客户端A给表中加了行锁,客户端B要给表加表锁,过程如下:

首先客户端A开启一个事务,在事务中对表中的数据进行增删改查,在执行增删改时,会对表中的这些数据加一个行锁,这时客户端B想在表中添加一个表锁,客户端B在添加表锁前,先会去检查当前表中每一行数据是否有行锁,如果没有则会去添加表锁。

也就是说,不使用意向锁的话。客户端向表加锁需要遍历整张表,当表数据量很大时,效率很低。

当有了意向锁之后,客户端A给表中加了行锁,客户端B要给表加表锁,过程如下:

首先客户端A开启一个事务,在事务中对表的数据进行增删改查,对数据添加行锁的同时,又会给表添加一个意向锁,这时客户端B想要在表中添加一个表锁,客户端B就会根据客户端A加的意向锁来判断是否可以成功添加表锁,并且不会再逐行检查数据是否有行锁,效率得到大幅度提升。

简单来说,意向锁相当于一个声明,而不是一个真正的锁,根据这个声明,添加表锁时就有了参考依据,因此不需要逐行判断是否可以添加表锁,从而避免了行锁与表锁产生的冲突。

意向锁的分类

  • 意向共享锁(IS):平常的select语句不会自定添加意向共享锁,需要在select后面加上lock in share mode参数,才能为表建立意向共享锁。
  • 意向排它锁(IX):insert、update、delete、select…for update等语句,都会字段添加一个意向排它锁。

意向共享锁可以与表锁中表共享读锁(read)兼容,但是与表锁中的表独占写锁(write)互斥,当表中存在一个意向共享锁时,我们可以为表正常设置一个读锁,但是不能设置为写锁,当为表设置写锁时,就会处于阻塞状态,只有当事务提交后,写锁才能正常执行。

意向排它锁既与表共享读锁排斥又与表独占写锁排斥,当表中有意向排它锁时,即不可以设置表读锁,也不可以设置为表写锁。

当事务提交后,意向共享锁、意向排它锁都自己释放锁(说是释放,其实可以理解为将标记清空),被阻塞的操作此时才能被执行。

行级锁

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

InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。对于行级锁,主要分为以下三类:

行锁(Record Lock):锁定单个行记录的锁,防止其他事务对此行进行update和delete。在读已提交、可重复读隔离级别下都支持

间隙锁(Gap Lock):锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在可重复读隔离级别下都支持

临键锁(Next-Key Lock):行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在可重复读隔离级别下支持。

行锁

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

  • 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
  • 排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。

锁兼容情况如下

共享锁

排他锁

共享锁

兼容

互斥

排他锁

互斥

互斥

加锁情况如下

SQL

行锁类型

说明

insert

排他锁

自动加锁

update

排他锁

自动加锁

delete

排他锁

自动加锁

select

不加锁

select……lock in share mode

共享锁

需要手动在select之后添加local in share mode

select ……for update

排他锁

需要手动在select之后加for update

行锁演示

默认情况下,lnnoDB在可重复读事务隔离级别运行,InnoDB使用临键锁进行搜索和索引扫描,以防止幻读。

  • 针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁。
  • InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁

查看行锁情况的SQL语句

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks ;

现在存在一个主键为id的user表,username没有创建索引

在一个客户端开启事务,并进行查询。另一个客户端查看行锁数据

此时我们可以看到,MySQL没有对select语句进行加锁。接下来我们手动对select语句加锁

由于行锁中的共享锁是互相兼容的,因此我也可以再另一个客户端进行select语句,此时锁记录表中出现两条锁记录。

当事务提交后,事务涉及到锁也会释放

接下来我们测试update语句

接下来测试对非索引的字段进行条件判断,观察添加的是什么锁

因此我们可以知道,当对没有索引的字段进行条件查询时,行级锁会升级为表锁。

间隙锁/临界锁

默认情况下,InnoDB在可重复读事务隔离级别运行,lnnoDB使用间隙锁锁进行搜索和索引扫描,以防止幻读。

  1. 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。
  2. 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,临键锁退化为间隙锁
  3. 索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止。

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

演示

展示第一种情况,给不存在的记录加锁。

加下来展示第二种情况,我添加了一个age字段,并创建了普通索引

另一个客户端插入对应被锁住的范围时会阻塞,而插入其他范围可以正常执行。

接下来展示第三种情况,对唯一索引的范围查找。

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

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

相关文章

Git提示 Connection closed by remote host

问题如下图: 解决: 删除./ssh目录下的config文件,如下图config文件是新增的 原因:不知道什么原因,连接外网后突然断开或导致自动增加config文件。

样品实验Fortegra202环氧树脂增韧剂TDS说明书

样品实验Fortegra202环氧树脂增韧剂TDS说明书 150克/瓶

微信小程序input type=nickname不能触发隐私政策?小程序隐私协议开发指南之nickname权限篇

小程序隐私协议开发指南之nickname权限篇 涉及处理用户个人信息的小程序开发者,需通过弹窗等明显方式提示用户阅读隐私政策等收集使用规则。 为规范开发者的用户个人信息处理行为,保障用户合法权益,微信要求开发者主动同步微信当前用户已阅读并同意小程序的隐私政策等收集使…

网络运维与网络安全 学习笔记2023.11.30

网络运维与网络安全 学习笔记 第三十一天 今日目标 实现AP自动注册、配置WLAN业务参数、无线终端通过wifi互访 实现AP自动注册 项目背景 企业内网的大量AP已经通过DHCP的方式获得IP地址 为了实现后期大量AP的统一管理,希望通过AC实现集中控制 在AC设备上&#…

思维跳动:抖店商品怎么设置拼团?

在抖店上销售商品时,设置拼团活动是一种促销策略,可以吸引更多用户参与购买,并增加销量。下面将介绍一些方法和步骤,帮助你在抖店中设置商品的拼团活动。 一、抖店商品怎么设置拼团? 首先,选择适合的商品进…

Java项目学生管理系统二查询所有

学生管理 近年来,Java作为一门广泛应用于后端开发的编程语言,具备了广泛的应用领域和丰富的开发资源。在前几天的博客中,我们探讨了如何搭建前后端环境,为接下来的开发工作打下了坚实的基础。今天,我们将进一步扩展我…

性能优化之FPS

如果每秒钟有60帧,那么每一帧的时间就是总时间(1秒)除以总帧数(60帧): 所以:每帧时间1000 毫秒/60 帧≈16.67 毫秒 因此,如果每秒有60帧,那么每一帧大约需要16.67毫秒来…

华为云之一键安装宝塔面板

华为云之一键安装宝塔面板 一、本次实践介绍1.1 实践环境简介1.2 本次实践目的 二、宝塔面板介绍三、环境准备工作3.1 预置实验环境3.2 查看环境信息3.3 登录华为云3.4 查看弹性云服务器状态3.5 ssh登录弹性云服务器3.6 查看操作系统版本 四、安装宝塔面板4.1 一键部署宝塔面板…

c MJPG(1)

.读取量化表&#xff0c;全局参数&#xff0c;霍夫曼表&#xff0c;恢复表编码&#xff0c;现在只是实现思路。 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sy…

J签证、移民、绿卡都是怎么回事?

随着全球化的不断推进&#xff0c;越来越多的人开始关注国际间的移民与签证政策&#xff0c;其中包括J签证、移民以及绿卡的申请问题。本文将简要介绍J签证、移民绿卡的基本概念&#xff0c;并提供相关申请的一般步骤&#xff0c;以帮助读者更好地了解这些程序。 首先&#xff…

网站优化SEO文章采集组合方法

为了在激烈的网络竞争中脱颖而出&#xff0c;SEO专业人士不断寻求创新的方法和技术。其中&#xff0c;SEO文章采集后重组是一项备受关注的技术&#xff0c;通过巧妙地整合和重新组织已有的信息&#xff0c;以提升网站在搜索引擎中的排名和曝光度。 SEO文章采集是这一技术的第一…

老师上公开课的好处

作为一名老师&#xff0c;公开课是不可避免的&#xff0c;也是提升自己教学水平的重要途径。那么&#xff0c;老师上公开课到底有哪些好处呢&#xff1f;以下几条&#xff0c;也许可以为你解开疑惑。 提升老师的教学水平。在公开课上&#xff0c;老师需要将平时的教学经验、方法…

docker-compose;私有镜像仓库harbor搭建;镜像推送到私有仓库harbor

docker-compose&#xff1b;私有镜像仓库harbor搭建&#xff1b;镜像推送到私有仓库harbor 文章目录 docker-compose&#xff1b;私有镜像仓库harbor搭建&#xff1b;镜像推送到私有仓库harbordocker-compose私有镜像仓库harbor搭建镜像推送到私有仓库harbor docker-compose D…

Elk+Filebeat+Kafka实现日志收集

ElkFilebeatKafka实现日志收集(本机nginx) 部署Zookeeper 1.实验组件 #准备3台服务器做Zookeeper集群 20.0.0.10 20.0.0.20 20.0.0.30 2.安装前准备 #关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 0#安装JDK yum install -y java-1.8.0-o…

井盖位移报警器安装,智能化井盖厂家推荐

当井盖发生位移或倾斜时&#xff0c;通常会引起所处道路的安全隐患&#xff0c;给过往的车辆和行人带来许多潜在的危险。为了避免潜在的安全事故频繁出现&#xff0c;及时发现并处理井盖位移或倾斜才能更好的保障人民的安全。因此安装井盖位移报警器是满足政府和市民需求的。 单…

抖音本地生活服务商申请条件

抖音的本地生活服务商目前有两种&#xff0c;一种是可以做全国的服务商&#xff0c;我们一般叫抖音本地生活服务商&#xff0c;一种是区域优待服务商&#xff0c;也就是后面出来的服务商&#xff0c;这两种服务商的申请方式大同小异。 相同的地方就是都需要给平台交保证金。抖…

用java制作飞翔的小鸟

第一步是创建项目 项目名自拟 第二步创建个包名 来规范class 再创建一个包 来存储照片 如下&#xff1a; package game; import java.awt.*; import javax.swing.*; import javax.imageio.ImageIO;public class Bird {Image image;int x,y;int width,height;int size;doubl…

计算机体系结构----指令系统(二)

本文仅供学习&#xff0c;不作任何商业用途&#xff0c;严禁转载。绝大部分资料来自----计算机系统结构教程(第二版)张晨曦等 计算机体系结构----指令系统&#xff08;二&#xff09; 2.1 指令系统结构的分类2.2 寻址方式2.3 MIPS 指令系统结构2.3.1 MIPS的寄存器2.3.2 MIPS的…

虚拟化CentOS7分区大小调整+磁盘扩容=新分区

一、适应场景 1、虚拟化环境ESXI6.7下的虚拟服务器&#xff0c;使用一段时间后&#xff0c;把空闲的存储空间腾出来&#xff0c;给新的分区使用。 2、Linux的版本为CentOS7 3、本例为部署minio存储业务做准备 4、虚拟化存储扩容 二、配置过程 调整分区大小&#xff0c;为min…

Go语言 值传递

官方说法&#xff0c;Go中只有值传递&#xff0c;没有引用传递 而Go语言中的一些让你觉得它是引用传递的原因&#xff0c;是因为Go语言有值类型和引用类型&#xff0c;但是它们都是值传递。 值类型 有int、float、bool、string、array、sturct等 引用类型有slice&#xff0c…