浅谈Mysql(四)——Mysql知识补充

一、mysql什么时候会锁表

  MySQL中的查询语句通常不会锁表,因为查询操作只读取数据而不修改数据。然而,当执行某些特定的查询语句或者在特定情况下,MySQL可能会对表进行锁定以保证数据的一致性和完整性。以下是几种可能导致表锁定的情况:

  1. 事务锁定(Transaction Locking):当使用事务(Transaction)处理多个操作时,MySQL可能会对相关的表进行锁定以保证事务的隔离性。例如,在使用BEGIN、START TRANSACTION或SET autocommit = 0开始事务后,执行的查询语句可能会锁定相关表。
  2. 写操作锁定(Write Locking):某些写操作(如INSERT、UPDATE、DELETE)可能会锁定涉及的表。这是为了防止其他并发的写操作引起数据不一致。例如,当执行一个UPDATE语句时,MySQL会对被更新的行进行锁定,以确保其他事务不能同时修改这些行。
  3. 表锁定(Table Locking):有些情况下,MySQL可能会对整个表进行锁定。例如,执行ALTER TABLE、TRUNCATE TABLE、OPTIMIZE TABLE等操作时,MySQL会对相应的表进行锁定以保证数据的完整性。
  4. 锁冲突(Lock Conflicts):当多个事务同时请求对同一资源(行、页、表等)的锁定时,可能会发生锁冲突。MySQL会根据事务的隔离级别(Isolation Level)和锁定类型(Lock Type)来处理这些冲突。如果一个事务请求的锁与其他锁发生冲突,MySQL可能会将其等待或者阻塞,直到冲突解决。

  需要注意的是,MySQL的锁定机制是为了保证数据的一致性和隔离性,但过多的锁定可能会导致性能下降和并发性降低。因此,在设计数据库和查询时,应该合理选择锁定的粒度,并优化查询语句,以减少锁定的需求,并提高系统的性能和并发能力。

二、select语句就一定不会锁表吗?

——不是。

  在某些情况下,SELECT语句可能导致表锁定,尤其是在与元数据相关的操作时。以下是几种可能导致SELECT语句锁定表的情况:

  1. 元数据锁定(Metadata Locking):当执行SELECT语句时,MySQL可能会获取与表相关的元数据锁定。元数据锁定用于保护表结构的一致性,以防止其他并发操作对表结构进行更改。例如,当执行SELECT语句时,MySQL可能会获取一个共享锁(Shared Lock),以防止其他操作对表的结构进行更改,直到SELECT语句完成。
  2. 表级锁定(Table-Level Locking):在某些情况下,MySQL可能会对整个表进行锁定,而不仅仅是锁定所需的行。这可能发生在使用不可重复读(Repeatable Read)或串行化(Serializable)隔离级别的情况下。当一个SELECT语句正在执行时,MySQL可能会对整个表进行锁定,以确保其他事务不能对表进行写操作,保证查询结果的一致性。
  3. 查询缓存锁定(Query Cache Locking):如果在MySQL中启用了查询缓存(Query Cache),当执行SELECT语句时,MySQL会检查查询缓存中是否有相应的缓存结果。在查询缓存的锁定过程中,MySQL可能会对相关的表进行锁定,以确保缓存的数据一致性。

为了避免SELECT语句导致表锁定的情况,可以考虑以下几点:

  1. 优化查询语句:确保查询语句使用适当的索引和优化技巧,以最小化对表的访问和锁定。
  2. 调整隔离级别:根据业务需求,选择合适的隔离级别。较低的隔离级别(如读已提交)可能会减少锁定的范围。
  3. 避免长事务:长时间运行的事务可能会导致锁定,因此尽量减少事务的执行时间。
  4. 考虑使用非阻塞读取:MySQL提供了一些非阻塞读取的技术,如快照读取(Snapshot Read)和多版本并发控制(MVCC),可以降低对表的锁定需求。

  请注意,具体的表锁定情况可能因MySQL版本、配置和具体操作而有所不同。在生产环境中,建议进行系统性能优化和监测,以确定导致表锁定的具体原因,并采取相应的措施进行优化和调整。

2.1 什么情况下,select查询语句时,会导致表相关的元数据锁定?

  当执行SELECT查询语句时,可能会导致表相关的元数据锁定的情况包括:

  1. 表结构变更:如果在SELECT查询执行期间有其他并发操作正在对表的结构进行修改,例如执行ALTER TABLE语句来添加、删除或修改列,MySQL会获取表的元数据锁定。这是为了确保查询期间表结构的一致性,避免查询结果受到并发结构变更的影响。
  2. 表级锁定:在某些隔离级别下,如可重复读(Repeatable Read)或串行化(Serializable),当执行SELECT查询时,MySQL可能会获取表级锁定。这种锁定是为了保证查询期间其他事务无法对表进行写操作,以保持查询结果的一致性。在持有表级锁定的情况下,其他事务无法对表进行插入、更新或删除操作。
  3. 查询缓存锁定:如果启用了MySQL的查询缓存,并且SELECT查询的结果被缓存,则在查询缓存过程中,MySQL会获取与相关表的元数据锁定。这是为了保证查询缓存的一致性,防止其他并发操作对查询结果的影响。

  需要注意的是,元数据锁定是为了保证数据库的一致性和隔离性,以防止并发操作引起的问题。然而,过多的锁定可能会对系统的性能和并发性产生负面影响。因此,在设计数据库结构和查询时,应避免频繁的表结构变更和长时间的事务操作,以减少元数据锁定的发生,从而提高系统的性能和并发能力。

2.2 生产问题案例

在生产环境中发现了SELECT语句导致表锁定的情况,并且这些SELECT语句正好在执行分区操作时发生了锁表,锁表原因:

  1. 分区锁定冲突:当多个事务同时请求对同一分区进行锁定时,可能会发生锁冲突。这可能是因为SELECT语句正在执行分区操作,而其他事务正在尝试对相同的分区进行写操作。根据MySQL的锁定机制,写操作(如INSERT、UPDATE、DELETE)可能需要获取排它锁(Exclusive Lock),而SELECT语句可能需要获取共享锁(Shared Lock)。如果写操作和SELECT语句同时对同一分区请求锁定,就会导致锁冲突和锁表的情况。
  2. 元数据锁定:执行分区操作可能会涉及到表的元数据的修改。当执行分区操作时,MySQL可能会获取与表相关的元数据锁定,以保证分区操作的一致性。如果其他事务正在执行SELECT语句,并且需要获取相同的元数据锁定,就会导致锁冲突和锁表的情况。

结合实际场景,我们发生锁表的原因是第2点。

针对这种情况,您可以考虑以下几点解决方法:

  1. 优化事务和查询:确保事务和查询语句尽可能地减少对同一分区的冲突访问。可以通过合理的事务设计、优化查询语句和索引等方式来减少锁冲突的可能性。
  2. 调整隔离级别:根据业务需求,选择合适的隔离级别。较低的隔离级别(如读已提交)可能会减少锁定的范围,降低锁冲突的概率。
  3. 分区策略优化:评估和优化分区策略,确保分区操作的粒度和并发性能的平衡。可能需要根据具体的业务需求和数据访问模式来调整分区策略。、

三、S锁(共享锁)和X锁(排他锁)

  在MySQL中,S锁(共享锁)和X锁(排他锁)是用于实现并发控制的锁机制。它们在以下情况下触发:

S锁(共享锁)

  1. 当一个事务获取了S锁后,其他事务可以继续获取S锁,允许多个事务同时读取同一份数据;
  2. S锁在读取数据时被自动获取,不需要显式地指定;
  3. S锁不会阻塞其他事务的读取操作,但会阻塞其他事务的写操作;

X锁(排他锁)

  1. 当一个事务获取了X锁后,其他事务无法再获取S锁或X锁,阻塞其他事务的读取和写入操作;X锁用于保护数据的写入和修改操作,确保在事务进行修改时,其他事务无法读取或修改同一份数据;
  2. X锁可以显式地指定,通常通过语句中的FOR UPDATE来获取;
  3. 但是也会自动触发,当执行UPDATE语句时,MySQL会自动获取X锁来保护正在更新的数据行,防止其他事务同时读取或修改该数据行;

3.1 update语句会自动触发x锁吗?

  在MySQL中,UPDATE语句默认情况下会自动触发X锁(排他锁)。当一个事务执行UPDATE语句时,它会获取X锁来保护正在更新的数据行,以确保其他事务无法同时读取或修改该数据行。X锁的目的是确保在事务进行更新操作时,其他事务无法读取或修改同一份数据,从而实现数据的一致性和隔离性。其他事务如果尝试获取X锁或S锁来读取或修改被锁定的数据行,它们会被阻塞,直到持有X锁的事务完成或释放锁。需要注意的是,如果在UPDATE语句中使用了WHERE子句来指定更新条件,MySQL只会锁定满足条件的数据行,并不会锁定整个表。这样可以减少锁的粒度,提高并发性能。如果你想在UPDATE语句中避免自动触发X锁,你可以使用LOCK IN SHARE MODE或FOR UPDATE来显式地指定锁的类型。LOCK IN SHARE MODE会获取S锁(共享锁),而FOR UPDATE会获取X锁(排他锁)。

四、拓展阅读

Mysql锁相关知识

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

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

相关文章

目标检测标签分配策略,难样本挖掘策略

在目标检测任务中,样本的划分对于模型的性能具有至关重要的影响。其中,正样本指的是包含目标物体的图像或区域,而负样本则是不包含目标物体的图像或区域。然而,在负样本中,有一部分样本由于其与正样本在特征上的相似性…

jest单元测试——项目实战

jest单元测试——项目实战 一、纯函数测试二、组件测试三、接口测试四、React Hook测试💥 其他的疑难杂症另:好用的方法 🌟 温故而知新:单元测试工具——JEST 包括:什么是单元测试、jest的基本配置、快照测试、mock函数…

机器学习工作流

本文的目的是演示如何构建一个相对完整的机器学习工作流 1.首先对工程进行基本的参数配置 # 进行建模基本配置 SCORE_EVA roc_auc random_state_clf 1 n_jobs 4 cv_split StratifiedKFold(n_splits5, shuffleTrue, random_state1) cv_split2 StratifiedKFold(n_splits5, …

(013)window的Idea运行程序 Amazon java.nio.file.AccessDeniedException

解决方法一 在资源管理器中删除该目录, 在程序中使用代码,重新建立该目录: if (!FileUtil.exist(destinationPath)){FileUtil.mkdir(destinationPath); }解决方法二 JDK 的版本有问题,换个JDK。 解决方法三 网络不好&#xf…

「39」打造专业流畅的直播特效转场……

「39」工作室模式 打造专业流畅的直播特效转场体验 工作室模式是OBS软件里的一个特殊功能,用于后期直播过程中追求直播效果的用户,才会使用此功能。 该功能意在更加平滑,使用模板信息变化的过渡效果。主要用在赛事比分、活动抽奖、直播时需要经常更改的场景和内容,以及片…

Spring之底层架构核心概念解析

你好,我是柳岸花开。 在当今快速发展的软件开发领域,各种技术层出不穷,但有一项技术以其卓越的设计、灵活的配置和广泛的应用,始终屹立在开发者的工具箱中——这就是Spring框架。自2003年首次发布以来,Spring已经成为J…

Android 11属性系统初始化流程

在init进程启动的第二阶段,调用PropertyInit 对属性系统进行初始化 int SecondStageMain(int argc, char** argv) {//省略PropertyInit();//省略 }PropertyInit函数在system\core\init\property_service.cpp 中实现 void PropertyInit() {//省略mkdir("/dev/…

opencv x86(32位) windows下vs2019编译问题

opencv x86(32位) windows下vs2019编译相关资料很多,都特别受用。例如 - https://blog.csdn.net/m0_59025104/article/details/134109081 - https://blog.csdn.net/sements/article/details/108410470 但是,自己编译时候仍遇到一些问题,例如&…

智能网联汽车自动驾驶数据记录系统DSSAD数据元素

目录 第一章 数据元素分级 第二章 数据元素分类 第三章 数据元素基本信息表 表1 车辆及自动驾驶数据记录系统基本信息 表2 车辆状态及动态信息 表3 自动驾驶系统运行信息 表4 行车环境信息 表5 驾驶员操作及状态信息 第一章 数据元素分级 自动驾驶数据记录系统记录的数…

【GameFi】 链游 | Brilliantcrypto点火活动

活动:https://app.galxe.com/quest/brilliantcrypto/GCt8wthq2J Brilliantcrypto点火活动正在Galxe上进行 🎉 活动时间:2024/04/06 12:00 ~ 2024/05/04 12:00 奖励总价值1200美元的MATIC 完成任务並在Brilliantcrypto Galxe Space上赚取积分。…

【数据结构与算法】:快速排序和冒泡排序

一,快速排序 快速排序是一种比较复杂的排序算法,它总共有4种实现方式,分别是挖坑法,左右"指针"法,前后"指针"法,以及非递归的快速排序,并且这些算法中也会涉及多种优化措施…

Docker是一个开源的应用容器引擎

Docker是一个开源的应用容器引擎,它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。Docker技术的…

zdpdjango_materialadmin使用Django开发一个Material风格的后台管理系统

启动项目 同样地,还是先看看代码: 将项目启动起来: 浏览器访问:http://localhost:8000/ 代码初步优化 首先是将admin_materal提到本地来: 移除掉第三方依赖: pip uninstall django-admin-materi…

sqlserver2014安装与老版本卸载

本篇博客只提供安装包 安装与卸载难度较低,不做赘述 并不是说一定要卸载才能安装,灵活掌握,如果实际场景需要清理老版本sqlserver那么选择卸载 一、下载 下载地址 sqlserver2014官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 二、卸载…

移动平台相关(安卓)

目录 安卓开发 Unity打包安卓 ​编辑​编辑 BuildSettings PlayerSettings OtherSettings 身份证明 配置 脚本编译 优化 PublishingSettings 调试 ReMote Android Logcat AndroidStudio的调试 Java语法 ​编辑​编辑​编辑 变量 运算符 ​编辑​编辑​编辑​…

面向低碳经济运行目标的多微网能量互联优化调度matlab程序

微❤关注“电气仔推送”获得资料(专享优惠) 运用平台 matlabgurobi 程序简介 该程序为多微网协同优化调度模型,系统在保障综合效益的基础上,调度时优先协调微网与微网之间的能量流动,将与大电网的互联交互作为备用…

gcc/g++:预编译阶段查看模块生成目标的层级依赖

预编译阶段查看模块生成目标的层级依赖首先需要找到需要包含头文件的位置,然后进行引入。 示例: 1)用户头文件 /*brief design and implements of demo-for-precompile.author wenxuanpeiemail 15873152445163.com(query for any question …

百度松果菁英班——机器学习实践四:文本词频分析

飞桨AI Studio星河社区-人工智能学习与实训社区 🥪jieba分词词频统计 import jieba # jieba中文分词库 ​ with open(test.txt, r, encodingUTF-8) as novelFile:novel novelFile.read() # print(novel) stopwords [line.strip() for line in open(stop.txt, r,…

初识C++ · 类和对象(上)

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1 访问限定符 4.2 封装 5.类的作用域 6.类的实例化 7.类的对象大小的计算 8.类成员函数的this指针 1.面向过程和面向对象初步认识 C语言是一门面向过程的语言,注重的…

vue+springboot多角色登录

①前端编写 将Homeview修改为manager Manager&#xff1a; <template><div><el-container><!-- 侧边栏 --><el-aside :width"asideWidth" style"min-height: 100vh; background-color: #001529"><div style"h…