MySQL锁机制总结(二)
前言:
Mysql是一个支持插件式存储引擎的数据库系统,本文讨论的锁机制也主要包含两部分SERVER层的锁和存储引擎的锁,存储引擎是指innodb,其它存储引暂不讨论。
1. 数据库中锁相关的基本概念
1) 乐观锁,悲观锁
乐观锁和悲观锁都是一种并发控制策略。悲观锁假定多个事务会同时访问同一个资源,采用的策略是“先上锁,后访问”,这种策略会有死锁的风险。乐观锁相对于悲观锁而言,假定多个事务在运行过程中不会相互影响,写入在读取和写入记录时,不上锁,取而代之是产生一个时间戳或版本号,事务提交阶段,检查记录的版本号是否有被修改(若修改,则表示有其他事务读写),确定是否需要回滚事务。目前在数据库领域,几乎所有的DBMS都是采用悲观锁机制。
2) MVCC(Multi-Version Concurrency Control)
MVCC也是一种并发控制方法,MVCC对悲观锁控制机制做了改进,通过冗余数据的历史版本,达到“读不上锁,读写不冲突”的效果,提高了并发效果。MVCC主要作用于读提交和可重复读两种隔离级别上。
3) 两阶段锁协议
所谓两段锁协议是指上锁分为两个阶段,加锁和解锁阶段,保证加锁和解锁阶段不交错。对于数据库系统而言,事务开始时,处于加锁阶段;事务提交或rollback时,事务进入解锁阶段。只有满足两段锁协议的数据库系统,并发调度的事务才是可以串行化的。
4) 意向锁
意向锁机制约定如果对一个节点加锁,必需先对它的上一层节点加意向锁。比如,对一个记录加锁之前,首先对该记录所在的表加意向锁。意向锁主要包括IS和IX,他们与S和X的兼容关系不在这里赘述。意向锁的主要作用在于提高表锁和行锁冲突检测效率。
5) 表锁,记录(行)锁
表锁和记录锁是锁系统里面最基本的锁。分别用于锁定表和记录。对于表而言,根据情况可以有S,X,IS和IX四种锁类别;对表上IS和IX,表示需要读记录和写记录;记录锁则主要包括X锁和S锁。有关行锁的实现,可以参考之前的文章,INNODB行锁源码学习
6) 字典锁(metadata lock)
字典锁是保护元数据的一种锁,主要为了防止DDL和DML冲突的情况。有关MDL的详细介绍,可以参考之前的文章,MYSQL METADATA LOCK
7) 死锁
所谓死锁是指两个或多个事务,各自占有对方的期望获得的资源,形成的循环等待,彼此无法继续执行的一种状态。
2. 举个栗子
上面列了这么多种类的锁,下面通过一个简单的例子说明各种锁是如何作用的,它们加锁和释放锁的先后顺序如何。这里假设隔离级别是RC,ID为主键。
begin:
update t3 set c1=1 where id=1;
commit;
|
流程 |
执行语句 |
执行内容 |
字典锁 |
行锁/表锁 |
|
1 |
Begin |
释放MDL release_transactional_locks |
释放表锁,行锁 |
|
|
2 |
update t3 set c1=1 where id=1; |
上字典锁 |
GLOBAL:STATMENT MDL_INTENTION_EXCLUSIVE |
|
|
3 |
TABLE:TRANSACTION MDL_SHARED_WRITE |
|||
|
4 |
上行锁 |
LOCK_TABLE:IX (table:t3) |
||
|
5 |
LOCK_REC:X (id=1) |
|||
|
6 |
执行更新 |
|||
|
7 |
释放MDL |
GLOBAL:STATMENT |
||
|
8 |
commit; |
COMMIT 字典锁 |
COMMIT: MDL_EXPLICIT MDL_INTENTION_EXCLUSIVE |
|
|
9 |
执行提交 |
|||
|
10 |
释放引擎锁 |
lock_release |
||
|
11 |
释放MDL |
COMMIT: MDL_EXPLICIT MDL_INTENTION_EXCLUSIVE |
||
|
12 |
release_transactional_locks TABLE:TRANSACTION |
可以看到,第一行begin,表示开启一个新事务,隐含提交会话的上一个事务,需要释放之前的锁。第2到7行是两阶段锁中的上锁阶段,分别先后上了字典锁、表的意向锁和行锁。上完锁后,才开始真正的更新阶段,从这里也可以看到MySQL的写操作是符合悲观锁策略。第4行和第5行,我们可以看到意向锁是如何运作的,上记录id=1的行锁之前,先对表t3上了意向锁。第7行,语句执行完后,可以释放STATEMENT级别的字典锁,避免长时间持有锁阻塞该表的DDL操作。8-12是提交阶段,进入两段锁中的释放锁过程,先后释放引擎层的表锁和行锁;然后释放TRANSACTION级别的MDL锁。
3. 常用语句加锁分析
假设隔离级别:RC,id为主键
|
典型语句 |
SQL层面(MDL锁) |
存储引擎 innodb |
||
|
范围/对象 |
持有时间 |
表锁 |
行锁 |
|
|
SELECT操作 SELECT * FROM T |
TABLE: MDL_SHARED_READ |
MDL_TRANSACTION |
None |
None |
|
Show create table T |
TABLE: MDL_SHARED_HIGH_PRIO |
MDL_TRANSACTION |
||
|
LOCK TABLE T READ |
TABLE: MDL_SHARED_READ |
MDL_TRANSACTION |
None |
None |
|
LOCK TABLE T WRITE |
GLOBAL: MDL_INTENTION_EXCLUSIVE |
MDL_STATEMENT |
None |
None |
|
SCHEMA: MDL_INTENTION_EXCLUSIVE TABLE: MDL_SHARED_NO_READ_WRITE |
TRANSACTION |
|||
|
Flush table t with read lock |
TABLE: MDL_SHARED_NO_WRITE |
TRANSACTION |
None |
None |
|
Flush table with read lock |
GLOBAL: MDL_SHARED |
MDL_EXPLICIT |
None |
None |
|
COMMIT: MDL_SHARED |
MDL_EXPLICIT |
|||
|
DML操作 SELECT * FROM T FOR UPDATE; Update T set c1=? Where id=? |
GLOBAL: MDL_INTENTION_EXCLUSIVE |
MDL_STATEMENT |
IX |
X |
|
TABLE: MDL_SHARED_WRITE |
TRANSACTION |
|||
|
DDL操作 Alter table t add column c1 int; Truncate table t; |
GLOBAL: MDL_INTENTION_EXCLUSIVE |
MDL_STATEMENT |
None |
X |
|
SCHEMA: MDL_INTENTION_EXCLUSIVE TABLE: MDL_EXCLUSIVE |
TRANSACTION |
|||
|
COMMIT: MDL_INTENTION_EXCLUSIVE |
MDL_EXPLICIT |
|||
|
Set global read_only=1; |
GLOBAL: MDL_SHARED COMMIT: MDL_SHARED |
MDL_EXPLICIT |
None |
None |
MySQL锁机制总结(二)的更多相关文章
- Mysql锁机制介绍
Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...
- InnoDB的锁机制浅析(二)—探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意向锁)
Record锁/Gap锁/Next-key锁/插入意向锁 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Recor ...
- 再谈mysql锁机制及原理—锁的诠释
加锁是实现数据库并发控制的一个非常重要的技术.当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁.加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更 ...
- Mysql锁机制--索引失效导致行锁变表锁
Mysql 系列文章主页 =============== Tips:在阅读本文前,最好先阅读 这篇(Mysql锁机制--行锁)文章~ 在上篇文章中,我们看到InnoDB默认的行锁可以使得操作不同行时不 ...
- mysql锁机制详解
前言 大概几个月之前项目中用到事务,需要保证数据的强一致性,期间也用到了mysql的锁,但当时对mysql的锁机制只是管中窥豹,所以本文打算总结一下mysql的锁机制. 本文主要论述关于mysql锁机 ...
- 对mysql锁机制的学习
1.对于mysql学习,经常翻看一些博客,论坛,好像或多或少有mysq锁机制的学习与总结,所以今天有必要 对mysql锁机制的一些个人的总结,以便以后深入的学习. 2.学习这件事,从来都是“深入浅出” ...
- mysql锁机制(转载)
锁是计算机协调多个进程或线程并发访问某一资源的机制 .在数据库中,除传统的 计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所 ...
- mysql锁机制和事务隔离
mysql事务 1.InnoDB事务原理 事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态. 在数据库提交时,可以确保要么所有修 ...
- mysql锁机制 读书笔记
目录 MySQL锁机制 1.什么是锁 2.lock与latch 3.InnoDB存储引擎中的锁 3.1锁的类型 3.2 一致性非锁定读 3.3 一致性锁定读 4 锁的算法 4.1行锁的3中算法 4.2 ...
随机推荐
- Android网页浏览器的开发
Android网页浏览器的核心Widget是包含了WebKit的WebView. 首先,布局文件activity_main.xml: <LinearLayout xmlns:android=&q ...
- 后缀名为properties,config和xml的文件内容读取
1.先建立文件(后缀名为properties和config) 2.读取类建立 public class Read{ public static Properties properties = new ...
- 字符串-Alphabet
在一些应用当中,会对字符串的字母表进行限制,在这些应用中,往往会用到如下的示例所涉及到的几点知识: public static void main(String[] args){ String[] a ...
- spring3.0结合Redis在项目中的运用
推荐一个程序员的论坛网站:http://ourcoders.com/home/ 以下内容使用到的技术有:Redis缓存.SpringMVC.Maven.项目中使用了redis缓存,目的是在业务场景中, ...
- Verilog学习笔记简单功能实现(四)...............译码器和编码器
这里以简单的3-8译码器和8-3编码器为例: module decoder3_8(a,out); :]a; :]out; 'b1<<a;/*把最低位的1左移in位(根据in口输入的值)并赋 ...
- python 三级菜单
三级列表: menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{}, '网易':{}, 'google':{} }, '中关村':{ '爱奇艺':{}, '汽车之家':{}, ...
- MYSQL数据库如何赋予远程某个IP访问权限
1. 授权用户root使用密码jb51从任意主机连接到mysql服务器:代码如下:GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'jb ...
- java 编译时的初始化顺序
有的时候,java的初始化会对我的工作照成很大影响,所以简单介绍一下, 首先介绍简单的变量的初始化:在类的内部,变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法定义之间,它也会先于构造器和 ...
- java内存模型-volatile
volatile 的特性 当我们声明共享变量为 volatile 后,对这个变量的读/写将会很特别.理解 volatile 特性的一个好方法是:把对 volatile 变量的单个读/写,看成是使用同一 ...
- 优秀的 HTML5 实战教程,提升你的综合开发能力
HTML5 作为下一代网站开发技术,无论你是一个 Web 开发人员或者想探索新的平台的游戏开发者,都值得去研究.借助尖端功能,技术和 API,HTML5 允许你创建响应性.创新性.互动性以及令人惊叹的 ...