MySQL锁

MySQL锁

    • 事务
      • 事务的隔离级别
      • 脏读,不可重复读,幻读
    • 表锁与行锁
      • 表锁
        • 测试准备
        • 测试
      • 行锁
        • 测试
    • 读锁与写锁
      • 读锁(共享锁)
        • 测试
      • 写锁(排他锁)
        • 测试
    • 元数据锁
      • 表级元数据锁
      • 表级MDL**(Metadata Lock)**
        • 测试
    • 锁表
      • 如果解决锁表呢?

聊到MySQL锁的一些机制的时候,我们会想到一写相关的知识。

  • 事务
  • 事务隔离级别
  • 表锁,行锁
  • 读锁(共享锁),写锁(排他锁)
  • 元数据锁(DDL或MDL造成的锁)
  • 锁表

事务

通常我们需要一组操作,同时成功,或者同时失败的时候需要通过事务来进行保证。

从而保证原子性,一致性,隔离性,和持久性。

事务的隔离级别

  • Read Uncommitted 读未提交(最低) 允许一个事务读取另外一个事务未提交的数据,可能造成脏读,不可重复读,幻读。
  • Read Committed 读已提交 允许一个事务读取另外一个事务已提交的数据,可以防止脏读。但可能出现不可重复读,幻读。
  • Repeatable Read 可重复读 保证同一个事务内,多次读取相同数据的结果是一致的,可以防止脏读和不可重复读。但会出现幻读。
  • Serializable 串行(最高) 确保所有事务按照严格的顺序执行,避免了幻读,不可重复度,和幻读,但是会牺牲并发性能。

脏读,不可重复读,幻读

  • 脏读:读取一个事务还未提交的数据,作为了当时的数据,但是如果这个事务回滚了,就会导致当时的那个数据是脏的。
  • 不可重复读:读取另外一个事务已提交的数据,如果一个事务内有两次读取这个数据去计算,那么这两个计算结果不通。重复读取的数据不一致的问题。
  • 幻读:同一个事务类读取相同的数据结果是一致的。那么如果在一个事务内需要读取两次这个数据,那么在第二次结果读取前,我们的数据发生了改变。尽管我们在事务内的数据读取的都是开启事务时的数据,但是实际上数据库的数据就不一致了。那么就会造成幻读的问题。

表锁与行锁

InnoDB 是支持 表锁与行锁的。

MyIsam 只支持行锁。

表锁

用于锁定整个表,阻止其他会话对整个表进行访问

测试准备

创建一个InnoDB引擎的表

drop table if exists InnoDBTest;
CREATE TABLE `InnoDBTest` (`id` int(11) NOT NULL AUTO_INCREMENT,`a` int(11) NOT NULL,`b` int(11) NOT NULL,PRIMARY KEY (`id`),KEY `idx_a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into InnoDBTest(a,b) values(1,1),(2,2);

测试

# 开启session1
BEGIN;# 使用写锁select * from InnoDBTest  FOR UPDATE;
# 重新开始一个查询窗口后# 开启session2
BEGIN;# 使用写锁select * from InnoDBTest  FOR UPDATE;
# 会发现 session2的selet会被阻塞住,
# 当我们的session1 执行commit后,session2的select才会执行完成。

行锁

用于锁定表中的某行或者某些行(范围),允许其他事务方法未被锁定的行

测试

# 开启session1
BEGIN;# 使用写锁select * from InnoDBTest where a = 1  FOR UPDATE;
# 重新开始一个查询窗口后# 开启session2
BEGIN;# 使用写锁select * from InnoDBTest where a = 1   FOR UPDATE;# 会发现 session2的selet会被阻塞住,# 开启session3
BEGIN;# 使用写锁select * from InnoDBTest where a = 2   FOR UPDATE;
# 会发现可以session3的select会执行成功,不会等待session1
# 可以理解会 where a = 1  给a=1的记录加了行锁,只要不访问带有锁的行就能不被阻塞。

读锁与写锁

读锁(共享锁)

普通的select通过加上关键字LOCK IN SHARE MODE可以使对应的行或者表获取到锁。

允许多个事务同时读取一份数据,不会互相干扰。

但读锁会阻止其他事务获得写锁,但不会阻止其他事务获得写锁。

多个事务可以同时获取读锁,称之为共享锁

测试

# 开启session1
BEGIN;# 使用读锁select * from InnoDBTest where a = 1  LOCK IN SHARE MODE;# 重新开始一个查询窗口后# 开启session2
BEGIN;# 使用读锁select * from InnoDBTest where a = 1  LOCK IN SHARE MODE;# 会发现session2能正常获取数据# 开启session3
BEGIN;# 使用写锁update InnoDBTest set b = 3 where a = 1;
# session3会被阻塞因为update where a=1 需要获取a=1的记录当时此时,session1给a=1的记录上了读锁,所以session3会阻塞,只到 session1完成。# 开启session4
BEGIN;# 使用写锁update InnoDBTest set b = 3 where a = 2;# 会发现session4不会阻塞,因为在innodb中支持行锁,a=2的记录没有被上读锁。

写锁(排他锁)

  • 写锁用于防止青铜器会话在同一时间内对相同数据进行读或者写操作。
  • 只允许一个事务对数据进行写操作,其他事务不能同时读取或写入。这里也称为排他锁
  • 写锁会阻塞其他写锁和读锁,以确保数据的一致性。

通常我们的update、insert、delete都是会获取写锁的。但是普通的select并没有获取锁,需要为其加上 for update才能使普通的select拿到写锁

测试

# 开启session1
BEGIN;# 使用读锁select * from InnoDBTest for update;# 开启session2
BEGIN;select * from InnoDBTest;# 普通读不会阻塞# 开启session3
BEGIN;# 使用读锁select * from InnoDBTest LOCK IN SHARE MODE;# 需要获取InnoDBTest的读锁所以会阻塞# 开启session4
BEGIN;# 使用写锁insert into  InnoDBTest value(3,3);# session4执行insert 需要获取写锁,所以 session3会阻塞

元数据锁

表级元数据锁

当一个会话正在修改表结果(新增列,删除列(DDL)等)时,会持有一个表级的元数据锁阻止其他会话对相同的表结果进修改

表级MDL**(Metadata Lock)**

当我们的表被锁住时,我们通过DDL语句去操作表结果的时候,就会触发表级MDL,触发后不管是读锁,写锁,或者是普通的select都会被阻塞

测试

# 开启session1
BEGIN;# 获取写锁delete from InnoDBTest;# 开启session2
alter table InnoDBTest add COLUMN c VARCHAR(50);
# 因为session1把表的写锁给获取了,所以当我们执行DDL语句的时候,就被阻塞了,需要等待session1执行完成,但是,alter table 又需要获取元数据锁,所以,之后只要操作InnoDBTest的操作都会阻塞,需要等待 seesion1与session2执行完成。# 开启session3
select * from InnoDBTest# 普通的select阻塞了。

这里如果session1一直不commit这里就是一个死锁。也就导致了锁表。

如果验证呢?请看锁表章节

锁表

  1. 用于查看当前打开的表信息
SHOW OPEN TABLES WHERE In_use >0;

In_use > 0 代表至少被一个会话使用的表才显示。

image-20230914003730273

2.查看当前正在执行的所有数据库连接和查询的详细信息

SHOW FULL PROCESSLIST;

列描述

  • Id:连接或线程的唯一标识符。
  • User:执行查询的MySQL用户。
  • Host:连接的主机名或IP地址。
  • db:当前连接的数据库(如果有)。
  • Command:正在执行的命令类型,例如 SELECT、INSERT、UPDATE、DELETE 等。
  • Time:该查询执行的时间(以秒为单位)。
  • State:查询的当前状态,例如正在锁定、发送数据等。
  • Info:包含有关查询的更多信息,如查询文本。

可以看见我们这条sql导致了锁表。也就是我们的session使得session2也阻塞了,从而导致table metadata lock一直被占用。

image-20230914004223888

所以,线上环境在高峰期的时候一定要避免去执行DDL,这样会导致非常严重的问题,类似与,数据源连接池全部都阻塞了。导致程序挂掉。有幸遇到过😂

如果解决锁表呢?

如果session1能够被关闭还好了,但是如果通过session1关不掉,不是我们自己的程序去操作的那怎么办?

刚才通过SHOW FULL PROCESSLIST找到了是个主机,及那个sql使得我们的表锁定了。找到该行的**ID**

# 通过线程ID来终止指定的线程
KILL <process_id>;
# 终止对应的进程后
kill 21;SHOW FULL PROCESSLIST;
# 也没有看到其他的锁表信息了。# 普通select 可以正常查询了
select * from InnoDBTest

今天遇到一个问题就是 有一个truncate table 在执行。一直没有导致线上服务查询基本信息的时候出现大量卡住的问题,导致服务不可用。记录下问题及解决方案,及其他知识点。

以上没有解决的话!

请直接祭出最终办法:万能重启!!!😂

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

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

相关文章

十大排序算法及Java中的排序算法

文章目录 一、简介二、时间复杂度三、非线性时间比较类排序冒泡排序&#xff08;Bubble Sort&#xff09;排序过程代码实现步骤拆解演示复杂度 选择排序&#xff08;Selection Sort&#xff09;排序过程代码实现步骤拆解演示复杂度 插入排序&#xff08;Insertion Sort&#xf…

【Linux常用命令】

一、防火墙相关 1、查看防火墙状态 systemctl status flrewalld2、如果防火墙是开启状态的&#xff0c;需要关闭 systemctl stop firewalld3、永久行关闭操作&#xff08;禁止开机自启动&#xff09; 因为防火默认是开启状态的&#xff0c;如果只是手动关闭&#xff0c;先次…

【Java】抽奖系统———保姆学习教程

目录 一、抽奖系统介绍 二、代码实现 1、随机生成中奖号码 1.1、中奖号码createNumber方法 1.2、控制判断contains方法 2、用户输入中奖号码 3、判断中奖情况 3.1、判断奖项isWin方法 三、完整代码 一、抽奖系统介绍 抽奖的号码由6个红色球号码和1个蓝色球号码组成。红色…

智慧园区:AI边缘计算技术与视频监控汇聚平台打造智慧园区解决方案

一、行业趋势与背景 智慧园区是现代城市发展的重要组成部分&#xff0c;通过智能化技术提高园区的运营效率、降低成本、增强环境可持续性等具有重要作用。在智慧园区中&#xff0c;人工智能和视频汇聚技术是重要的前置技术。人工智能技术可以实现对数据的智能化处理和分析&…

时序数据库 TimescaleDB 安装与使用

TimescaleDB 是一个时间序列数据库&#xff0c;建立在 PostgreSQL 之上。然而&#xff0c;不仅如此&#xff0c;它还是时间序列的关系数据库。使用 TimescaleDB 的开发人员将受益于专门构建的时间序列数据库以及经典的关系数据库 (PostgreSQL)&#xff0c;所有这些都具有完整的…

2023/9/13 -- C++/QT

作业&#xff1a; 1> 将之前定义的栈类和队列类都实现成模板类 栈&#xff1a; #include <iostream> #define MAX 40 using namespace std;template <typename T> class Stack{ private:T *data;int top; public:Stack();~Stack();Stack(const Stack &ot…

TouchGFX之缓存位图

位图缓存是专用RAM缓冲区&#xff0c;应用可将位图保存&#xff08;或缓存&#xff09;在其中。 如果缓存了位图&#xff0c;在绘制位图时&#xff0c;TouchGFX将自动使用RAM缓存作为像素来源。位图缓存在许多情况下十分有用。 从RAM读取数据通常比从闪存读取要快&#xff08;特…

Linux下Minio分布式存储安装配置(图文详细)

文章目录 Linux下Minio分布式存储安装配置(图文详细)1 资源准备1.1 创建存储目录1.2 获取Minio Server资源1.3 获取Minio Client资源 2 Minio Server安装配置2.1 切换目录2.2 后台启动2.3 查看进程2.4 控制台测试 3 Minio Client安装配置3.1 切换目录3.2 移动mc脚本3.2 运行mc命…

Vue3后台管理系统Element-plus_侧边栏制作_无限递归

在home.view中添加代码 <template><div><div class"common-layout"><el-container><el-header class"common-header flex-float"><div class"flex"><img class"logo" src"../assets/logo…

【Redis】Redis实现分布式锁

【Redis】Redis常见面试题&#xff08;1&#xff09; 文章目录 【Redis】Redis常见面试题&#xff08;1&#xff09;1. 为什么要用分布式锁2. Redis如何实现分布式锁3. Redis接受多个请求模拟演示4. 使用Redis实现分布式锁会存在什么问题4.1 一个锁被长时间占用4.2 锁误删 【Re…

vue2+element-ui批量导入方法并判断上传的文件是否为xls或xlsx

业务需求: 代码结构: <el-dialogtitle"批量导入":close-on-click-modal"true"close"close()":visible"true"width"35%":center"true"><div class"el-dialog-div"><!-- 头部区域布局 -…

【基本数据结构 四】线性数据结构:队列

学习了栈后,再来看看第四种线性表结构,也就是队列,队列和栈一样也是一种受限的线性表结构,和栈后进先出的操作方式不同的是,队列是FIFO的结构,也就是先进先出的操作方式。 队列的定义 队列这个概念非常好理解。可以把它想象成排队买票,先来的先买,后来的人只能站末尾…

软考知识汇总--结构化开发方法

文章目录 1 结构化开发2 耦合3 内聚4 设计原则5 系统文档6 数据流图6.1 数据流图的基本图形元素 7 数据字典 1 结构化开发 结构化方法总的指导思想是自顶向下、逐层分解&#xff0c;它的基本原则是功能的分解与抽象。它是软件工程中最早出现的开发方法&#xff0c;特别适合于数…

「C++程序设计 (面向对象进阶)」学习笔记・二

0、引言 本专栏的系列文章是在学习 北京邮电大学 崔毅东 老师的《C程序设计 (面向对象进阶)》课程过程中整理的。欢迎前往专栏了解更多相关内容~ &#x1f600; 有关于现代 C 的基本介绍&#xff0c;请前往《现代C基本介绍》&#xff01; &#x1f514; 先决条件 本专栏的系列…

定时器+BOM

9.定时器BOM 1.定时器 **概念:**重复执行一个函数 1.1setInterval() setInterval(“代码/函数”,时间,参数),返回定时器的序列号,默认从1开始 clearInterval(序列号)清除定时 <button class"start">开启定时器</button><button class"close…

通过Power Platform自定义D365 CE 业务需求 - 3. 使用Microsoft Power应用程序

Microsoft Power Apps是一个用于开发应用程序的无代码、无代码平台。Power应用程序可以在Dataverse之上配置为数据库。尽管您可以连接Salesforce、OneDrive、Dropbox等多种云源,但Dataverse也可以用作内部数据库来构建应用程序,并通过连接器连接其他数据源进行集成。 Power应…

Java开发之Redis核心内容【面试篇 完结版】

文章目录 前言一、redis使用场景1. 知识分布2. 缓存穿透① 问题引入② 举例说明③ 解决方案④ 实战面试 3. 缓存击穿① 问题引入② 举例说明③ 解决方案④ 实战面试 4. 缓存雪崩① 问题引入② 举例说明③ 解决方案④ 实战面试 5. 缓存-双写一致性① 问题引入② 举例说明③ 解决…

内存管理机制

aCoral内存管理机制 aCoral内存管理机制在伙伴系统基础上&#xff0c;采用了位图法方式提高内存分配和回收速度的确定性&#xff0c;更能满足系统实时性的需求。 aCoral内存管理机制分为两级&#xff0c;上一级采用改进的伙伴系统&#xff0c;负责确定要分配的内存的大小&…

数据分析综述

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

C#类与类库调用注意事项

类 创建一个类文件&#xff0c;myfunction.cs //静态类&#xff1a;直接引用、无需实例化 static public int jiafa(int V) //普通类&#xff1a;引用时需要实例化 public int jiafa(int V)using System; using System.Collections.Generic; using System.Diagnostics; using …