(十三)MySQL锁机制

摘要:
2.锁的分类可以分为MySQL支持的表级锁、行级锁、页级锁和锁操作。它们可以分为读锁、写锁、乐观锁、悲观锁和悲观锁。修改数据库表结构将自动添加表级锁——元数据锁将更新数据未使用的索引,行级锁将升级为表级锁。使用索引更新数据将使用行级锁来选择…forupdate将使用行级别锁。3.表级锁使用MySQL Server层为每个操作锁定整个表。这是因为MVCC(用于行)机制,它由多个版本读取。

1.常见问题

  • MySQL支持的锁有哪些?有哪些使用场景?

    • 什么是读写锁?什么是排他锁?
    • 行锁是什么?有哪些分类,原理是什么?
  • 死锁是如何产生的?

    • 如何解决死锁?

2.锁的分类

从锁的粒度上分MySQL支持的锁

  • 表级锁
  • 行级锁(InnoDB)
  • 页级锁(BDB)

从锁的操作上可以分为

  • 读锁
  • 写锁

从实现方式上分

  • 乐观锁
  • 悲观锁

(十三)MySQL锁机制第1张

使用场景

  • 修改数据库表结构会自动加表级锁——元数据锁

  • 更新数据未使用索引,行级锁会上升为表级别锁

  • 更新数据使用索引会使用行级锁

  • select ... for update 会使用行级锁

3.表级锁的使用

MySQL Server 层实现
每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低
应用在MyISAM,InnoDB,BDB等存储引擎中。

MySQL的表级锁有两种:

  • 一种是表锁
  • 一种是元数据锁(meta data lock,MDL)

表锁有两种表现形式:

  • 表共享读锁(Table Read Lock)
  • 表独占写锁(Table Write Lock)

表读锁
(十三)MySQL锁机制第2张

表写锁
(十三)MySQL锁机制第3张

4.元数据锁

MDL(metaDataLock)元数据:表结构
在MySQL5.5 版本中引入了MDL,当对一个表做增删改查操作的时候,加MDL 读锁;当要对表结构变更操作的时候,加MDL写锁。

元数据读锁
(十三)MySQL锁机制第4张

5.行级锁

InnoDB实现
行级锁:每次操作锁住一行数据。锁粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。

RecordLock锁:锁定单个行记录的锁。RC,RR隔离级别都支持。

GapLock锁:间隙锁,锁定索引记录间隙,确保索引记录的间隙不变。RR隔离级别支持。

Next-key Lock锁:行锁和间隙锁组合,同时锁住数据,并且锁住数据前面的Gap。RR隔离级别支持。

行读锁
(十三)MySQL锁机制第5张

行读锁升级为表锁
(十三)MySQL锁机制第6张

常见行锁升级为表锁举例

session1:
  begin;
  update mylock set age=10 where name='y';
  commit;

name 没有索引,update会锁定整张mylock表,造成其他的访问mylock的请求全部等待

行写锁
(十三)MySQL锁机制第7张

3,session2:select * from mylock where id =1; --可以读 不加锁。是因为MVCC(针对行)机制,多版本读。
4,session2:select * from mylock where id =1 lock in share mode; --加了读锁,就会被阻塞(加写锁 for update 一样会被阻塞,单纯的select 是无锁的,才可以MVCC多版本读)。

6.什么是读写锁?什么是排他锁?

锁是计算机协调多个进程或者线程并发访问某一资源的机制。锁使用独占的方式来保证在只有一个版本的情况下事务之间相互隔离,所以锁可以理解为单版本控制。
引入锁之后就可以支持并行处理事务,如果事务之间涉及到相同的数据项时,会使用排他锁,或叫互斥锁,先进入的事务独占数据项以后,其他事务被阻塞,等待前面的事务释放锁。

读写锁,可以让读和读并行,而读和写,写和读,写和写这几种之间还是要加排他锁。

排他锁
引入锁之后就可以支持并行处理事务,如果事务之间涉及到相同的数据项时,会使用排他锁,或叫互斥锁,先进入的事务独占数据项以后,其他事务被阻塞,等待前面的事务释放锁。

(十三)MySQL锁机制第8张

注意,在整个事务1结束之前,锁是不会被释放的,所以,事务2必须等到事务1结束之后开始。

读写锁
读写锁,可以让读和读并行,而读和写,写和读,写和写这几种之间还是要加排他锁 。

如果几个事务之间没有共享数据项,完全可以并行被处理

(十三)MySQL锁机制第9张

7.行锁是什么?有那些分类,原理是什么?

InnoDB存储引擎实现,每次操作锁住一行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。

InnoDB的行级锁,按照锁定范围来说,分为三种:

  • RecordLock锁:锁定单个行记录的锁。RC,RR隔离级别都是支持。

  • GapLock锁:间隙锁,锁定索引记录间隙,确保索引记录的间隙不变,RR隔离级别支持。

  • Next-key Lock 锁:行锁和间隙锁组合,同时锁住数据,并且锁住数据前面的Gap。RR隔离级别支持。

行级锁分类
按照功能来说分为两种:

  • 共享读锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

  • 排他写锁(X):允许获得排他写锁的事务(当前获得锁的事务)更新数据,阻止其他事务取得相同数据集的共享读锁(是指select ... lock in share mode 不是单纯的select读,单纯的select读没有锁, 这里会采用MVCC机制)和排他写锁(DML(insert,update,delete),select ... for update)。

行锁原理

  • 主键加锁
    加锁行为:仅在id=10的主键索引记录录入加X锁。
    (十三)MySQL锁机制第10张

  • 唯一键加锁
    加锁行为:先在唯一索引id上加 id=10的X 锁,再在id=10的主键索引记录上加X锁。
    (十三)MySQL锁机制第11张

  • 非唯一键加锁
    加锁行为:对满足id=10条件的记录和主键分别加X锁,然后在(6,c)(10,b),(10,b)(10,d),(10,d)~(11,f)间隙分别加Gap锁。
    (十三)MySQL锁机制第12张

  • 无索引加锁
    加锁行为:表里面所有行和间隙均加X锁。由于InnoDB引擎行锁机制是基于索引实现记录锁定的,因此没有索引时会导致全表锁定,这点大家要特别注意。
    (十三)MySQL锁机制第13张

8.死锁是如何产生的?如何解决?

加锁是实现数据库并发控制的一个非常重要的技术。当两个事务的锁发生冲突,互相等待对方的锁释放,不能继续执行事务逻辑,就会出现死锁,严重影响应用的正常执行。

死锁的现象主要有:

  • 表锁死锁
  • 行级锁死锁
  • 共享锁转换为排他锁

表锁死锁
产生原因:用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这样死锁就产生了

解决方案:

  • 调整程序的逻辑
  • 尽量避免同时锁定两个资源

行级锁死锁
产生原因1:
在事务执行了一条不满足条件的 for update操作,则执行全表扫描,把行级锁上升为表级锁,多个这样的事务执行后,就很容易产生死锁和阻塞。

解决方案:SQL语句不要使用太复杂的关联多表的查询,优化索引。

产生原因2:
两个事务分别想拿到对方持有的锁,互相等待,于是产生死锁。

解决方案:
在同一个事务中,尽可能做到一次锁定所需要的所有资源
按照id对资源排序,然后按照顺序进行处理
采用MVCC机制处理

共享锁转换为排他锁
产生原因:
事务A查询一条记录,然后更新该条记录;
此时事务B也更新该条记录,这时事务B的排他锁由于事务A有共享锁,必须等A释放共享锁后才可以获取,只能排队等待,事务A再执行更新操作时,此处发生死锁,因为事务A需要排他锁来做更新操作。但是,无法授予该锁请求,因为事务B已经有一个排他锁请求,并且正在等待事务A 释放其共享锁。

(十三)MySQL锁机制第14张

解决方案:
避免引发同时对同一条记录多次操作
使用乐观锁进行控制

免责声明:文章转载自《(十三)MySQL锁机制》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Http自动跳转Https的接口测试实践利用Matlab自带的深度学习工具进行车辆区域检测与车型识别【福利-内附源码与数据库】(一)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

查询设计分析

一、查询设计的建议   在一些情况下,查询结构使优化器不能选择最好的处理策略。知道何时发生这种情况以及如何避免它是很重要的。这里主要介绍如下几点: 在小的结果集上操作; 有效使用索引; 避免优化器提示; 使用域和参照完整性; 避免资源密集型的查询; 减少网络传输数量; 减少事务开销; 二、在小结果集上操作   为了改进查询性能,应限制操作的数据量,包括...

my.cnf配置文件实用优化

[client] 1.登陆过程自动化(这样做可以让你在命令行登陆的时候免去输入用户名和密码) host="mysql服务器地址" user="用户名" password=“密码” 2.自动切换数据库(这样做可以避免每次进入都要use 某数据库) database="你的数据库名字" [mysqld] auto-rehash 启用TAB键自动补齐 skip-...

Oracle基础(九) Oracle的体系结构

一、Oracle体系结构概述:   Oracle的体系结构是指数据库的组成、工作过程与原理,以及数据在数据库中的组织与管理机制。要了解Oracle数据库的体系结构,必须理解Oracle系统的重要概念和主要组件。   Oracle系统体系结构由三部分组成:内存结构,进程结构,存储结构。。如下图所示:        1、内存结构(SGA、PAG)   内存结构...

mybatis查询oracle ’无效的列索引‘和ORA-00911’无效的字符‘错误

1、Caused by: java.sql.SQLException: 无效的列索引 参考文献:http://bbs.csdn.net/topics/300179772 配置的sql语句写错了 select distinct '#{pkgName}' as pkgName, '#{appName}' as app...

SQL优化

SQL优化   sql执行性能低、执行时间长、等待时间长、SQL语句欠佳(连接查询)、索引失效、服务器参数设置。 (1.)SQL解析过程: 编写过程:select distinct ... from ... join..on..where..group by...having...order 解析过程:from .. on.. join..where.....

十三、ES备份恢复

一、备份恢复方案 ES支持两种备份恢复方案,第一种是官方的工具snapshot,第二种是第三方工具elasticsearch-dump。 snapshot工具 官方提供的工具,也叫快照备份; 备份原理是需要一台存储服务器,这里使用nfs存储服务器,并将其挂载到各个节点上,snapshot工具会将每台ES数据分开备份在nfs服务器上。 备份数据无法直接查看...