mysql中的锁理解

在这里插入图片描述

1.共享锁,排他锁,也叫读锁和写锁

共享锁(S锁)(读锁):事务在读取记录的时候获取共享锁,允许其它事务同时获取共享锁。
排他锁(X锁)(写锁):事务在修改记录的时候获取排他锁,只允许一个事务获取排他锁,其它事务会阻塞等待。
在这里插入图片描述
读锁和写锁是互斥的:
一个事务占用了某条记录的读锁,另一个事务想要获取写锁(可以获取读),需要等待读锁先释放。
一个事务占用了某条记录的写锁,另一个事务想要获取读或者写锁,需要等待写锁先释放。

2.表锁、行锁、页锁

================================================================
表锁:对整张表进行加锁,加锁之后其它事务无法对表进行任何读写操作。
表锁又分为:
1)表级别的S锁、X锁:

LOCK TABLES t READ; # 存储引擎会对表t加表级别的共享锁。共享锁也叫读锁或S锁(Share的缩写)
LOCK TABLES t WRITE; # 存储引擎会对表t加表级别的排他锁。排他锁也叫独占锁、写锁或X锁(exclusive的缩写)

一般不会使用,锁定整张表效率低。
在这里插入图片描述
给表加了读锁之后,自己可以读,自己不能写,而且不能操作其它的表,他人可读,他人写的话得等待。
给表加了写锁之后,自己可以读,自己可以写,而且不能操作其它的表,他人读需要等待,他人写也得等待。

2)意向锁:
意向锁的存在是为了协调行锁和表锁的关系。
假如业务上真用到了表锁,那么表锁和行锁之间肯定会存在冲突,当InnoDB加表锁的时候,如何判断表里面是否有行锁?难道一条条记录遍历去找?效率太低。所以有了意向锁。

意向锁分为:意向共享锁(IS)、意向排他锁(IX)
意向共享锁(IS): 当需要对表中的记录加共享锁的时候,先在表上加个意向共享锁,表示此时表内有共享锁。

例如:

事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table ... LOCK IN SHARE MODE;

意向排他锁(IX): 当需要对表中的记录加排他锁的时候,先在表上加个意向排他锁,表示此时表内有排他锁。

例如:

事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table ... FOR UPDATE;

这样一来,如果要加表锁,就不用去遍历了,直接根据意向锁进行判断。
如果要加表级别的S锁,如果表上没有IX,说明表中没有记录有排他锁,就可以直接上表级别的S锁。
如果要加表级别的X锁,如果表上没有IX和IS,说明表中的记录没有锁,就可以直接上表级别的X锁。

互斥性:
在这里插入图片描述

1.所有意向锁之间是相互兼容的。
2.只有表级别的共享锁和意向共享锁是兼容的,其它表级别的共享锁和排他锁和意向锁都是互斥的。
3.IX,IS是表级锁,不会和行级的X,S锁发生冲突。

例子:
事务A先获得了某一行的排他锁,并未提交:

BEGIN;
SELECT * FROM teacher WHERE id = 6 FOR UPDATE;

事务A获取了teacher表上的意向排他锁。事务A获取了id为6的数据行上的排他锁。
之后事务B想要获取teacher表上的共享锁。

BEGIN;
LOCK TABLES teacher READ;

事务B检测到事务A持有teacher表的意向排他锁。事务B对teacher表的加锁请求被阻塞(排斥)。
最后事务C也想获取teacher表中某一行的排他锁。

BEGIN;
SELECT * FROM teacher WHERE id = 5 FOR UPDATE;

事务C申请teacher表的意向排他锁。事务C检测到事务A持有teacher表的意向排他锁。
因为意向锁之间并不互斥,所以事务C获取到了teacher表的意向排他锁。因为id为5的数据行
上不存在任何排他锁,最终事务C成功获取到了该数据行上的排他锁。

3)元数据锁:
当对一个表做增删改查操作的时候,加 MDL读锁;当要对表做结构变更操作的时候,加 MDL 写锁。

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

4)自增锁:
用于自增列插入数据时使用。在插入数据的时候,会在表上加上auto-inc lock,然后为自增列分配递增的值在语句插入结束之后,再释放auto-inc lock。

自增锁是在语句插入结束之后才释放锁,效率比较低,所以后面弄了个互斥量(mutex)来进行自增减的累加,互斥量是在语句插入的时候,获取递增值之后,就可以释放锁,所以性能更好。

mysql有参数innodb_autoinc_lock_mode来控制使用自增锁还是互斥量,有3个值:
0:只使用自增锁
1:默认值,对于插入前已经知道行数的插入,用互斥量;插入前不知道具体插入行数的插入,用自增锁。这种最安全,statement格式的binlog也是安全的。
2: 只用互斥量

================================================================
行锁:仅对特定的行进行加锁,允许其它事务并发访问其它不同的行。
行锁又分为:
1)记录锁(record locks)
锁定当前的记录。对某条记录执行增删改的时候,会在这条记录上加记录锁。

记录锁是有S锁和X锁之分的,称之为 S型记录锁X型记录锁

  • 当一个事务获取了一条记录的S型记录锁后,其他事务也可以继续获取该记录的S型记录锁,但不可以继续获取X型记录锁;
  • 当一个事务获取了一条记录的X型记录锁后,其他事务既不可以继续获取该记录的S型记录锁,也不可以继续获取X型记录锁。

2)间隙锁(Gap locks)
锁定的是一个间隙,防止其它事务插入数据到间隙中。
间隙锁之间不会冲突,也就是说不同的事务可以对同一个间隙同时加锁。因为间隙锁的目的是一致的,都是为了防止其它事务插入数据到间隙中。

3)临键锁(next-key locks)
临键锁 = 记录锁 + 间隙锁
除了锁定间隙,还锁定某条记录。

例如下面的语句:会产生临键锁,锁定id为8的这条记录,还锁定3~8的区间。锁定的范围是(3, 8].

begin;
select * from student where id <=8 and id > 3 for update;

4)插入意向锁
插入意向锁,它是一类间隙锁,但是它不是锁定间隙,而是等待间隙。

如果一个间隙上被加了间隙锁,这时候来了一个新的事务,想要往这个间隙上插入数据,那么这个事务会被间隙锁给阻塞,这时候新事务会生成一个插入意向锁,表示等待这个间隙锁的释放。

插入意向锁之间不会相互阻塞,因为他们的目的相同,都是等待这个间隙被释放。

3.页锁

================================================================
页锁:
页锁就是在 页的粒度 上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有多个行记录。当我 们使用页锁的时候,会出现数据浪费的现象,但这样的浪费最多也就是一个页上的数据行。页锁的开销介于表锁和行锁之间,会出现死锁。锁定粒度介于表锁和行锁之间,并发度一般。

4.悲观锁,乐观锁

================================================================
乐观锁:
假设不会发生冲突,因此操作数据时不会加锁,只会在更新数据的时候做版本
校验,看数据有没有被别的事务修改,如果修改了,则拒绝当前事务的修改。
使用版本或者时间戳实现,一般是在数据库里面加一个版本或者时间戳字段。联想到CAS操作。适用于读多写少的场景。

悲观锁:
假设会发生冲突,操作数据之前都会对数据进行加锁,使其它的事务无法访问。
数据库提供的锁实现,例如表锁,行锁等。适用于写操作频繁的场景。

5.死锁

================================================================
死锁:
发生死锁怎么解决?
1.自动检测+锁等待时间+回滚
mysql会自动检测是否存在死锁,如果存在的话,会对一个事务进行回滚,并且释放该事务占有的锁;
有锁等待时间,如果一个事务获取锁的等待时间超过该阈值的时候,则回滚该事务,并且释放该事务占有的锁。
2.手动分析,kill发生死锁的事务的线程
show engine innodb status命令:分析死锁日志,找到发生死锁的事务以及线程id,然后kill;
通过查询information scheme,找到发生死锁的事务以及线程id,然后kill

避免死锁的手段:
1.避免长事务。长事务长时间占有锁,发生死锁的概率高。
2.降低事务隔离级别。例如使用读已提交隔离级别,比可重复读少了间隙锁,临建锁,可以减少死锁发生的概率。
3.合理建立索引。提高索引命中率,命中索引可以减少要处理的行,这样锁定的行也少,就可以减少死锁发生的概率。
4.开启死锁检测,适当调整锁等待时间。

死锁例子1:
在这里插入图片描述
在这里插入图片描述
死锁例子2:
在这里插入图片描述

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

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

相关文章

聚水潭数据集成到MySQL的技术实操与解决方案

聚水潭数据集成到MySQL的技术案例分享 在现代企业的数据管理过程中&#xff0c;如何高效、可靠地实现不同系统之间的数据对接是一个关键问题。本案例将聚焦于“聚水谭-仓库查询单-->BI邦盈-仓库表”的数据集成方案&#xff0c;详细探讨如何通过轻易云数据集成平台&#xff…

鸿蒙系统的优势 不足以及兼容性与未来发展前景分析

2024 年 10 月 22 日&#xff1a;华为正式发布原生鸿蒙操作系统 HarmonyOS next&#xff0c;并正式命名为 HarmonyOS 5&#xff0c;这是鸿蒙系统史上最大的升级&#xff0c;实现了国产操作系统从底层架构到应用生态的全面自主可控。 鸿蒙系统与安卓、iOS 相比&#xff0c;具有…

C++:哈希表

目录 哈希的概念 直接定址法 哈希冲突 负载因子 哈希函数 除法散列法/除留余数法 乘法散列法 处理哈希冲突 开放定址法 线性探测 二次探测 双重散列 链地址法 哈希表的实现 哈希表的结构 闭散列&#xff08;开放定址法&#xff09; 结构 插入 查找 删除 …

Java系统学习笔记

计算机知识 CMD 环境变量 想要在任意目录下都可以打开指定的软件&#xff0c;就可以把软件的路径配置到环境变量中。 JDK JDK安装目录中 javac 是JDK提供的一个工具&#xff0c;可以通过这个工具&#xff0c;把java文件编译成class文件 java 也是JDK提供的一个工具&#xf…

C语言部分输入输出(printf函数与scanf函数,getchar与putchar详解,使用Linux ubuntu)

1.输入输出 1.1.按格式输入输出 printf 可以在man手册中查看 int printf(const char *format, ...); printf:函数名(参数)int:函数的返回值 功能&#xff1a;按格式在终端输出 参数&#xff1a;多参 返回值&#xff1a;输出字符个数 格式&#xff1a; %d int %c char…

WPF+MVVM案例实战(十五)- 实现一个下拉式菜单(上)

文章目录 1 案例效果2、图标资源下载3、功能实现1.文件创建2、菜单原理分析3、一级菜单两种样式实现1、一级菜单无子项样式实现2、一级菜单有子项样式实现 4、总结 1 案例效果 提示 2、图标资源下载 从阿里矢量素材官网下载需要的菜单图片&#xff0c;如下所示&#xff1a; …

Python 从入门到实战43(Pandas数据结构)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;可以熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们学习了NumPy数组操作的相关基础知识。今天学习一下pa…

电商行业的流程革命:创建SOP的最佳实践

在电商行业&#xff0c;随着业务规模的扩大和市场环境的快速变化&#xff0c;创建和遵循标准化操作程序&#xff08;SOP&#xff09;变得尤为重要。SOP不仅能够确保业务流程的一致性和高效性&#xff0c;还能帮助企业快速适应市场变化&#xff0c;提高服务质量。本文将探讨电商…

服务器宝塔安装哪吒监控

哪吒文档地址&#xff1a;https://nezha.wiki/guide/dashboard.html 一、准备工作 OAuth : 我使用的gitee&#xff0c;github偶尔无法访问&#xff0c;不是很方便。第一次用了极狐GitLab&#xff0c;没注意&#xff0c;结果是使用90天&#xff0c;90天后gg了&#xff0c;无法登…

计算机网络(Ⅶ)Web and HTTP

一些术语&#xff1a; Web页&#xff1a;由一些对象组成 对象可以是HTML文件&#xff0c;JPEG图像&#xff0c;Java小程序&#xff0c;声音剪辑文件等 Web页含有一个基本的HTML文件&#xff0c;该基本HTML文件又包含若干对象的引用&#xff08;链接&#xff09; 通过URL对每个对…

【ChatGPT】搜索趋势分析

【ChatGPT】搜索趋势分析 为了分析 ChatGPT 在过去一年的流行趋势&#xff0c;我们可以查看 Google Trends 的数据 安装依赖pytrends pip install pytrends运行以下 Python 脚本 import pandas as pd import matplotlib.pyplot as plt from pytrends.request import TrendR…

「MinIO快速入门」

官网&#xff1a;MinIO | S3 Compatible Storage for AI 中文&#xff1a;http://minio.org.cn/ MinIO 开始 MinIO 是一款高性能、开源的对象存储服务器。 一、主要特点 高性能 MinIO 采用了分布式架构&#xff0c;能够高效地处理大量数据的存储和访问请求。它针对多核处理…

C++ | Leetcode C++题解之第516题最长回文子序列

题目&#xff1a; 题解&#xff1a; class Solution { public:int longestPalindromeSubseq(string s) {int n s.length();vector<vector<int>> dp(n, vector<int>(n));for (int i n - 1; i > 0; i--) {dp[i][i] 1;char c1 s[i];for (int j i 1; j…

2024年,Rust开发语言,现在怎么样了?

Rust开发语言有着一些其他语言明显的优势&#xff0c;但也充满着争议&#xff0c;难上手、学习陡峭等。 Rust 是由 Mozilla 主导开发的通用、编译型编程语言&#xff0c;2010年首次公开。 在 Stack Overflow 的年度开发者调查报告中&#xff0c;Rust 连续多年被评为“最受喜爱…

【C/C++】模拟实现strlen

学习目标&#xff1a; 使用代码模拟实现strlen。 逻辑&#xff1a; strlen 需要输入一个字符串数组类型的变量&#xff0c;并且返回一个整型类型的数据。strlen 需要计算字符串数组有多少个元素。 代码1&#xff1a;使用计数器 #define _CRT_SECURE_NO_WARNINGS 1 #include&…

LLM | 论文精读 | 地学视觉语言大模型:Towards Vision-Language Geo-Foundation Model: A Survey

论文标题&#xff1a;Towards Vision-Language Geo-Foundation Model: A Survey 作者&#xff1a;Yue Zhou, Litong Feng, Yiping Ke, Xue Jiang, Junchi Yan, Xue Yang, Wayne Zhang 期刊&#xff1a;未提供 DOI&#xff1a;https://arxiv.org/abs/2406.09385 email&#x…

LC:贪心题解

文章目录 376. 摆动序列 376. 摆动序列 题目链接&#xff1a;https://leetcode.cn/problems/wiggle-subsequence/description/ 这个题目自己首先想到的是动态规划解题&#xff0c;贪心解法真的非常妙&#xff0c;参考下面题解&#xff1a;https://leetcode.cn/problems/wiggle…

淘宝商品评价API的获取与应用

在当今数字化时代&#xff0c;电商平台如淘宝已成为消费者购物的重要渠道。对于商家和开发者而言&#xff0c;如何高效地获取并利用商品评价数据&#xff0c;成为了提升产品竞争力和优化用户体验的关键。本文将详细介绍如何使用淘宝开放平台提供的商品评论API来获取这些宝贵的数…

类和对象(中)—— 类的六个默认成员函数

目录 1.类中的默认成员函数 2.构造函数 为什么要有构造函数 什么是构造函数 构造函数做了什么 默认生成的构造函数功能的分析 C11的补救 什么时候自己写构造函数 3.析构函数 为什么要有析构函数 什么是析构函数 析构函数做了什么 默认生成的析构函数功能的分析 什…

Java Executor ScheduledExecutorService 源码

前言 相关系列 《Java & Executor & 目录》《Java & Executor & ScheduledExecutorService & 源码》《Java & Executor & ScheduledExecutorService & 总结》《Java & Executor & ScheduledExecutorService & 问题》 涉及内容 …