美文网首页
InnoDB存储引擎学习总结 第六章 锁

InnoDB存储引擎学习总结 第六章 锁

作者: 油多坏不了菜 | 来源:发表于2019-02-22 21:16 被阅读0次

命令

select @@tx_isolation;//查看当前隔离级别

概述

锁机制用于管理对共享资源的并发访问

InnoDB中的锁

  1. 行级锁介绍
  • 共享锁(S),允许事务读一行数据
  • 排他锁(X),允许事务删除或者更新一行数据
    当一个事务获取到一行数据的S锁,其他事务可以获取到该行数据的S锁,但不能获取到X锁;当一个事务获取到一行数据的X锁,其他事务不能获取到该行数据的S锁和X锁。
    show engine status中 transactions 部分可以查看锁的状态。
  1. 一致性非锁定读
    • 一致性非锁定读:读取某行的数据时,不需要获取S锁;并且如果当前某事务占有该行的X锁,读取也不会阻塞。
    • 当一致性非锁定读取的行已被加X锁,则会去Undo段中获取历史版本数据(MVCC),(Undo段用来在事务回滚数据)。
    • 可重复读(读取事务一开始的数据版本)和已提交读(读取已提交数据最新版本)的事务隔离级别下,这是默认的读取方式。
  2. 一致性锁定读
    • select for update (X锁)
    • select .. lock in share mode (S锁)
    • 当事务提交时,锁释放
    • 开始一个事务:begin, start transaction,set autocommit = 0.
  3. 自增长与锁(不算太懂)
    • InnoDB的内存结构中,对每个含有自增值的表都有一个自增长计数器
    • Auto_INC locking:在对含有自增长列的表插入时,会执行select max(auto_inc_col) from t for update(这个会锁表)获取下个自增长列的值,然后把相应记录插入表中之后,相应的表锁就会释放(不用等到整个事务执行完,仅需等待插入操作完成)
    • Auto_INC locking的缺点:会锁表(虽然不用等到整个事务提交),对于bulk inserts (表锁时间会比较长)来说可能导致其他事务等待太长的时间。
    • innodb_autoinc_lock_mode 参数:0代表atuo_inc locking的方式;1代表对于simple inserts ,会用互斥量去对内存中的值进行自增(无表锁,这种方式只有在无回滚,无删除的情况下才能保证完全自增),对于bulk inserts 还是使用传统的 auto_inc locking.2不议。
    • InnoDB中,自增长列必须是索引,且必须是索引的第一个列。
  4. 外键和锁
    • InnoDB默认对外键列加索引,以避免表锁。?
    • 对于外键值的插入或者更新,首先查询父表的记录,这里查询父表会使用一致性锁定读(lock in share mode).

锁的算法

  • Record Lock:单个行记录上的锁(已提交读下的默认算法)
  • Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
  • Next-Key Lock :Gap Lock + Record Lock (可重复读下的默认算法)

Next-Key Lock详解

参考博文(http://hedengcheng.com/?p=771
假设有表如下:其中id列为主键列,b列为索引列

初始值
  1. 对主键的where条件查询的锁定情况。
 select * from a where id=2;//只锁定id=2 这一条记录,
其实是Next-Key Lock 退化为 Record Lock.
 select * from a where id >2; //理论上,应该只锁定id>2的部分,但是这里全表都都锁了。(再议)

2、对辅助索引的锁定

select * from a where b =5 for update;//这里会把聚集索引里面id=4和辅助索引区间(3,5] 和(5,101]加锁

3、对非索引列的锁定
非索引列会造成很多的行锁和间隙锁。要注意使用。

利用Next-Key Lock在应用层面实现唯一性检查

select * from table where col=** in share mode;
if not found any row: 
      ##insert into tables values(....) //这里插入的话在并发情况下能保证只有一个会话成功,其余的会获取锁失败(?why)

锁问题

  • 脏读:脏页和脏读不同,脏读是读取另外事务中未被提交的数据。一般事务在 read-ncommitted 隔离级别下才会出现。
  • 不可重复读。如果事务的隔离级别未read-committed,那么就是不可重复读的,在repeatable read隔离级别下,利用Next-Key Lock解决不可重复读(幻读)问题。
  • 丢失更新
    银行转账例子:
    事务一: 序列1-A账号有10000元(select),序列2:转出9000元(update) 序列3:提交
    事务二:序列4:A账号有10000元(select),序列5:转出1元(update) 。序列6:提交
    然后 上面连个事务如果按照 序列 1,2,4, 3 , 5, 6的顺序执行,就会发生事务一更新丢失
    分析可知:在上面序列2(或者5)执行的时候,序列1查询的值不应该被改变过,所以我们需要对序列1的的查询加锁(这里应该加X锁,如果加S锁的话个人感觉可能死锁)。所以上面需要用 `select for update'

阻塞

  • innodb_lock_wait_timeout 超时时间
  • innodb_rollback_on_timeout 超时是否回滚事务,默认不会回滚

死锁

  • A等待B释放锁,同时B等待A释放锁。AB-BA死锁问题
  • 死锁会回滚事务(虽然默认大多数异常不回滚),一般会回滚undo段小的事务。

锁升级

在 InnoDB中不存在锁升级问题,因为行锁不是按照每个记录来产生的,相反,其根据每个事务访问的每个页来对锁进行管理,采用的是位图模式(所以锁资源的开销应该不大)。

相关文章

  • mysql规范

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

  • MySQL的锁分类以及使用场景

    myisam存储引擎默认是表级锁innodb存储引擎默认是行级锁DBD存储引擎默认是页面锁表级锁:开销小,加锁快;...

  • 【原创】因酷数据库开发规范

    基本规范 所有表必须使用Innodb存储引擎Innodb存储引擎是Mysql5.6以后默认引擎支持事务,行级锁,更...

  • 深入理解MySQL

    存储引擎 现在常用的存储引擎是InnoDB,以前常用的是MyISAM。 InnoDB 支持事务、支持行级锁、支持外...

  • Mysql存储引擎Innodb小结

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

  • 文章总结(6)—数据库

    InnoDB和MyISAM存储引擎的区别 InnoDB使用的是行锁,MyISAM使用的是表锁; InnoDB支持事...

  • 【学习】MySQL数据库

    存储引擎 存储引擎 索引 InnoDB索引原理索引 锁 锁不同Select加锁分析 事务 事务事务隔离级别XAMV...

  • InnoDB介绍

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

  • mysql 存储引擎

    什么是存储引擎 常见的几种存储引擎 InnoDB InnoDB是一个支持事务安全的搜索引擎。支持外键、行锁、事务...

  • Innodb的锁

    Innodb的锁是行级锁 mysql delete是否会锁表 MySQL的InnoDB存储引擎支持行级锁,Inno...

网友评论

      本文标题:InnoDB存储引擎学习总结 第六章 锁

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