MySql什么时候表锁or行锁?

文章目录

    • 锁的基本概念
      • 共享锁(读锁)
      • 排他锁(写锁)
      • 锁的兼容性
      • 锁的升级和降级
    • 全局锁、表锁、行锁
      • 全局锁
      • 表锁
      • 行锁
    • 何时使用行锁
    • 何时使用表锁
    • 额外思考:

在数据库的世界里,性能优化是一个永恒的话题。MySQL作为广泛使用的数据库之一,其锁机制是保证数据一致性的关键。了解何时使用行锁和表锁,能够帮助我们更有效地进行数据库操作,避免死锁和性能瓶颈。

众所周知,我们都知道 Innodb 有全局锁、表级锁、行级锁三种,但你知道什么时候会用表锁,什么时候会用行锁吗?

  1. 对于表级锁而言,当执行 DDL 语句去修改表结构时,会使用表级锁
  2. 对于行级锁而言,一般情况下都会默认使用行级锁,貌似是需要有索引匹配到才行

锁的基本概念

在深入讨论行锁与表锁之前,我们先来回顾一下锁的基本概念。锁是数据库管理系统用来控制对数据的并发访问的一种机制。在MySQL中,锁分为共享锁(读锁)和排他锁(写锁)
在MySQL中,锁是用于管理并发访问数据库资源的一种机制,以确保数据的完整性和一致性。锁分为两种基本类型:共享锁(Shared Locks,通常称为读锁)和排他锁(Exclusive Locks,通常称为写锁)

共享锁(读锁)

共享锁是一种允许多个用户同时读取同一数据资源的锁类型。当一个事务对数据行或表持有共享锁时,其他事务也可以获取该数据行或表的共享锁,但无法获取排他锁。共享锁通常用于以下场景:

  1. 读取操作:当用户需要从数据库中读取数据时,数据库会为这些数据行或整个表添加共享锁。
  2. 非阻塞读取:共享锁允许多个事务同时读取数据,不会阻止其他读取操作,从而提高了并发性能。
  3. 隔离级别:在某些事务隔离级别下(如READ COMMITTED),MySQL会使用共享锁来实现非阻塞读取。

排他锁(写锁)

排他锁是一种不允许其他用户同时读取或写入同一数据资源的锁类型。当一个事务对数据行或表持有排他锁时,其他事务既不能获取该数据行或表的共享锁,也不能获取排他锁。排他锁通常用于以下场景:

  1. 写入操作:当用户需要向数据库中插入、更新或删除数据时,数据库会为这些数据行或整个表添加排他锁。
  2. 数据保护:排他锁确保在数据被修改时,没有其他事务可以访问这些数据,从而防止数据不一致。
  3. 隔离级别:在更高的事务隔离级别下(如REPEATABLE READ和SERIALIZABLE),MySQL会使用排他锁来防止脏读、不可重复读和幻读。

锁的兼容性

  • 共享锁与共享锁:兼容。多个事务可以同时持有同一数据资源的共享锁。
  • 共享锁与排他锁:不兼容。持有共享锁的事务不能获取排他锁,反之亦然。
  • 排他锁与排他锁:不兼容。同一数据资源上不能同时存在多个排他锁。

锁的升级和降级

在某些情况下,MySQL可能会自动将共享锁升级为排他锁,或者将排他锁降级为共享锁,以满足事务的需求。例如,如果一个事务持有共享锁并尝试修改数据,MySQL会尝试将共享锁升级为排他锁。
了解共享锁和排他锁的工作原理对于优化数据库性能和设计高效的数据库应用至关重要。正确的锁策略可以减少锁争用,提高并发性能,同时确保数据的一致性和完整性。

全局锁、表锁、行锁

全局锁

全局锁就是对整个数据库实例加锁。 MySQL 提供了一个加全局读锁的方法,命令是 Flush tables with read lock (FTWRL)。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。你可以理解为,全局锁基本上把数据所所有的变更语句都锁住了。

全局锁的典型场景应用场景是全库逻辑备份,也就是把整个库每个表都 select 出来存起来。上面说到全局锁会锁住所有变更语句,但这只是对于 MyISAM 存储引擎而言的。对于 Innodb 而言,其可以利用 MVCC 实现数据的一致性视图,从而不需要锁整个库就可以实现全库的数据备份。

表锁

表锁,顾名思义就是对某个表加锁。

表锁是一种粗粒度的锁,它锁定的是整个表。当一个表被锁定时,其他用户无法对该表进行读写操作,直到锁被释放。表锁通常在以下情况下使用:

  1. 全表扫描:当执行全表扫描操作时,使用表锁可以减少锁的开销。
  2. 批量操作:在进行大量数据的插入、更新或删除操作时,表锁可以减少锁的争用。
  3. 低并发环境:在并发较低的环境中,表锁可以简化锁管理,提高操作效率。
    一般情况是对应的存储引擎没有行级锁(例如:MyIASM),或者是对应的 SQL 语句没有匹配到索引。

对于第一种情况而言,因为对应存储引擎不支持行锁,所以只能是使用更粗粒度的锁来实现,这也比较好理解。

对于第二种情况而言,如果存储引擎支持行锁,但对应的 SQL 就没有使用索引,那么此时也是会全表扫描,那此时也是会使用表锁。例如下面的语句没有指定查询列,或者指定了查询列但是并没有用到索引,那么也是会直接锁定整个表。
// 没有指定查询列
selectfrom user;
// 指定查询列,但是没有用到索引
selectfrom user where name = ‘zhangsan’;
上面说的索引,可以说是判断是否会用行级锁的关键

行锁

行锁是MySQL中一种细粒度的锁,它锁定的是数据库表中的一行或多行数据。行锁的优点是它能够提供较高的并发性,因为只锁定需要操作的数据行,而不会影响其他行。行锁通常在以下情况下使用:

  1. 事务隔离级别较高:在REPEATABLE READ或SERIALIZABLE隔离级别下,MySQL默认使用行锁。
  2. 高并发读写操作:当有大量的读写操作同时进行时,行锁可以减少锁的争用,提高系统性能。
  3. 使用索引进行查询:如果查询语句能够利用索引,MySQL会自动使用行锁。

何时使用行锁

  1. 高并发读写:在高并发读写的场景下,使用行锁可以减少锁的争用,提高系统的并发处理能力。
  2. 细粒度控制:当需要对单个或少数几条记录进行操作时,行锁可以提供更细粒度的控制。
  3. 避免锁升级:在某些情况下,如果事务只涉及少量数据行,使用行锁可以避免锁从行锁升级为表锁。

何时使用表锁

  1. 全表操作:当执行全表的插入、更新或删除操作时,使用表锁可以减少锁的开销。
  2. 批量数据处理:在处理大量数据时,表锁可以简化操作,提高效率。
  3. 低并发环境:在并发较低的环境中,使用表锁可以减少锁管理的复杂性。

额外思考:

如果查询或更新用到了索引,但是查询或更新的数据特别多,占全表的 80% 甚至更多,这时候是会用表锁,还是行锁呢?
在MySQL中,即使查询或更新操作使用了索引,如果涉及到的数据量非常大,比如占全表的80%或更多,MySQL的行为可能会取决于几个因素:

  1. 事务隔离级别:不同的隔离级别会影响锁的行为。例如,在REPEATABLE READ(MySQL的默认隔离级别)或SERIALIZABLE隔离级别下,MySQL倾向于使用行锁,但在高并发和大量锁定的情况下,可能会出现锁升级,即从行锁变为表锁。
  2. 锁的争用和死锁:如果大量的行被锁定,MySQL的锁管理器可能会决定升级为表锁以减少锁的争用和避免死锁。
  3. InnoDB的锁策略:InnoDB存储引擎有自己的锁策略,它试图平衡行锁和表锁的使用以优化性能。InnoDB会根据事务的大小和并发情况动态调整锁的行为。
  4. 锁的粒度:InnoDB通常优先使用行锁,但如果锁定的行数超过了一定比例(通常认为是表中行数的20%左右),InnoDB可能会将锁升级为表锁。
  5. 具体的SQL操作:某些特定的SQL操作,如UPDATE或DELETE涉及大量数据,即使使用索引,也可能触发表锁。
  6. 系统配置和版本:MySQL的配置和版本也会影响锁的行为。例如,某些配置参数可以调整锁升级的阈值。
    在实际操作中,如果确实涉及到大量数据的查询或更新,并且对性能有严格要求,建议采取以下措施:
  • 优化索引:确保索引设计得当,以减少锁的范围和提高查询效率。
  • 分批处理:将大量数据的操作分批进行,每次处理一小部分数据,以减少锁的影响。
  • 调整隔离级别:根据业务需求,适当调整事务隔离级别。
  • 监控和调优:使用MySQL的监控工具来观察锁的行为,并根据实际情况进行调优。
    总之,MySQL会根据当前的事务情况和系统配置来决定使用行锁还是表锁。如果操作涉及的数据量非常大,即使使用了索引,也可能会使用表锁,特别是当系统认为这样做可以提高性能或减少死锁风险时。

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

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

相关文章

03-07Java自动化之JAVA基础之循环

JAVA基础之循环 一、for循环 1.1for循环的含义 for(初始化语句;条件判断;条件控制或–){ ​ //代码语句 } 1、首先执行初始话语句,给变量一个起始的值 2、条件判断进行判断,为true,执行循环体中的代码语句 ​ …

3DGS语义分割之LangSplat

LangSplat是CVPR2024的paper. 实现3DGS的语义分割(可文本检索语义) github: https://github.com/minghanqin/LangSplat?tabreadme-ov-file 主要思想是在3DGS中加入了CLIP的降维语义特征,可用文本检索目标,实现分割。 配置环境&…

网线水晶头为什么要按标准线序打

网线接水晶头为什么要按照线序接? 减少串扰和增强信号质量: 双绞线的设计是为了减少信号间的串扰( Crosstalk),每一对线芯在传输过程中通过相互扭绞抵消外部电磁干扰。按照标准线序接线能够确保每一对线芯之间的信号传…

Ubuntu server 24 (Linux) 安装部署smartdns 搭建智能DNS服务器

SmartDNS是推荐本地运行的DNS服务器,SmartDNS接受本地客户端的DNS查询请求,从多个上游DNS服务器获取DNS查询结果,并将访问速度最快的结果返回给客户端,提高网络访问速度和准确性。 支持指定域名IP地址,达到禁止过滤的效…

Pinia的介绍、使用及持久化

Pinia介绍 什么是Pinia? Pinia 是 Vue 的最新 状态管理工具,状态就是数据。 通俗地讲:Pinia 是一个插件,可以帮我们管理 vue 通用的数据 (多组件共享的数据)。 比如一份数据有多个组件需要使用,在学Pinia之前我们需…

Accelerate 笔记:保存与加载文件

保存和加载模型、优化器、随机数生成器和 GradScaler 使用 save_state() 将上述所有内容保存到一个文件夹位置使用 load_state() 加载之前通过 save_state() 保存的状态通过使用 register_for_checkpointing(),可以注册自定义对象以便自动从前两个函数中存储或加载 …

vue3+electron+typescript 项目安装、打包、多平台踩坑记录-mac+linux(包括国产化系统)

上一章《vue3electrontypescript 项目安装、打包、多平台踩坑记录》,我们讲了vue3electrontypescript的项目安装和windows 32位、64位的打包。这一节我们来看下mac和linux平台的打包和一些坑。 mac 经过上一章我们的踩坑后,再到mac环境,这里…

“雪糕刺客”爆改“红薯刺客”,钟薛高给了消费品牌哪些启示?

夏日袭来,一支价格高昂却让人眼前一亮的雪糕,曾一度成为市场热议的焦点。然而,随着消费者对性价比的日益关注,曾经的“雪糕刺客”钟薛高,其创始人林盛近期以直播带货红薯开启他的还债之路,高打情怀“直播自…

构建一个java项目,对于安全方面,需要哪些业务模块

概览: 构建一个Java项目时,安全方面需要考虑多个业务模块,以确保系统的安全性和数据的完整性。以下是一些关键的安全业务模块: 身份验证模块: 用户登录和注销功能。支持多种认证方式(如用户名密码、OAuth、…

关于序列化与反序列化解题

1、[安洵杯 2019]easy_serialize_php <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_SESSION){unset($_SESSION); }$_SESSION["use…

《数据资产》专题:《数据资产》如何确权、估值? 《数据产权》如何明确、保护?

2020 年 04 月 10 日&#xff0c;《中共中央国务院 关于“构建更加完善的要素市场化配置体制机制”的意见》正式公布&#xff0c;将数据确立为五大生产要素&#xff08;土地、资本、劳动力以及技术&#xff09;之一&#xff0c;数据要素市场化已成为建设数字中国不可或缺的一部…

python系列29:压测工具locust

1. 介绍 使用pip进行安装&#xff0c;下面是个简单例子&#xff1a; from locust import HttpUser, taskclass HelloWorldUser(HttpUser):taskdef hello_world(self):self.client.get("/hello")self.client.get("/world")然后打开web页面&#xff1a; 点…

rpm打包及打包问题汇总

rpm打包详解 https://www.cnblogs.com/ishmaelwanglin/p/17033333.html 打包问题汇总&#xff1a; https://blog.csdn.net/u014007037/article/details/78727526 基本够用&#xff0c;有问题私信探讨&#xff01;

大尺寸图像分类检测分割统一模型:Resource Efficient Perception for Vision Systems

论文题目&#xff1a;Resource Efficient Perception for Vision Systems 论文链接&#xff1a;http://arxiv.org/abs/2405.07166 代码链接&#xff1a;https://github.com/Visual-Conception-Group/Localized-Perception-Constrained-Vision-Systems 作者设计了一个统一的模…

安装LLVM后无法使用FileCheck工具

如题&#xff0c;笔者在使用LLVM提供的FileCheck工具时&#xff0c;报错无法找到命令。 经查找&#xff0c;原因是笔者安装过多个版本的LLVM&#xff0c;因此LLVM在安装时为工具添加了对应的版本号&#xff0c;因此filecheck命令要切换为FileCheck-19。

k8s牛客面经篇

k8s的pod版块: k8s的网络版块: k8s的deployment版块: k8s的service版块: k8s的探针板块: k8s的控制调度板块: k8s的日志监控板块: k8s的流量转发板块: k8s的宏观版块:

单列集合--collection

package exercise;import java.util.ArrayList; import java.util.Collection;public class CollectionDemo {public static void main(String[] args) {//注意点://Co1lection是一个接口,我们不能直接创建他的对象。//所以&#xff0c;现在我们学习他的方法时&#xff0c;只能…

英伟达(NVIDIA)、AMD和Intel部分GPU性能参数对比

当然&#xff0c;以下是对NVIDIA、AMD和Intel部分GPU型号更为详细的性能参数对比&#xff0c;以及对它们的市场应用和技术创新的概述。 NVIDIA GPU 1. NVIDIA H100 CUDA核心数&#xff1a;数千个&#xff08;具体数量根据型号配置有所不同&#xff09;Tensor Core数&#xf…

【LeetCode算法】第108题:将有序数组转换为二叉搜索树

目录 一、题目描述 二、初次解答 三、官方解法 四、总结 一、题目描述 二、初次解答 1. 思路&#xff1a;由于数组nums是递增的&#xff0c;采用二分查找法来构造平衡二叉搜索树。首先&#xff0c;选择nums的中间结点作为根节点&#xff0c;然后将左部分的中间值作为左子树…

vscode远程登录ubuntu linux报错,一直输入密码问题

再查询了各种解决方法没有解决后&#xff0c;我在csdn发出问题&#xff0c;找到磁盘不足的原因&#xff0c;于是在linux中使用命令&#xff1a; 查看磁盘空间使用情况&#xff1a; df -h 查找并删除不需要的文件&#xff0c;例如旧的内核和缓存文件&#xff1a; sudo apt-ge…