电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

面试必会系列之MySQL锁

10页
  • 卖家[上传人]:y****1
  • 文档编号:217548573
  • 上传时间:2021-12-03
  • 文档格式:DOCX
  • 文档大小:24.97KB
  • / 10 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 1、面试必会系列之MySQL锁相关内容序言:文章内容适用于每一个学习后端编程的朋友详细总结了一下MySQL锁相关的知识,分享给大家MySQL的锁概述数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外。MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎所针对的应用场景特点都不太一样,为了满足各自特定应用场景的需求,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别。本文没有说明的情况下默认使用的是Innodb引擎。Innodb原理(简单说一下 innodb一定存在聚簇索引,默认以主键作为聚簇索引 有几个索引,就有几棵B+树(不考虑hash索引的情形) 聚簇索引的叶子节点为磁盘上的真实数据。非聚簇索引的叶子节点还是索引,指向聚簇索引B+树。 锁的分类 共享锁(S锁): 假设事务T1对数据A加上共享锁,那么事务T2可以读数据A,不能修改数据A。 排他锁(X锁): 假设事务T1对数据A加上排他锁,那

      2、么事务T2不能读数据A,不能修改数据A。我们通过update、delete等语句加上的锁都是行级别的锁。只有LOCK TABLE READ和LOCK TABLE WRITE才能申请表级别的锁。 意向共享锁(IS锁): 一个事务在获取(任何一行/或者全表)S锁之前,一定会先在所在的表上加IS锁。 意向排他锁(IX锁): 一个事务在获取(任何一行/或者全表)X锁之前,一定会先在所在的表上加IX锁。 意向锁存在的目的这里说一下意向锁存在的目的。假设事务T1,用X锁来锁住了表上的几条记录,那么此时表上存在IX锁,即意向排他锁。那么此时事务T2要进行LOCK TABLE WRITE的表级别锁的请求,可以直接根据意向锁是否存在而判断是否有锁冲突。加锁算法 Record Locks: 简单翻译为行锁。注意了,该锁是对索引记录进行加锁!锁是加在索引上而不是行上的。注意了,innodb一定存在聚簇索引,因此行锁最终都会落到聚簇索引上! Gap Locks: 简单翻译为间隙锁,是对索引的间隙加锁,其目的只有一个,防止其他事物插入数据。在Read Committed隔离级别下,不会使用间隙锁。这里我对官网补

      3、充一下,隔离级别比Read Committed低的情况下,也不会使用间隙锁,如隔离级别为Read Uncommited时,也不存在间隙锁。当隔离级别为Repeatable Read和Serializable时,就会存在间隙锁。 Next-Key Locks: 这个理解为Record Lock+索引前面的Gap Lock。记住了,锁住的是索引前面的间隙!比如一个索引包含值,10,11,13和20。那么,间隙锁的范围如下12345(negative infinity, 10(10, 11(11, 13(13, 20(20, positive infinity)还有不懂的地方可以看一下MySQL的官方文档快照读和当前读在mysql中select分为快照读和当前读,执行下面的语句select * from table where id = ?;执行的是快照读,读的是数据库记录的快照版本,是不加锁的。(这种说法在隔离级别为Serializable中不成立,后面会再补充。)那么,执行select * from table where id = ? lock in share mode;会对读取记录

      4、加S锁 (共享锁),执行select * from table where id = ? for update会对读取记录加X锁 (排他锁),那么加的是表锁还是行锁呢?表锁or行锁 针对这点,我们先回忆一下事务的四个隔离级别,他们由弱到强如下所示: Read Uncommited(RU): 读未提交,一个事务可以读到另一个事务未提交的数据! Read Committed (RC): 读已提交,一个事务可以读到另一个事务已提交的数据! Repeatable Read (RR): 可重复读,加入间隙锁,一定程度上避免了幻读的产生!注意了,只是一定程度上,并没有完全避免!另外就是记住从该级别才开始加入间隙锁(这句话记下来,后面有用到)! Serializable: 串行化,该级别下读写串行化,且所有的select语句后都自动加上lock in share mode,即使用了共享锁。因此在该隔离级别下,使用的是当前读,而不是快照读。 那么关于是表锁还是行锁,大家可以看到网上最流传的一个说法是这样的InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过

      5、在数据块中对相应数据行加锁来实现的。 InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!这句话大家可以搜一下,都是你抄我的,我抄你的。那么,这句话本身有两处错误!错误一: 并不是用表锁来实现锁表的操作,而是利用了Next-Key Locks,也可以理解为是用了行锁+间隙锁来实现锁表的操作!为了便于说明,我来个例子,假设有表数据如下,pId为主键索引pId(int)name(varchar)num(int)1aaa1002bbb2007ccc200执行语句(name列无索引)select * from table where name = aaa for update那么此时在pId=1,2,7这三条记录上存在行锁(把行锁住了)。另外,在(-,1)(1,2)(2,7)(7,+)上存在间隙锁(把间隙锁住了)。因此,给人一种整个表锁住的错觉!ps: 对该结论有疑问的,可自行执行show engine innodb status;语句进行分析。错误二: 所有文章都不提隔离级别!注意上面说的,之所以能够锁表,是通过行锁+间隙锁来

      6、实现的。那么,RU和RC都不存在间隙锁,这种说法在RU和RC中还能成立么?因此,该说法只在RR和Serializable中是成立的。如果隔离级别为RU和RC,无论条件列上是否有索引,都不会锁表,只锁行!分析 下面来对开始的问题作出解答,假设有表如下,pId为主键索引pId(int)name(varchar)num(int)1aaa1002bbb2003bbb3007ccc200RC/RU+条件列非索引1. select * from table where num = 200不加任何锁,是快照读。 2. select * from table where num 200不加任何锁,是快照读。 3. select * from table where num = 200 lock in share mode当num = 200,有两条记录。这两条记录对应的pId=2,7,因此在pId=2,7的聚簇索引上加行级S锁,采用当前读。 4. select * from table where num 200 lock in share mode当num 200,有一条记录。这条记录对应的pId=

      7、3,因此在pId=3的聚簇索引上加上行级S锁,采用当前读。 5. select * from table where num = 200 for update当num = 200,有两条记录。这两条记录对应的pId=2,7,因此在pId=2,7的聚簇索引上加行级X锁,采用当前读。 6. select * from table where num 200 for update当num 200,有一条记录。这条记录对应的pId=3,因此在pId=3的聚簇索引上加上行级X锁,采用当前读。 RC/RU+条件列是聚簇索引恩,大家应该知道pId是主键列,因此pId用的就是聚簇索引。此情况其实和RC/RU+条件列非索引情况是类似的。1. select * from table where pId = 2不加任何锁,是快照读。 2. select * from table where pId 2不加任何锁,是快照读。 3. select * from table where pId = 2 lock in share mode在pId=2的聚簇索引上,加S锁,为当前读。 4. select * fro

      8、m table where pId 2 lock in share mode在pId=3,7的聚簇索引上,加S锁,为当前读。 5. select * from table where pId = 2 for update在pId=2的聚簇索引上,加X锁,为当前读。 6. select * from table where pId 2 for update在pId=3,7的聚簇索引上,加X锁,为当前读。 为什么条件列加不加索引,加锁情况是一样的?其实是不一样的。在RC/RU隔离级别中,MySQL Server做了优化。在条件列没有索引的情况下,尽管通过聚簇索引来扫描全表,进行全表加锁。但是,MySQL Server层会进行过滤并把不符合条件的锁当即释放掉,因此你看起来最终结果是一样的。但是RC/RU+条件列非索引比本例多了一个释放不符合条件的锁的过程!RC/RU+条件列是非聚簇索引我们在num列上建上非唯一索引。此时有一棵聚簇索引(主键索引,pId)形成的B+索引树,其叶子节点为硬盘上的真实数据。以及另一棵非聚簇索引(非唯一索引,num)形成的B+索引树,其叶子节点依然为索引节点,保存了

      9、num列的字段值,和对应的聚簇索引。接下来分析开始1. select * from table where num = 200不加任何锁,是快照读。 2. select * from table where num 200不加任何锁,是快照读。 3. select * from table where num = 200 lock in share mode当num = 200,由于num列上有索引,因此先在 num = 200的两条索引记录上加行级S锁。接着,去聚簇索引树上查询,这两条记录对应的pId=2,7,因此在pId=2,7的聚簇索引上加行级S锁,采用当前读。 4. select * from table where num 200 lock in share mode当num 200,由于num列上有索引,因此先在符合条件的 num = 300的一条索引记录上加行级S锁。接着,去聚簇索引树上查询,这条记录对应的pId=3,因此在pId=3的聚簇索引上加行级S锁,采用当前读。 5. select * from table where num = 200 for update当num = 200,由于num列上有索引,因此先在 num = 200的两条索引记录上加行级X锁。接着,去聚簇索引树上查询,这两条记录对应的pId=2,7,因此在pId=2,7的聚簇索引上加行级X锁,采用当前读。 6. sel

      《面试必会系列之MySQL锁》由会员y****1分享,可在线阅读,更多相关《面试必会系列之MySQL锁》请在金锄头文库上搜索。

      点击阅读更多内容
    最新标签
    监控施工 信息化课堂中的合作学习结业作业七年级语文 发车时刻表 长途客运 入党志愿书填写模板精品 庆祝建党101周年多体裁诗歌朗诵素材汇编10篇唯一微庆祝 智能家居系统本科论文 心得感悟 雁楠中学 20230513224122 2022 公安主题党日 部编版四年级第三单元综合性学习课件 机关事务中心2022年全面依法治区工作总结及来年工作安排 入党积极分子自我推荐 世界水日ppt 关于构建更高水平的全民健身公共服务体系的意见 空气单元分析 哈里德课件 2022年乡村振兴驻村工作计划 空气教材分析 五年级下册科学教材分析 退役军人事务局季度工作总结 集装箱房合同 2021年财务报表 2022年继续教育公需课 2022年公需课 2022年日历每月一张 名词性从句在写作中的应用 局域网技术与局域网组建 施工网格 薪资体系 运维实施方案 硫酸安全技术 柔韧训练 既有居住建筑节能改造技术规程 建筑工地疫情防控 大型工程技术风险 磷酸二氢钾 2022年小学三年级语文下册教学总结例文 少儿美术-小花 2022年环保倡议书模板六篇 2022年监理辞职报告精选 2022年畅想未来记叙文精品 企业信息化建设与管理课程实验指导书范本 草房子读后感-第1篇 小数乘整数教学PPT课件人教版五年级数学上册 2022年教师个人工作计划范本-工作计划 国学小名士经典诵读电视大赛观后感诵读经典传承美德 医疗质量管理制度 2
    关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
    手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
    ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.