一、前言

MySQL 的锁按照范围可以分为全局锁、表锁、行锁,其中行锁是由数据库引擎实现的,并不是所有的引擎都提供行锁,MyISAM 就不支持行锁,所以文章介绍行锁会以InnoDB引擎为例来介绍。

二、全局锁

MySQL 提供全局锁来对整个数据库实例加锁。

语法:

FLUSH TABLES WITH READ LOCK

这条语句一般都是用来备份的,当执行这条语句后,数据库所有打开的表都会被关闭,并且使用全局读锁锁定数据库的所有表,同时,其他线程的更新语句(增删改),数据定义语句(建表,修改表结构)和更新类的事务提交都会被阻塞。

在mysql 8.0 以后,对于备份,mysql可以直接使用备份锁。

语句:

LOCK INSTANCE FOR BACKUP

UNLOCK INSTANCE

这个锁的作用范围更广,这个锁会阻止文件的创建,重命名,删除,包括 REPAIR TABLE TRUNCATE TABLE, OPTIMIZE TABLE操作以及账户的管理都会被阻塞。当然这些操作对于内存临时表来说是可以执行的,为什么内存表不受这些限制呢?因为内存表不需要备份,所以也就没必要满足这些条件。

三、表锁

Mysql的表级别锁分为两类,一类是元数据锁(Metadata Lock,MDL),一种是表锁。

元数据锁(MDL) 不需要显式使用,在访问一个表的时候会被自动加上。这个特性需要MySQL5.5版本以上才会支持,当对一个表做增删改查的时候,该表会被加MDL读锁;当对表做结构变更的时候,加MDL写锁。MDL锁有一些规则:

读锁之间不互斥,所以可以多线程多同一张表进行增删改查。

读写锁、写锁之间是互斥的,为了保证表结构变更的安全性,所以如果要多线程对同一个表加字段等表结构操作,就会变成串行化,需要进行锁等待。

MDL的写锁优先级比MDL读锁的优先级,但是可以设置max_write_lock_count系统变量来改变这种情况,当写锁请求超过这个变量设置的数后,MDL读锁的优先级会比MDL写锁的优先级高。(默认情况下,这个数字会很大,所以不用担心写锁的优先级下降)

MDL的锁释放必须要等到事务结束才会释放

所以我们在操作数据库表结构时候必须要注意不要使用长事务,这里具体是什么意思呢?我举个例子说明下:

上图表示演示了4个session执行语句,首先SessionA开启了事务没有提交,接着sessionB执行查询,因为是获取MDL读锁,所以互相不影响,可以正常执行,SessionC新增一个字段,由于MDL写和读是互斥的,所以SessionC会被阻塞,之后SessionD开始执行一个查询语句,由于SessionC的阻塞,所以SessionD也阻塞了。所以,我们模拟的SessionA的事务是长事务,然后后面执行了修改表结构,会导致后续对该表所有的读写操作都不可行了。所以在实际场景中,如果业务请求比较频繁的时候,对表结构进行修改的时候就有可能导致该库的线程被阻塞满。

表锁 的语法如下:

LOCK TABLES

tbl_name [[AS] alias] lock_type

[, tbl_name [[AS] alias] lock_type] ...

lock_type: {

READ [LOCAL]

| [LOW_PRIORITY] WRITE

}

UNLOCK TABLES

表锁分为读锁和写锁,读锁不互斥,但是获取读锁不能写入数据,其他没有获取到读锁的session也是可以读取表的,所以读锁的目的就是限制表被写。如果表被读锁锁住后,再执行插入语句会报错,报错如下:

1099 - Table 'XXXX' was locked with a READ lock and can't be updated

写锁被获取后可以对表进行读写,写锁是互斥的,一旦某个session获取到表的写锁,另外的session无法访问这个表,直到写锁被释放。

表的解锁可以使用unlock tables解锁,也可以客户端口自动解锁。lock tables锁表会独占式的锁住表,除了限制其他线程对该表的读写,也会限制本线程接下来的操作对象。

四、行锁(InnoDB)

MySQL的行锁是在引擎层面实现的,所以这里讨论的也是InnoDB引擎下的行锁,下面会详细介绍InnoDB下常见的几种行锁

4.1 共享锁

共享锁能允许事务获取到锁后进行读操作,共享锁是不互斥的,一个事务获取到共享锁后,另外一个事务也可以获取共享锁,获取共享锁后不能进行写操作。

4.2 排它锁

排他锁允许事务获取到锁后进行更新一行或者删除某一行操作,排他锁顾名思义是互斥的,一个事务获取到排他锁后,其他事务不能获取到排他锁,直到这个锁被释放。

4.3 意向锁

InnoDB支持多种粒度的锁,允许行锁和表锁共存,这里说的意向锁其实是一种表级别的锁,但是我把它放在行锁里面是因为它不会单独存在,它的出现肯定会伴随着行锁(共享锁或者排他锁),它主要的目的就是表示将要锁定表中的行或者正在锁定表中的行。

意向锁根据和行锁的组合可以分为:

意向排他锁:表明将要在表中的某些行获取排他锁

意向共享锁:表明将要在表中的某些行获取共享锁

意向锁的获取必须在行锁获取之前,也就是说获取共享锁之前必须先要获取共享意向锁,对于排他锁也是一样的道理。

那么这个意向锁到底有什么作用呢?

解释这个之前,我们先看看意向锁和行锁之前的兼容关系:

排他锁(X)

意向排他锁(IX)

共享锁(S)

意向共享锁(IS)

排他锁(X)

冲突

冲突

冲突

冲突

意向排他锁(IX)

冲突

兼容

冲突

兼容

共享锁(S)

冲突

冲突

兼容

兼容

意向共享锁(IS)

冲突

兼容

兼容

兼容

我们假设有2个事务A和事务B,事务获取到了共享锁,锁住了表中的某一行,这一行只能读,不能写,现在事务B要申请整个表的写锁。如果事务B申请成功,那么肯定是可以对表中所有的行进行写操作的,那么肯定与A获取的行锁冲突。数据库为了避免这种冲突,就会进行冲突检测,那么如何去检测呢?有两种方式:

判断表是否已经被其他事务用表级锁锁住。

判断表中的每一行是否被行锁锁住。

判断表中的每一行需要遍历所有记录,效率太差,所以数据库就用第一种方式去做冲突检测,也就是用到了意向锁。

总结

本文主要从MySQL的加锁范围来分析了MySQL的锁,MySQL根据加锁范围可以分为全局锁、表锁、行锁。全局锁和表锁是MySQL自己实现,行锁都是由引擎层面去实现。InnoDB下的行锁主要分为共享锁和排他锁。共享锁请求后,行只能读,共享锁之间不互斥。排他锁获取后能更新和删除行,排他锁与其他锁都互斥。最后我在行锁的基础上提到了意向锁,意向锁主要表示正在锁住行或者即将锁住行,为了在锁冲突检测中提高效率。当然InnoDB下还有其他锁,比如间隙锁,记录锁,Next-Key锁等,这些都不在本文的探讨范围之内,如有兴趣的同学可以自行研究。

怎么算掌握了mysql_MySQL你必须掌握了解的锁知识!相关推荐

  1. 怎么算掌握了mysql_mysql 需要掌握的重点

    1. 安装mysql: google it. 2. 新建database,table: create database database_name; create table table_name; ...

  2. 【科普】超算到底是咋算的?

        最近一段时间,有关超算的话题成为热门,一时间大家都开始讨论超算,各种浮于表面的吹牛,逼格负无穷的装逼.然而,冬瓜哥发现在所有这些讨论中,从没有在任何时间任何地点发现任何人问出就连小学生都经常问 ...

  3. 从算筹算盘到计算机教案,三年级数学下册 从算筹、算盘到计算器教案 沪教版...

    <三年级数学下册 从算筹.算盘到计算器教案 沪教版>由会员分享,可在线阅读,更多相关<三年级数学下册 从算筹.算盘到计算器教案 沪教版(2页珍藏版)>请在人人文库网上搜索. 1 ...

  4. n维椭球体积公式_混凝土工程量计算规则及公式

    ▶下载微试验APP ▶发布招聘 点击进入"微试验_视频课件+题库复习+模拟考试"学习 混凝土垫层工程量计算规则及公式 1.条形基础砼垫层计算公式  外墙条基砼垫层体积=外墙条形基础 ...

  5. Zookeeper和Redis实现分布式锁,附我的可靠性分析

    作者:今天你敲代码了吗 链接:https://www.jianshu.com/p/b6953745e341 在分布式系统中,为保证同一时间只有一个客户端可以对共享资源进行操作,需要对共享资源加锁来实现 ...

  6. Redisson实现Redis分布式锁的N种姿势

    点击蓝色"程序猿DD"关注我哟 来源:阿飞的博客 前几天发的一篇文章<Redlock:Redis分布式锁最牛逼的实现>,引起了一些同学的讨论,也有一些同学提出了一些疑问 ...

  7. 程序员需要牢记的一点

    2019独角兽企业重金招聘Python工程师标准>>> 对于一个程序员,需要学习的知识很多,但有一点感觉是需要牢记的: 用尽一切办法了解自己所做的,包括业务和技术,那你会在这个阶段做 ...

  8. 成为Java GC专家(5)—Java性能调优原则

    2019独角兽企业重金招聘Python工程师标准>>> 这是"成为Java GC专家"系列的第五篇文章.在第一篇深入浅出Java垃圾回收机制中,我们已经学习了不同 ...

  9. 浅谈“知识蒸馏”技术在机器学习领域的应用

    什么是知识蒸馏技术? 知识蒸馏技术首次出现是在Hinton几年前的一篇论文<Distilling the Knowledge in a Neural Network>.老大爷这么大岁数了还 ...

最新文章

  1. mysql_connect() 不支持 请检查 mysql 模块是否正确加载
  2. java正则表达式 过滤特殊字符的正则表达式
  3. 多项式加法 java 链表_多项式加法,用单链表实现。
  4. 深入理解JavaScript系列(33):设计模式之策略模式
  5. html正则表达式的书写,前端正则表达式书写及常用的方法
  6. 七招挽回受损WORD文档
  7. 文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别
  8. 秒懂,手机射频芯片有卵用 (zz)
  9. 实际参数列表和形式参数列表长度不同_Dynamo参数化轴网,这些对你很有帮助
  10. 运行Android项目时指定特定的AVD进行测试
  11. dropify插件的字符串
  12. 【洛谷1985】【USACO07OPEN】翻转棋
  13. linux多媒体音频架构
  14. 寻找 IT 服务行业隐形冠军, 航天信息上市十年再造中国梦
  15. 使用pygame制作双人五子棋小游戏
  16. MOOC《Python语言程序设计》第6周练习题
  17. 阿里云服务器一年多少钱?最便宜的一年
  18. C语言中:的其中一种作用
  19. 【NOIP2013】华容道 最短路优化搜索(spfa)
  20. CloudDrive不能用了还有其他方法么

热门文章

  1. Android无线调试——抛开USB数据线
  2. ASP.NET MVC3 异步刷新
  3. NFS无法启动根文件系统的解决
  4. JavaScript 正则表达式(RegExp对象、属性、方法、String支持)
  5. Ext 1.0 简要说明 类继承关系图
  6. 单机单网卡最大tcp长连接数真的是65535吗?
  7. unity消息队列判断字符串相等有错误_Python3十大经典错误及解决办法
  8. 编写一个项目开发文档
  9. 华为mate20能用鸿蒙吗,华为mate20可以用5g网络吗
  10. python pyqt5安装_Python3 安装PyQt5及exe打包图文教程