当前位置: 首页 > news >正文

mysql 锁详解

目录

前言

一、全局锁

二、表级锁

三、行锁


前言

为什么要设计锁,锁设计初衷是为了解决多线程下并发问题。出现并发的时候用锁进行数据同步,避免因并发造成了数据错误(数据覆盖)。可见锁的重要性,并不是所有的数据库都有锁。比如Redis,单个操作是原子性的,并且是单线程的,并发请求会在队列排列,请求是按顺序执行的,就不需要锁。Mysql 需要锁,mysql 是多线程的,并发操作要保证数据的一致性,需要通过锁进行数据同步。根据锁的范围来讲,mysql 的锁分为全局锁、表级锁和行锁

一、全局锁

全局锁就是对整个数据库实例加锁。Msql 提供的加全局锁的方法,命令是 Flush tables with read lock (FTWRL),以及set global readonly=true那么整库是只读状态,那么对数据库的DDL 以及 DML 将被阻塞,数据库将报下列错误。

全局锁主要是用在全库逻辑备份。这个命令产生以下风险:如果你在主库上备份,那么备份期间不能执行更新,如果在从库上备份,备份期间从库不能执行主库同步过来的binlog,会导致主从延迟。

我们在想想备份为什么要加锁,一定要加锁吗。答案是肯定的,必须的。加锁是为了保证数据的一致性以及业务的完整性。

我们现在有一个订单表,有一个余额表。有用户购买一个产品,业务逻辑是先扣除余额,然后往订单插一条数据。业务期间我们开始备份,在扣除余额前开始备份。恢复数据时候我们发现,用户的余额没有减少,但是用户多了一个订单。是不是不可以呀,所以备份前需要加锁的。加全局锁会影响业务,也是不可取的,有没有其他方法呢。

可以用官方自带的逻辑备份工具mysqldump,当在mysqldump使用参数–single-transaction 的时候,导数据前会启动一个事物,这个事物的隔离级别必须是RR,来确保拿到了一致性视图。由于MVCC 支持,数据库的DML 正常的处理。这种方法需要使用事务引擎的库,MyISAM就不可以。

MyISAM备份还是需要使用FTWRL的。有人说用set global readonly=true也可以让全库只读,可以不,当然也是可以的。他们之间有什么区别呢。一是,修改global变量的方式影响面非常大,readonly会被用来做其他逻辑,比如用来判断一个库是主库还是备库 二是,在异常处理机制的差异。如果客户端异常断开时使用FTWRL会自动释放全局锁,整个库可以正常更新。使用readonly整个库依旧处于只读状态,不能更新。

二、表级锁

在mysql 提供了两种表级别的锁:一种是表锁,二种是元数据锁(meta data lock,MDL)。表锁的语法是 lock tables … read/write,用这种方法的话可以用unlock 去释放锁,也可以客户端断开时自动释放。lock 的影响面很大不仅影响其他线程的write/read,write,本线程接下来的write/也会影响。这种方法毕竟对业务的影响很大,并不常用。

MDL锁,不需要用户显示使用,是mysql 内部的一种机制。当我们对数据表DML时,系统会自动加上MDL读锁,防止用户DDL操作,产生不一致性。当我们对数据表DDL时,系统会自动加上MDL写锁,防止用户DML操作以及其他线程的MDL操作避免数据不一致。

多说一句MDL是一个两阶段锁,在事务开始时加锁,事物结束时释放锁。在这个地方可以给大家解释下,session A , session B , session C, session D 是几个客户端

Session A

此时表加了一个MDL 读锁,事务还没有结束一直保留着MDL 读锁,直到commit 或者 rollback

Session B

此时表加了一个MDL 读锁,读锁之间可以共享

Session C

此时表加了一个MDL 写锁,读锁和写锁之间是互斥的所以阻塞

Session D

此时表加了一个MDL 读锁,由于Session C 被阻塞了所以 Session D也不阻塞了

由此我们可以确定MDL 锁的生命周期是从事务开始到事务提交。上面在解释一下Session D也是MDL读锁为啥也被阻塞了,Session C被阻塞后,后面客户端对表的MDL锁都会放到队列里,当事务提交后,依次从队列取出执行

如何安全的给表修改字段呢?

事务不提交,就会一直占着MDL锁。在 MySQL 的 information_schema 库的 innodb_trx 表中,你可以查到当前执行中的事务。如果你要做 DDL 变更的表刚好有长事务在执行,要考虑先暂停 DDL,或者 kill 掉这个长事务。

下面是如何kil 一个事物

一、在 information_schema 库的 innodb_trx 中找到一个事物id ,然后执行kill 就可以了

如果业务很重要或者表一直有数据更新,那么这种方法不可以了。需要用

ALTER TABLE tbl_name NOWAIT add column ...ALTER TABLE tbl_name WAIT N add column ...

这种方法,失败了重试,知道成功 。MariaDB 已经合并了 AliSQL 的这个功能,所以这两个开源分支目前都支持 DDL NOWAIT/WAIT n 这个语法。

有人问我mysql 5.6不是支持online ddl了吗?还会有阻塞吗,其实会的。online ddl 执行过程是这样的分为以下几步:

  1. 拿MDL写锁

  2. 降级成MDL读锁

  3. 真正做DDL

  4. 升级成MDL写锁

  5. 释放MDL锁

1、2、4、5如果没有锁冲突,执行时间非常短。第3步占用了DDL绝大部分时间,这期间这个表可以正常读写数据,是因此称为“online ”

我们的例子第一步就锁住了

三、行锁

行锁住要讨论的是innodb引擎下机制,myisam 不支持行锁,也就不支持并发,也就意味着myisam的更新是表级锁。

在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。

这个机制非常重要,为我们在业务设计中减少锁的冲突提供了理论的支持。那就是说如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。

既然是有锁,对于我们业务开发会不会造成死锁呢,答案是肯定的,什么事死锁呢?

当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。

当出现死锁后,有两种策略解决死锁:

  1. 一种策略是,直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。

  2. 另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑。

在 InnoDB 中,innodb_lock_wait_timeout 的默认值是 50s,意味着如果采用第一个策略,当出现死锁以后,第一个被锁住的线程要过 50s 才会超时退出,然后其他线程才有可能继续执行。对于在线服务来说,这个等待时间往往是无法接受的。如果值设置的太小那么正常的逻辑也有可能受到影响。

innodb_deadlock_detect 这个是有负担的,试想100个线程更新一条记录,那么就有100*100 个量级死锁检测,表的行数越多,会消耗大量的cpu 资源。如果关掉呢,又会一直死锁,直到超时,会影响业务。

那么怎么解决这样的问题呢?

以上两种方案,减少innodb_lock_wait_timeout时间以及 innodb_deadlock_detect=off都是不可取的,那么我们通过减少连接线程去减少并发从而达到减少死锁,后来发现这种方案也是不可靠的,第一、客户端的数量没法控制 第二、减少线程意味着系统的性能得不到完全利用。也只能从业务上去考虑呢,根据不同业务,把更新一行放到多行上,锁的粒度变小了,死锁就减少了。通过这些我们总结一个结论,提高系统性能往往需要确定系统的瓶颈在哪,锁造成的瓶颈,可以考虑减少锁的粒度,比如用分片锁等等

重要:大家有没有想过行锁是加在哪呢,是在索引上,意味着我们在update 时候,wehere 没有设置索引,那么只要扫描的记录都会加上索引,事务提交的时候统一释放。所以update 更新语句一定要记住加上索引,由于update 是当前读的,没有加上索引一定是灾难性的。

相关文章:

mysql 锁详解

目录 前言 一、全局锁 二、表级锁 三、行锁 前言 为什么要设计锁,锁设计初衷是为了解决多线程下并发问题。出现并发的时候用锁进行数据同步,避免因并发造成了数据错误(数据覆盖)。可见锁的重要性,并不是所有的数据库都有锁。比如Redis&a…...

【PX4-AutoPilot教程-TIPS】PX4控制无人机在Gazebo中飞行时由于视角跟随无人机在画面中心导致视角乱晃的解决方法

PX4控制无人机在Gazebo中飞行时由于视角跟随无人机在画面中心导致视角乱晃的解决方法 问题描述解决方法 问题描述 无人机在Gazebo中飞行时,无人机始终处于画面中央,会带着视角乱晃,在Gazebo中进行任何操作视角都无法固定。 观察Gazebo左侧Wo…...

五种多目标优化算法(NSGA2、MOPSO、MSSA、MOGWO、NSWOA)求解9个测试函数,包含6种评价指标(提供MATLAB代码)

一、5种多目标优化算法简介 1.1NSGA2 1.2MOPSO 1.3MSSA 1.4MOGWO 1.5NSWOA 二、5种多目标优化算法性能对比 为了测试5种算法的性能将其求解9个多目标测试函数(zdt1、zdt2 、zdt3、 zdt4、 zdt6 、Schaffer、 Kursawe 、Viennet2、 Viennet3)&#xff0…...

Sora--首个大型视频生成模型

Sora--首个大型视频生成模型 胡锡进于2024年2月20日认为:台当局怂了 新的改变世界模拟器视觉数据转换视频压缩时空补丁(Spacetime Laten Patches)视频生成扩展变压器算法和模型架构结语 胡锡进于2024年2月20日认为:台当局怂了 **T…...

关于 Reflect 的笔记

背景:Reflect 为了操作对象而提供的新Api 和 Proxy对象一样 特点 将object 对象的一些明显属于语言内部的方法,放到Reflect 上处理;修改某些object返回的异常结果,让其变得更合理;让object操作都变成函数行为&#xf…...

week04day02(爬虫02)

<span>: 通常用于对文本的一部分进行样式设置或脚本操作。<a>: 定义超链接&#xff0c;用于创建链接到其他页面或资源的文本。<img>: 用于插入图像。<br>: 用于插入换行。 姓名&#xff1a;<input type"text" value"lisi">…...

【C++初阶】类和对象(中)

目录 一.类的6个默认成员函数 1.知识引入 ​编辑 2.构造函数 (1)概念 (2)语法特性 (3)特征 ①问题引入1 ②问题引入2 &#xff08;缺少默认构造函数&#xff09; 3.析构函数 (1)概念 (2)特性 4.拷贝构造函数 (1)概念 (2)特征 ①拷贝构造函数是构造函数的一…...

Python爬虫知识图谱

下面是一份详细的Python爬虫知识图谱&#xff0c;涵盖了从基础入门到进阶实战的各个环节&#xff0c;涉及网络请求、页面解析、数据提取、存储优化、反爬策略应对以及法律伦理等多个方面&#xff0c;并配以关键点解析和代码案例&#xff0c;以供读者深入学习和实践。 一、Pyth…...

安宝特AR汽车行业解决方案系列1-远程培训

在汽车行业中&#xff0c;AR技术的应用正悄然改变着整个产业链的运作方式&#xff0c;应用涵盖培训、汽修、汽车售后、PDI交付、质检以及汽车装配等&#xff0c;AR技术为多个环节都带来了前所未有的便利与效率提升。 安宝特AR将以系列推文的形式为读者逐一介绍在汽车行业中安宝…...

微服务篇之分布式系统理论

一、CAP定理 1.什么是CAP 1998年&#xff0c;加州大学的计算机科学家 Eric Brewer 提出&#xff0c;分布式系统有三个指标&#xff1a; 1. Consistency&#xff08;一致性&#xff09;。 2. Availability&#xff08;可用性&#xff09;。 3. Partition tolerance &#xff0…...

MLflow【部署 01】MLflow官网Quick Start实操(一篇学会部署使用MLflow)

一篇学会部署使用MLflow 1.版本及环境2.官方步骤Step-1 Get MLflowStep-2 Start a Tracking ServerStep 3 - Train a model and prepare metadata for loggingStep 4 - Log the model and its metadata to MLflowStep 5 - Load the model as a Python Function (pyfunc) and us…...

NDK的log.h使用__android_log_print报错app:buildCMakeDebug[x86_64]

org.gradle.api.tasks.TaskExecutionException: Execution failed for task :app:buildCMakeDebug[x86_64] 重点是 Execution failed for task :app:buildCMakeDebug[x86_64]. 我的代码&#xff1a; #include <android/log.h> #define LOG_TAG "MyJNI" #d…...

【计算机网络:DHCP协议】

文章目录 前言一、DHCP是什么&#xff1f;二、DHCP的工作原理1.基本流程发现&#xff08;DISCOVER&#xff09;提供&#xff08;OFFER&#xff09;请求&#xff08;REQUEST&#xff09;确认&#xff08;ACKNOWLEDGEMENT&#xff09; 2.DHCP租约的概念3.DHCP续租过程 三、DHCP服…...

http前生今世

HTTP/0.9&#xff0c;仅支持GET方法&#xff0c;并且响应中没有HTTP头信息&#xff0c;只有文档内容。 HTTP/1.0增加了对POST方法、状态码、HTTP头信息等的支持&#xff0c;这一版本也是广泛应用的历史性版本。 HTTP/1.1引入了持久连接&#xff08;Persistent Connections&…...

一键安装ROS适用于Ubuntu22/20/18

一键安装ROS适用于Ubuntu22/20/18 1、简介 ROS&#xff08;Robot Operating System&#xff0c;机器人操作系统&#xff09;是一个用于机器人软件开发的框架。它提供了一套工具和库&#xff0c;用于机器人应用程序的开发、测试和部署。ROS是由美国斯坦福大学机器人实验室&…...

OLED透明屏厂家:开启2024年新征程

随着科技的不断进步和创新&#xff0c;OLED透明屏作为一种前沿的显示技术&#xff0c;正逐渐走进人们的视野&#xff0c;成为多个领域的焦点。在2024年2月21日这个特殊的日子&#xff0c;我们这家领先的OLED透明屏厂家正式开工&#xff0c;预示着我们将迎来一个充满机遇和挑战的…...

【算法与数据结构】200、695、LeetCode岛屿数量(深搜+广搜) 岛屿的最大面积

文章目录 一、200、岛屿数量1.1 深度优先搜索DFS1.2 广度优先搜索BFS 二、695、岛屿的最大面积2.1 深度优先搜索DFS2.2 广度优先搜索BFS 三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、200、岛屿数量 1.1 深度优先搜…...

第四十一回 还道村受三卷天书 宋公明遇九天玄女-python创建临时文件和文件夹

宋江想回家请老父亲上山&#xff0c;晁盖说过几天带领山寨人马一起去。宋江还是坚持一个人去。 宋江到了宋家村&#xff0c;被两个都头和捕快们追捕&#xff0c;慌不择路&#xff0c;躲进了一所古庙。一会儿&#xff0c;听见有人说&#xff1a;小童奉娘娘法旨&#xff0c;请星主…...

Tofu5m 高速实时推理Yolov8

Tofu5m 是高性价比目标识别跟踪模块&#xff0c;支持可见光视频或红外网络视频的输入&#xff0c;支持视频下的多类型物体检测、识别、跟踪等功能。 Yolov8推理速度达到40帧每秒。 实测视频链接&#xff1a;Tofu5m识别跟踪模块_哔哩哔哩_bilibili 产品支持视频编码、设备管理…...

[SWPUCTF 2021 新生赛]crypto8

第一眼看见是乱码不确定是什么的编码 看了下感觉是UUencode编码 UUencode编码是一种古老的编码方式&#xff0c;通常用于将二进制数据转换成可打印字符的形式。UUencode编码采用一种基于64个字符的编码表&#xff0c;将每3个字节的数据编码为4个可打印字符&#xff0c;以实现…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...