Mysql数据库锁机制

一:概念介绍

MySQL数据库锁管理机制:

SQL层实现的锁机制
   Meta-data元数据锁:在table cache缓存里实现的,为DDL(Data Definition Language)提供隔离操作。一种特别的meta-data元数据类型,叫Name Lock。
   表级table-level数据锁
   全局读锁—FLUSH TABLES WITH READ LOCK

引擎层实现的锁机制
   存储引擎特有机制—row locks行锁,page locks页锁,table locks表级,版本控制

在这里插入图片描述

MySQL常用存储引擎的锁机制

  1. MyISAM 和 MEMORY 采用表级锁(table-level locking)
  2. BDB 采用页面锁(page-level locking)或表级锁,默认为页面锁
  3. InnoDB 支持行级锁(row-level locking)和表级锁, 默认为行级锁

锁分类

  1. 按思想:悲观锁、乐观锁
  2. 按锁粒度:行级锁、间隙锁、页级锁、表级锁
  3. 按锁性质:排它锁(X)、共享锁(S)、意向排它锁(IX)、意向共享锁(IS),读锁(一般为共享锁)、写锁(一般为排它锁)

其中,InnoDB是最常见的MySQL存储引擎,以下以它为例

二:Innodb 中的锁机制

Innodb 中的行锁与表锁

在 Innodb 引擎中既支持行锁也支持表锁,那么什么时候会锁住整张表,什么时候或只锁住一行呢?

InnoDB 行锁是通过给索引上的索引项加锁来实现的,这一点 MySQL 与 Oracle 不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB 这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB 才使用行级锁,否则,InnoDB 将使用表锁!

在分析锁冲突时, 可以检查 SQL 的执行计划, 以确认是否真正使用了索引。

为什么Innodb 会出现死锁

MyISAM 中是不会产生死锁的,因为 MyISAM 总是一次性获得所需的全部锁,要么全部满足,要么全部等待。而在 InnoDB 中,锁是逐步获得的,就造成了死锁的可能。

在 MySQL 中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条 sql 语句操作了主键索引,MySQL 就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL 会先锁定该非主键索引,再锁定相关的主键索引。 在 UPDATE、DELETE 操作时,MySQL 不仅锁定 WHERE 条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的 next-key locking。

当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。

Innodb的死锁处理:

在Innodb的事务管理和锁定机制中,有专门检测死锁的机制,会在系统中产生死锁之后的很短时间内就检测到该死锁的存在。

当Innodb检测到系统中产生了死锁之后,Innodb会通过相应的判断来选这产生死锁的两个事务中较小的事务来回滚,而让另外一个较大的事务成功完成。

Innodb行锁优化建议

  1. 尽可能让所有的数据检索都通过索引来完成,从而避免Innodb因为无法通过索引键加锁而升级为表级锁定
  2. 合理设计索引,让Innodb在索引键上面加锁尽可能准确,尽可能的缩小锁定范围,避免造成不必要的锁定而影响其他Query的执行
  3. 尽可能减少基于范围的数据检索过滤条件,避免间隙锁带来的负面影响而锁定了不该锁定的记录
  4. 尽量控制事务的大小,减少锁定的资源量和锁定时间长度
  5. 在业务环境允许的情况下,尽量使用较低级别的事务隔离,以减少MySQL因为实现事务隔离级别所带来的附加成本

如何预防死锁

有多种方法可以避免死锁,这里只介绍常见的三种

1、如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。

2、在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;

3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

三:锁分类

3.1 按思想

悲观锁、乐观锁,见之前写的博文

3.2 按粒度

行级锁
是MySQL中粒度最小的锁,所以发生锁定资源争用的概率也最小。
但是由于粒度最小,导致开销大,加锁慢,并且最容易死锁。

表级锁

表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免死锁问题。
当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并大度较低。

页级锁

页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间。另外,页级锁定和行级锁定一样,会发生死锁。
在MySQL数据库中,使用表级锁定的主要是MyISAM,Memory,CSV等一些非事务性存储引擎,而使用行级锁定的主要是Innodb存储引擎和NDBCluster存储引擎,页级锁定主要是BerkeleyDB存储引擎的锁定方式。

间隙锁

在这里插入图片描述

3.3 按性质

排它锁(exclusive lock)

排它锁又叫写锁,如果事务T对A加上排它锁,则其它事务都不能对A加任何类型的锁。获准排它锁的事务既能读数据,又能写数据。

用法:SELECTFOR UPDATE

共享锁(share lock)

共享锁又叫读锁,如果事务T对A加上共享锁,则其它事务只能对A再加共享锁,不能加其它锁。获准共享锁的事务只能读数据,不能写数据。

用法:SELECTLOCK IN SHARE MODE;

意向锁(share lock)

为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。

意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。

意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

四:并发事务处理带来的问题

✈ 更新丢失(Lost Update)
  当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题–最后的更新覆盖了由其他事务所做的更新。
  
✈ 脏读(Dirty Reads)
  一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致的状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此作进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象的叫做“脏读”。
  一句话:事务A读取到了事务B已经修改但尚未提交的数据,还在这个数据基础上做了操作。此时,如果B事务回滚,A读取的数据无效,不符合一致性要求。
  
✈ 不可重读(Non-Repeatable Reads)
  一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读”。
  一句话:事务A读取到了事务B已经提交的修改数据,不符合隔离性
  
✈ 幻读(Phantom Reads)
  一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。
  一句话:事务A读取到了事务B提交的新增数据,不符合隔离性

脏读是事务B里面修改了数据
幻读是事务B里面新增了数据

事务隔离级别
在这里插入图片描述

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

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

相关文章

干货|亲测有效的N倍学习效果笔记法

这里是Z哥的个人公众号每周五11:45 按时送达当然了,也会时不时加个餐~我的第「108」篇原创敬上大家好,我是Z哥。先祝大家中秋快乐。我猜你现在心情不错,毕竟小长假的第一天才开始,后面还有60个小时的假期&a…

.NET Core 3.0 可卸载程序集原理简析

文章转载授权级别:A 预计阅读时间:8分钟 损失发量:不好统计因为最近在群里被问到如何理解 .NET Core 3.0 可卸载程序集,所以就写了这篇简单的分析。因为时间实在很少,这篇文章只简单的罗列了相关的代码&…

.NetCore技术研究-ConfigurationManager在单元测试下的坑

最近在将原有代码迁移.NET Core, 代码的迁移基本很快,当然也遇到了不少坑,重构了不少,后续逐步总结分享给大家。今天总结分享一下ConfigurationManager遇到的一个问题。先说一下场景:迁移.NET Core后,已有的配置文件&a…

分析一次double强转float的翻车原因

人逢喜事精神爽,总算熬到下班撩~~正准备和同事打个招呼回家,被同事拖住问了.?‍♂️: 你们组做的那块代码,把double类型数据成float有问题啊?.?‍♀️: 嗯?不对是正常啊,float精度是没有double高,但float能保存到小数点后好多位,对我们来说完全够用了!?‍♂️: 不是啊,这不…

.NET Core 3.0之深入源码理解Host(二)

写在前面停了近一个月的技术博客,随着正式脱离996的魔窟,接下来也正式恢复了。本文从源码角度进一步讨论.NET Core 3.0 中关于Host扩展的一些技术点,主要内容是关于创建Long Run Program的创建与守护。关于Host,我们最容易想到的就…

dotNET Core实现分布式环境下的流水号唯一

业务背景在管理系统中,很多功能模块都会涉及到各种类型的编号,例如:流程编号、订单号、合同编号等等。编号各有各自的规则,但通常有一个流水号来确定编号的唯一性,保证流水号的唯一,在不同的环境中实现方式…

认证方案之初步认识JWT

前言:现在越来越多的项目或多或少会用到JWT,为什么会出现使用JWT这样的场景的呢?假设现在有一个APP,后台是分布式系统。APP的首页模块部署在上海机房的服务器上,子页面模块部署在深圳机房的服务器上。此时你从首页登录…

Java实现生产消费模型的5种方式

** 前言 ** 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间为空时,消费者阻塞,当存储…

Leetcode 86. 分隔链表

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。示例:输入: head 1->4->3->2->5->2, x 3输出: 1->2->2->4->3->5题目分析…

深入理解 JVM Class文件格式(一)

** 一、JVM体系结构 ** ** 二、class格式文件概述 ** class文件是一种8位字节的二进制流文件, 各个数据项按顺序紧密的从前向后排列, 相邻的项之间没有间隙, 这样可以使得class文件非常紧凑, 体积轻巧, 可以被J…

深入理解 JVM Class文件格式(二)

** class文件中的特殊字符串 ** 特殊字符串是常量池中符号引用的一部分,包括三种: 类的全限定名, 字段和方法的描述符, 特殊方法的方法名。 下面我们就分别介绍这三种特殊字符串。 (1) 类的全限定名 在…

.NET框架之“小马过河”

.NET框架之“小马过河”有许多流行的 .NET框架,大家都觉得挺“重”,认为很麻烦,重量级,不如其它“轻量级”框架,从而不愿意使用。面对形形色色的框架发愁,笔者也曾发愁。但我发现只要敢于尝试,这…

深入理解 JVM Class文件格式(三)

** JVM常量池中各数据项类型详解 ** 关于常量池的大概内容, 已经在 深入理解 JVM Class文件格式(一) 中讲解过了, 这篇文章中还介绍了常量池中的11种数据类型。 本文的任务是详细讲解这11种数据类型, 深度剖析源文件…

深入理解 JVM Class文件格式(四)

(3)CONSTANT_Integer_info 一个常量池中的CONSTANT_Integer_info数据项, 可以看做是CONSTANT_Integer类型的一个实例。 它存储的是源文件中出现的int型数据的值。 同样, 作为常量池中的一种数据类型, 它的第一个字节也是一个tag值…

.Net Core中使用Quartz.Net Vue开即用的UI管理

Quartz.NETQuartz.Net 定制UI维护了常用作业添加、删除、修改、停止、启动功能,直接使用cron表达式设置作业执行间隔,有完整的日志记录。Quartz.NET是一个功能齐全的开源作业调度系统,可用于从最小的应用程序到大型企业系统。Quartz.NET是一个…

深入理解 JVM Class文件格式(五)

(8) CONSTANT_Class_info 常量池中的一个CONSTANT_Class_info, 可以看做是CONSTANT_Class数据类型的一个实例。 他是对类或者接口的符号引用。 它描述的可以是当前类型的信息, 也可以描述对当前类的引用, 还可以描述对…

混沌工程详细介绍——Netflix持续交付实践探寻

内容来源:DevOps案例深度研究 – Netflix的文化与工程实践战队(本文只展示部分案例PPT及研究成果,更多细节请关注案例分享活动,及本公众号)。本案例内容贡献者:高金梅,李晓莉,潘雄鹰…

深入理解 JVM Class文件格式(六)

经过前几篇文章, 终于将常量池介绍完了, 之所以花这么大的功夫介绍常量池, 是因为对于理解class文件格式,常量池是必须要了解的, 因为class文件中其他地方,大量引用了常量池中的数据项。 对于还不了解常量池…

远程开发初探 - VS Code Remote Development

如果你是学生,你还在你的 windows 电脑上为各种环境配置头疼的时候,你应该了解一下 Remote Development。如果你喜欢 linux 的开发环境和舒适的 shell,但却不舍得抛弃 windows/macos 图形界面给你带来的用户体验和一些软件的兼容(QQ, 微信), …

深入理解 JVM Class文件格式(七)

本专栏列前面的一系列博客, 对Class文件中的一部分数据项进行了介绍。 本文将会继续介绍class文件中未讲解的信息。 先回顾一下上面一篇文章。 在上一篇博客中, 我们介绍了: this_class 对当前类的描述 super_class 对当前类的超类的描述 in…