本文整理自网络,侵删。
目录
- 前言
- 1.什么是锁
- 2.InnoDB存储引擎中的锁
- 2.1锁的类型
- 2.2 一致性非锁定读
- 2.3 一致性锁定读
- 3 锁的算法
- 3.1行锁的3中算法
- 总结
前言
自7月份换工作以来,期间一直在学习MySQL的相关知识,听了一些视频课,但是一直好奇那些讲师的知识是从哪里学习的。于是想着从书籍中找答案。毕竟一直
看视频也不是办法,不能形成自己的知识。于是想着看书汲取知识,看了几本MySQL的相关书籍,包括《深入浅出Mysql》《高性能Mysql》《Mysql技术内幕》,发现那些讲
师讲的内容确实都在书上有出现过,于是确信看书才是正确的汲取知识方式。本片主要记录了Mysql的锁机制的学习。
1.什么是锁
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。
如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。
相对其他数据库而言,MySQL 的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level
locking);BDB存储引擎采用的是页面锁(page-levellocking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-levellocking),也支持表级锁,但默认情况下是采用行级锁。
MySQL这3种锁的特性可大致归纳如下。
- 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
- 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
- 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
3种锁的使用角度:
- 表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;
- 行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。
- BDB的页面锁已经被InnoDB取代,不做讨论。
2.InnoDB存储引擎中的锁
2.1锁的类型
InnoDB存储引擎实现了如下两种标准的行级锁:
- 共享锁(S Lock),允许事务读一行数据。
- 排他锁(X Lock),允许事务删除或更新一行数据。
如果一个事务T1已经获得了行r的共享锁,那么另外的事务T2可以立即获得行r的共享锁,因为读取没有改变行r的数据,称这种情况
为锁兼容(Lock Compatible)。但若有其他的事务T3想获得行r的排他锁,则其必须等待事务T1、T2释放行r的共享锁——这种情况称为锁不兼容。
X | S | |
---|---|---|
X | 不兼容 | 不兼容 |
S | 不兼容 | 兼容 |
此外,InnoDB存储引擎支持多粒度锁定,这种锁定允许事务在行级上锁和表锁上的锁同时存在。为了支持在不同粒度上进行加锁操作,InnoDB存
储引擎支持一种额外的锁方式,称之为意向锁。意向锁是将锁定的对象分为多个层次,意向锁意味着事务希望在更细粒度上进行加锁。 InnoDB存
储引擎支持意向锁设计比较简练,其意向锁即为表级别的锁。设计目的主要是为了在一个事务中揭示下一行将被请求的锁类型。其支持两种意向锁:
- 意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁
- 意向排他锁(IX Lock),事务想要获得一张表中某几行的排他锁
2.2 一致性非锁定读
一致性的非锁定读(consistant nonlocking read)是指InnoDB存储引擎通过多版本控制(multi versioning)的方法来读取当前执行时间数据库中行的
数据。如果读取的行正在执行Delete或Update操作,这时读取操作不会因此去等待行上锁的释放。相反地,InnoDB存储引擎会去读取行的一个快照
版本。如下如所示。
上图直观地展现了InnoDB存储引擎一致性的非锁定读。之所以称为非锁定读,因为不需要等待访问的行上X锁的释放。快照数据是指该行的之前版本
的数据,该实现是通过undo段来完成。而undo用来在事务中回滚数据,因此快照数据本身是没有额外的开销。此外,读取快照数据是不需要上锁的,
因为没有事务需要对历史的数据进行修改操作。
通过上图可以知道,快照数据其实就是当前行数据之前的历史版本,每行记录可能有多个版本,一般称这种技术为行多版本技术。由此带来的并发控制,
称之为多版本并发控制(Multi Version Concurrency Control, MVCC)。
在事务隔离级别READ COMMITTED和REPEATABLE READ下,InnoDB存储引擎使用非锁定的一致性读。然而,对于快照数据的定义却不相同。在READ
COMMITTED事务隔离级别下,对于快照数据,非一致性读总是读取被锁定行的最新一份快照数据。而在REPEATABLE READ事务隔离级别下,对于快照
数据,非一致性读总是读取事务开始时的行数据版本。如下表所示示例:
时间 | 会话A | 会话B |
---|---|---|
1 | begin | |
2 | select * from t_user where id = 1; | |
3 | begin | |
4 | update t_user set id = 10 where id = 1; | |
5 | select * from t_user where id = 1; | |
6 | commit; | |
7 | select * from t_user where id = 1; | |
8 | commit; |
假设原本id = 1的记录是存在的,大家可以按上表时间顺序执行对应的会话,比较及验证2者的不同。
2.3 一致性锁定读
在默认配置下,在事务的隔离级别为REPEATABLE READ模式下,InnoDB存储引擎的select操作使用一致性非锁定读。但是在某些情况下,用户需要显示地
对数据库读取操作进行加锁以保证数据逻辑的一致性。而这要求数据库支持加锁语句,即使时对于select的只读操作。InnoDB存储引擎对于select语句支持两
相关阅读 >>
mysql5.7.14下载安装图文教程及mysql数据库语句入门大全
更多相关阅读请进入《mysql》频道 >>

数据库系统概念 第6版
机械工业出版社
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。
转载请注明出处:木庄网络博客 » Mysql技术内幕之InnoDB锁的深入讲解
相关推荐
评论
管理员已关闭评论功能...