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…

Ei Scopus检索 | 2024年第三届能源与环境工程国际会议(CFEEE 2024)

会议简介 Brief Introduction 2024年第三届能源与环境工程国际会议(CFEEE 2024) 会议时间&#xff1a;2024年9月1日-3日 召开地点&#xff1a;新西兰奥克兰 大会官网&#xff1a;https://www.cfeee.org/ 2024年第三届能源与环境工程国际会议(CFEEE 2024) 将于2024年12月12日至1…

Struts.xml 配置文件说明

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!--…

【Linux常用命令】

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

elasticsearch集群部署-实操

elasticsearch&#xff08;集群&#xff09; 案例版本&#xff1a;elasticsearch 8.6.2 操作系统&#xff1a;CentOS 7 注意&#xff1a;全程使用普通用户操作。 0、节点信息 节点描述192.168.127.10master192.168.127.11slave…slave02 1、环境配置 1.1 修改文件 /etc/se…

中国大学MOOC地下水污染与防治答案

本文转载自 众课帮 众工号 1、下列哪项不属于有机污染物综合指标&#xff08; &#xff09; A、高锰酸盐指数 B、化学需氧量&#xff08;COD&#xff09; C、浊度 D、总有机碳&#xff08;TOC&#xff09; 答案&#xff1a;浊度 2、饮用水水质指标常说的“两虫”是指( ) A、贾…

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

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

第24节——react hooks组件传值 - 父子组件之间的传值

一、概念 一句话概括&#xff0c;react hook 父子组件之间通过props进行传值 二、父传子 父组件&#xff1a;在子组件标签上定义属性 子组件&#xff1a;函数组件接收一个props是一个对象&#xff0c;父组件传的属性名就是props对象的key&#xff0c;属性的值就是对应的val…

python实现Flask GET Demo

python代码 from flask import Flask, request, jsonifyapp Flask(__name__)#用/data路径路由 app.route(/data) def get_data():## 以下一行是从URL中获取参数的get方法data request.args.get(data)return jsonify(data data,info "success !",code "200…

十五、垃圾回收相关算法

目录 一、标记阶段&#xff1a;引用计算法对象存活判断引用计算法 二、标记阶段&#xff1a;可达性分析算法三、对象的finalization机制四、MAT和Jprofiler的GC Toots的溯源五、垃圾清除算法之标记-清除算法六、垃圾清除算法之复制算法七、垃圾清除算法之标记-压缩算法八、小结…

智慧园区: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命…

结构型设计模式

结构型设计模式 结构型设计模式主要总结了一些类或对象组合在一起的经典结构&#xff0c;这些经典的结构可以解决特定应用场景的问题。结构模式包括&#xff1a;代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、亨元模式。 1. 代理模式 实现方式&#xff…

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的结构,也就是先进先出的操作方式。 队列的定义 队列这个概念非常好理解。可以把它想象成排队买票,先来的先买,后来的人只能站末尾…