要做的完全掌握MySQL/InnoDB的加锁规则,甚至是其他任何数据库的加锁规则,需要具备以下的一些知识点

  1. 了解数据库的一些基本理论知识:数据的存储格式 (堆组织表 vs 聚簇索引表);并发控制协议 (MVCC vs Lock-Based CC);Two-Phase Locking;数据库的隔离级别定义 (Isolation Level);
  2. 了解SQL本身的执行计划 (主键扫描 vs 唯一键扫描 vs 范围扫描 vs 全表扫描);
  3. 了解数据库本身的一些实现细节 (过滤条件提取;Index Condition Pushdown;Semi-Consistent Read);
  4. 了解死锁产生的原因及分析的方法 (加锁顺序不一致;分析每个SQL的加锁顺序)

有了这些知识点,再加上适当的实战经验,全面掌控MySQL/InnoDB的加锁规则,当不在话下。

最近开始关注MySQL的锁问题,也希望开始对锁有个大概的认识,今天从简单的概念入手;一般分为2种,一种是DML操作时的锁机制,另一种,则是在DDL操作时,锁是如何来进行控制的。

作为学习的开始,还是先从简单的入手比较合适,所以,这里作为一个入门级的第一篇文章,先简单介绍下DML中涉及到的读写锁,即使如此,也还是在实际实验中,遇到了和理论不一致的情况,暂时还不能给大家拿出合理解释,下面给出详情:

  1. 共享锁和排它锁

    InnoDB支持最小粒度到数据行的行级锁:

    • 共享锁,允许事务通过持有共享锁去读取一行
    • 排他锁,允许事务通过持有排它锁去更新或者删除一行

    一行数据,可以允许多个事务同时持有共享锁,但是只能有一个事务持有排他锁,如果另一个事务也需要持有排他锁,则需要等待之前持有该锁的事务,释放掉锁

  2. 意向锁

    InnoDB除行级锁以外,还在表级别,添加了一种叫做意向锁的概念,其表示事务即将对该表的某些行做读或者写操作

    • 共享意向锁,表示某事务即将要对该表的某些行数据加共享锁
    • 排它意向锁,表示某事务即将要对该表的某些行数据加排他锁

    举个例子:

    select ... lock in share mode 将在表上持有IS共享意向锁,select for update则是在表上持有IX排他意向锁
    

    意向锁的两个使用规约:

    • 事务在持有表上某行数据的行共享锁之前,必须先持有表上的共享意向锁,或者级别更高的排他意向锁
    • 事务在持有表上某行数据的行排他锁之前,必须先持有表上的排他意向锁

    表级别的意向锁和行级别的锁,排斥关系如下:

      X IX S IS
    X Conflict Conflict Conflict Conflict
    IX Conflict Compatible Conflict Compatible
    S Conflict Conflict Compatible Compatible
    IS Conflict Compatible Compatible Compatible

    举一个例子:

    事务A执行了select lock in share mode ,这时,事务A持有了IS锁和S锁(为啥要加上 lock in share mode 呢?不加,就是快照读,不会要求去持有锁,反过来,利用lock in share mode,可以在业务上实现原子读写操作哦,大家可以自己思考一下) 事务B要在相同的行上,执行update 语句,那么这时,事务B首先要去持有表级别的IX锁,根据上图第2行最后一列,IX 和 IS 是共享的,所以,这个没问题。然后,事务B要对相同的行,做写操作,所以其需要持有X锁,根据上图第1行第3列,X和S是不兼容的,所以事务B需要等待事务A结束以后,才能执行。

    • 反思1:如果事务A使用select for update,事务B会如何反映?(结果一样,事务B会等待事务A结束)
    • 反思2:如果事务B,update不同的行,事务B会如何反映?(结果不一样,事务B不需要等待事务A)
    • 反思3:如果根据第一行第三列的规则,岂不是一个事务做了update操作,另一个事务就不能读了?写阻塞读?(其实读,都是快照读,并不会要求持有S锁)
  3. 行级锁

    行级锁总是针对某个索引记录进行加锁,用以防止其他事物并发对当前加锁的行进行读取和修改。所以,及时用户没有定义任何索引和主键,MySQL也会在内部,自动生成一个隐含的主键列。 行级锁,其目的,就是为了保证多个事务不能同时对相同的一条数据执行修改动作

  4. 间隙锁

    间隙锁,顾名思义,其锁定的是若干个索引记录的某个范围(不包括记录本身),比如:SELECT c1 FROM t WHERE c1 > 10 and c1 < 20 FOR UPDATE; 这个就锁定了10~20的这个范围(10.20),防止其他事物,插入c1的值在10~20直接的记录,但c1等于10或者c1等于20,则是允许被插入的 如上SQL所示,间隙表跟行级锁的一个区别在于,间隙锁是锁定了一个区间范围,防止别人对这个区间内的数据,执行insert或者update。

    小实验:

    假如在索引列上,事务A执行的是 c1 between 10 and 20 for update,那么,事务B能够插入c1等于10(或者20)的记录吗?

  5. Next-Key锁

    接上一个问题,假如事务A执行的是 c1 between 10 and 20 for update,那么,除了锁定10,20的区间以外,还需要锁定记录本身(10和20),这就是Next-Key锁: Next-Key就是间隙锁的一种升级,其锁定的内容,除了范围以外,还包含记录的本身,比如,C1这个普通索引列上,有3条数据:1,10,20,30,那么,可能存在的Next-Key的锁有以下几种(区间 + 记录):(无限小,1]. (1,10]. (10,20] . (20,30]. (30,无限大)

    当执行select * from A where c1 between 10 and 20 for update时,其加上的锁:为:(1,10],(10,20],(20,30),其范围会扩大到当前Key的下一个值中去,你会发现,在事务B中,c1 >1 到C1 < 30 的记录,全部不允许插入,而不仅仅是10到20直接。

  6. 自增锁

    表级别,还有一个特殊的锁:自增锁,后面的文章,将给出详细介绍。

参考: MySQL 加锁处理分析

【MySQL】锁入门的更多相关文章

  1. [转]MySQL主从复制入门

    1.MySQL主从复制入门 首先,我们看一个图: 影响MySQL-A数据库的操作,在数据库执行后,都会写入本地的日志系统A中. 假设,实时的将变化了的日志系统中的数据库事件操作,在MYSQL-A的33 ...

  2. Mysql锁初步

    存储引擎 要了解mysql的锁,就要先从存储引擎说起. 常用存储引擎列表如下图所示: 最常使用的两种存储引擎: Myisam是Mysql的默认存储引擎.当create创建新表时,未指定新表的存储引擎时 ...

  3. MYSQL锁表问题解决

    本文实例讲述了MYSQL锁表问题的解决方法.分享给大家供大家参考,具体如下: 很多时候!一不小心就锁表!这里讲解决锁表终极方法! 案例一 ? 1 mysql>show processlist; ...

  4. MySQL主从复制入门

    1.MySQL主从复制入门 首先,我们看一个图: MySQL 主从复制与读写分离概念及架构分析 影响MySQL-A数据库的操作,在数据库执行后,都会写入本地的日志系统A中. 假设,实时的将变化了的日志 ...

  5. MySQL 快速入门(一)

    目录 MySQL快速入门 简介 存储数据的演变过程 数据库分类 概念介绍 MySQL安装 MySQL命令初始 环境变量配置 MySQL环境变量配置 修改配置文件 设置新密码 忘记密码的情况 基本sql ...

  6. 「MySQL高级篇」MySQL锁机制 && 事务

    大家好,我是melo,一名大三后台练习生,最近赶在春招前整理整理发过的博客~! 引言 锁锁锁,到哪到离不开这桩琐事,并发琐事,redis琐事,如今是MySQL琐事,这其中琐事,还跟MySQL另一个重要 ...

  7. mysql锁

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

  8. 【转载】20分钟MySQL基础入门

    原文:20分钟MySQL基础入门 这里持续更新修正 开始使用 MySQL 为关系型数据库(Relational Database Management System),一个关系型数据库由一个或数个表格 ...

  9. mysql锁表机制及相关优化

    (该文章为方便自己查阅,也希望对大家有所帮助,转载于互联网) 1. 锁机制 当前MySQL支持 ISAM, MyISAM, MEMORY (HEAP) 类型表的表级锁,BDB 表支持页级锁,InnoD ...

  10. MySQL锁系列3 MDL锁

    http://www.cnblogs.com/xpchild/p/3790139.html   MySQL为了保护数据字典元数据,使用了metadata lock,即MDL锁,保证在并发的情况下,结构 ...

随机推荐

  1. UVA 12549 - 二分图匹配

    题意:给定一个Y行X列的网格,网格种有重要位置和障碍物.要求用最少的机器人看守所有重要的位置,每个机器人放在一个格子里,面朝上下左右四个方向之一发出激光直到射到障碍物为止,沿途都是看守范围.机器人不会 ...

  2. Android常见的控件

    1.Log类的使用 (1)Log.v()    v是verbose  提醒的意思 (2)Log.d()   d是debug调试 (3)Log.i()    i是info信息的意思 (4)Log.w() ...

  3. 去掉win10桌面小图标

    参考:http://bbs.kafan.cn/thread-1843802-1-1.html

  4. mybatis调用视图和存储过程

    现在的项目是以Mybatis作为O/R映射框架,确实好用,也非常方便项目的开发.MyBatis支持普通sql的查询.视图的查询.存储过程调用,是一种非常优秀的持久层框架.它可利用简单的XML或注解用语 ...

  5. 用.NET从外部dwg文件导入块

    翻译并引自Kean's blog的两篇文章: http://through-the-interface.typepad.com/through_the_interface/2006/08/import ...

  6. 与考试相关的JS方法

    var IsChange = 0;var ensure = 0;var timeCounter = (function () {//考试剩余时间 倒计时 var int; //var total = ...

  7. Swift处理堆栈问题——给定两组序列,其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序

    题目:输入两个整数序列.其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序.为了简单起见,我们假设push 序列的任意两个整数都是不相等的.比如输入的push 序列是1. ...

  8. mysql数据库性能篇

    慢查询:超过设定时间的SQL语句会被记录到指定文件内 1.观察mysql慢查询默认的时间(默认10秒) show variables like 'long%'; 2.修改慢查询设定时间 set lon ...

  9. /px/em/rem/的区别

    PX特点: 1 .IE无法调整那些使用px作为单位的字体大小: 2. 国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位: 3.Firefox能够调整px和em,rem,但是96%以上 ...

  10. Android AsyncTask 简单用法

    简介 AsyncTask 是一个轻量级的异步处理类.使用是需继承自该类.可以方便的执行异步任务并且在将进度显示在UI上. 注意事项 AsyncTask只适合处理轻量级的任务即耗时几秒或者几十秒的任务. ...