前言:

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锁机制总结(二)的更多相关文章

  1. Mysql锁机制介绍

    Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...

  2. InnoDB的锁机制浅析(二)—探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意向锁)

    Record锁/Gap锁/Next-key锁/插入意向锁 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Recor ...

  3. 再谈mysql锁机制及原理—锁的诠释

    加锁是实现数据库并发控制的一个非常重要的技术.当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁.加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更 ...

  4. Mysql锁机制--索引失效导致行锁变表锁

    Mysql 系列文章主页 =============== Tips:在阅读本文前,最好先阅读 这篇(Mysql锁机制--行锁)文章~ 在上篇文章中,我们看到InnoDB默认的行锁可以使得操作不同行时不 ...

  5. mysql锁机制详解

    前言 大概几个月之前项目中用到事务,需要保证数据的强一致性,期间也用到了mysql的锁,但当时对mysql的锁机制只是管中窥豹,所以本文打算总结一下mysql的锁机制. 本文主要论述关于mysql锁机 ...

  6. 对mysql锁机制的学习

    1.对于mysql学习,经常翻看一些博客,论坛,好像或多或少有mysq锁机制的学习与总结,所以今天有必要 对mysql锁机制的一些个人的总结,以便以后深入的学习. 2.学习这件事,从来都是“深入浅出” ...

  7. mysql锁机制(转载)

    锁是计算机协调多个进程或线程并发访问某一资源的机制 .在数据库中,除传统的 计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所 ...

  8. mysql锁机制和事务隔离

    mysql事务 1.InnoDB事务原理 事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态. 在数据库提交时,可以确保要么所有修 ...

  9. mysql锁机制 读书笔记

    目录 MySQL锁机制 1.什么是锁 2.lock与latch 3.InnoDB存储引擎中的锁 3.1锁的类型 3.2 一致性非锁定读 3.3 一致性锁定读 4 锁的算法 4.1行锁的3中算法 4.2 ...

随机推荐

  1. IOS中Json解析的四种方法

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...

  2. windbg学习进阶之——windbg环境变量配置

    接触性能调优以来一直想学下windbg分析dump,每次看老师几个命令就能找到很底层的问题原因那简直就是羡慕加崇拜啊~但是这接近一年了,愣是没啥进展呢,主要就是在今天整理的这部分卡住了...这理由找的 ...

  3. html初始化页面和a标签无下划线

    body, div, p, h1, h2, h3, h4, h5, h6, ul, ol, li, dl, dd, dt, img, form { padding:0px; margin:0px; b ...

  4. XMPP客户端开发(1)--连接和登录

    Smack可用于XMPP客户端的开发,下载Smack,将相关jar文件导入后,即可以开始XMPP客户端的开发. 以下代码实现了客户端连接Tigase服务器,并根据用户名和密码登录. package X ...

  5. 专业PHP 7 IDE - Eclipse PDT 4.0 终于出世

    2016年6月22日,第一款开源免费的完整支持PHP 7版本的IDE - PDT 4终于发布.原本我是期望Netbeans 8.2的,但PDT 4.0 发布,就等不及了. PDT团队很高兴的宣布PDT ...

  6. Scalaz(9)- typeclass:checking instance abiding the laws

    在前几篇关于Functor和Applilcative typeclass的讨论中我们自定义了一个类型Configure,Configure类型的定义是这样的: case class Configure ...

  7. 【Qt】2.3 使用Qt设计师来创建对话框

    安装完Qt OpenSource之后,在开始菜单目录下会有这几个东西. 其中[Designer]是用来设计窗口界面的程序.所以现在可以使用它来设计一个对话框.在[Qt Creator]中,[设计]这一 ...

  8. Linux修改SSH端口,并禁止Root远程登陆

    1.更改ssh远程登录端口: #vi /etc/ssh/ssh_config将port改为你想要的端口,例如8888.默认是#port 22,把#号删掉改为 port 8888即可. 还要更改以下文件 ...

  9. Sequence.js 实现带有视差滚动特效的图片滑块

    Sequence.js 功能齐全,除了能实现之前分享过的现代的图片滑动效果,还可以融合当前非常流行的视差滚动(Parallax Scrolling)效果.让多层背景以不同的速度移动,形成立体的运动效果 ...

  10. 10个漂亮的响应式的食品 WordPress 美食模板

    您是否拥有一个餐厅,酒吧,咖啡馆,小酒馆,比萨饼店?如果答案是肯定的,请确保您在网上也提供服务.为了使您的工作更轻松,我们选择了一些新的和独特的餐厅主题,覆盖了范围很广的食品企业.这些主题提供了很多很 ...