美文网首页
MySQL存储引擎InnoDB2-锁

MySQL存储引擎InnoDB2-锁

作者: 梦工厂 | 来源:发表于2018-03-16 12:06 被阅读48次

锁:为了支持对于共享资源的并发访问,提供数据的完整性和一致性。

1 lock vs latch (这一章讲的是lock)

lock 的对象是事务,用来锁定的是数据库中的对象,如表、页、行.
一般lock的对象仅在事务commit或者rollback后释放(不同隔离级别释放时间不同);


2 InnoDB中的锁
2.1. 锁的类型
  • 行级锁:锁定索引
    共享锁S:允许事务读一行数据。
    排他所X:允许事务删除或更新一行数据。
  • 意向锁:
    支持在不同粒度上加锁,行级和表级上的锁同时存在。
    InnoDB的意向锁就是表锁,主要是为了在一个事务中揭示下一行将被请求的锁类型;
    意向共享锁 IS:事务想要获取一张表中的某几行的共享锁。
    意向排他锁 IX:事务想要获取一张表中的某几行的排他锁。
  • IS IX S X
    IS 兼容 兼容 兼容 不兼容
    IX 兼容 兼容 不兼容 不兼容
    S 兼容 不兼容 兼容 不兼容
    X 不兼容 不兼容 不兼容 不兼容
    锁的兼容性:一个事务拿到锁之后另一个事务能不能拿到锁。
    IS IX S X
    IS 兼容 兼容 兼容 不兼容
    IX 兼容 兼容 不兼容 不兼容
    S 兼容 不兼容 兼容 不兼容
    X 不兼容 不兼容 不兼容 不兼容
2.2. 一致性非锁定读 MVCC

通过读取快照数据,实现读写并行


1)快照数据是该行之前版本的数据,通过undo段来实现。而undo用来在事务中回滚数据,因此快照数据没有额外开销。此外,读取快照数据是不需要上锁的,因为没有事务需要对快照数据进行修改操作。
2)MVCC是默认的读取方式,即读取不会占用和等待表上的锁。
在不同的隔离级别下,读取的方式不同,并不是在每个事务隔离级别下都是采用MVCC读。
此外,即使都是MVCC读,对于快照数据的定义在不同隔离级别也各不相同。
  • 隔离级别为可重复读时:InnoDB使用MVCC读,对于快照数据,总是读取事务开始时的行数据版本;
  • 隔离级别为读已提交时:InnoDB使用MVCC读,对于快照数据,总是读取被锁定行的最新一份快照数据;
2.3. 一致性锁定读

某些情况下,需要显示对读取操作进行加锁以保证数据的一致性。 (隔离级别更高了,读也要加锁)
对select语句加X锁:select ... for update
对select语句加S锁:select ... lock in share mode

3 外键和锁
  • Innodb中,对于外键列,如果没有显示加索引,会自动对其添加一个索引,因此避免表锁。
  • 对于外键值的插入或更新,首先需要查询父表记录,select父表。此时并不是采用MVCC读的方式,而是选择了select ... lock in share mode主动对父表加S锁。如果此时父表上已经加X锁,子表操作被阻塞。
    考虑:父表删除id操作,子表插入新纪录外键select父表选择MVCC就会产生不一致的情况。
4 行锁的算法
  1. Record Lock :单个行记录上的锁
  2. Gap Lock: 间隙锁,锁定一个范围,但不包含记录本身;(锁定的是两边的间隙,不能插进来)
  3. Next-Key Lock: Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身。
    辅助理解 MySQL 加锁处理分析
5 死锁

死锁是指两个或两个以上的事务在执行过程中,因争夺资源而造成的一种互相等待的现象。
解决方法:

  1. 超时机制,优点是简单,缺点是未能考虑事务的执行情况。
  2. 等待图 wait-for-group ,InnoDB采取这种方式。
    等待图 要求数据库保留两种信息:锁的事务链表,事务等待链表。

    根据上述信息构造出一张图,如果存在回路代表存在死锁。
    图中,事务1指向事务2的边定义为:
    (1)事务1等待被事务2所占用的资源;
    (2)事务1最终等待事务2所占用的资源,即事务12在等待相同的资源,而事务1在事务2后边;

    等待图是一种主动的死锁检测机制,每个事务请求锁的时候都会判断是否存在回路,若存在则死锁,通常InnoDB选择回滚undo量最小的事务。
6 补充总结
  1. MySQL Innodb存储引擎的并发控制方式:Lock-Based Concurrency Control + MVCC
    在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。
  2. 2PL:Two-Phase Locking
    传统RDBMS加锁的一个原则,就是2PL (二阶段锁):Two-Phase Locking
    锁操作分为两个阶段:加锁阶段与解锁阶段,并且保证加锁阶段与解锁阶段不相交。

    2PL就是将加锁/解锁分为两个完全不相交的阶段。加锁阶段:只加锁,不放锁。解锁阶段:只放锁,不加锁。
  3. 分析SQL语句加锁情况:MySQL 加锁处理分析
  4. 参考书《MySQL技术内幕 InnoDB存储引擎 第2版》

@梦工厂 2018.3.16

相关文章

  • MySQL存储引擎InnoDB2-锁

    锁:为了支持对于共享资源的并发访问,提供数据的完整性和一致性。 1 lock vs latch (这一章讲的是lo...

  • MySQL数据库锁机制之MyISAM引擎表锁和InnoDB行锁详

    MySQL中的锁概念 Mysql中不同的存储引擎支持不同的锁机制。比如MyISAM和MEMORY存储引擎采用的表级...

  • MySQL数据库锁机制之MyISAM引擎表锁和InnoDB行锁详

    MySQL中的锁概念 Mysql中不同的存储引擎支持不同的锁机制。比如MyISAM和MEMORY存储引擎采用的表级...

  • mysql规范

    一、基础规范【强制】使用InnoDB存储引擎解读:InnoDB存储引擎是MySQL默认存储引擎,支持事务和行级锁,...

  • MySQL 锁

    MySQL的锁机制 不同的存储引擎支持不同的锁机制 MyISAM和MEMORY存储引擎采用的是表级锁(table-...

  • MySQL二进制日志

    MySQL-day10 MySQL存储引擎-锁 1)什么是“锁”? 2)“锁”的作用是什么? 3)MySQL中的锁...

  • mysql锁(一)开始前你需要知道的

    ****Mysql中不同的存储引擎支持不同的锁机制****MyISAM和MEMORY存储引擎采用的表级锁BDB采用...

  • Mysql存储引擎Innodb小结

    innodb是mysql支持事务的存储引擎,也是当前mysql默认的存储引擎。innodb支持行级别锁,对并发性事...

  • InnoDB介绍

    InnoDB介绍 InnoDB是事务安全的mysql存储引擎,也是mysql的默认存储引擎,特点是行锁设计、支持M...

  • 详解mysql中的各类锁

    一、存储引擎中锁的区别 在介绍锁之前,我们先来了解下mysql的存储引擎。我们常用的存储引擎一般有两种,MyISA...

网友评论

      本文标题:MySQL存储引擎InnoDB2-锁

      本文链接:https://www.haomeiwen.com/subject/vsnkqftx.html