你好,游客 登录 注册 搜索
背景:
阅读新闻

关于MySQL InnoDB锁

[日期:2017-12-07] 来源:Linux社区  作者:helloz [字体: ]

Innodb中的锁

共享锁和排它锁(Shared and Exclusive Locks)
  共享锁和排它锁是行级锁,有两种类型的行级锁
    共享锁(s lock)允许持有锁的事务对行进行读取操作
    排它锁(x lock)允许持有锁的事务对行进行更新和删除操作

  事务a在行r上拥有共享锁,则其他事务可以获得r的共享锁,无法获得r的排它锁,即可读不可写
  事务a在行r上拥有排它锁,则其他事务既不能获得共享锁,也不能获得排它锁,即不可读也不可写而必须等待当前事务完成

意向锁(Intention Locks)
  意向锁是表级锁,用来表示将会有哪种类型的行级锁即将被使用,有两种类型的意向锁
    意向共享锁(IS Locks):表明即将在表中的某一行上设置共享锁(s lock)
    意向排它锁(Ix Locks): 表明即将在表中的某一行上设置排它锁(x lock)

  一个事务如果要获得一个共享锁(s lock)必须首先获得一个意向共享锁(is lock),一个事务如果要获得一个排它锁(x lock)则必须先获得一个意向排它锁(ix lock)
各种锁级别的兼容性

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


行级锁(Record Locks)
  行级锁总是锁住索引记录(index records),即便表没有定义索引,innodb也会创建一个隐藏的聚簇索引,然后用这个索引来锁住这一行。
间隙锁(Gap Locks)
  间隙锁是用于索引之间或第一个索引之前或最后一个索引之后的锁, 当语句中有一个确定的索引值的时候,间隙锁会降级为行级锁。例如这个
    select * from child where id =100;
Next-Key Locks
  不知道怎么翻译了。这是行级锁和间隙锁的组合,也就是说这种类型的锁会做作用于一条记录上和它之前的间隙,不允许插入。
自增锁(AUTO-INC Locks)
  一个特殊的表级锁,用于带有auto-increment选项的列上,它会让你获得连续的主键值。这个锁的释放在它的sql语句执行完成之时,而非事务结束之时,这样其他的事务可以不必等到事务结束才获得自增锁。innodb_autoinc_lock_mode是用来配置这个锁的。
Predicate Locks
谓词锁(不知道是不是这个意思),作用于空间索引(spatial indexes)。

常见sql语句的锁级别
  innodb默认的隔离级别是可重复读(repeatable read),默认的读取方式是一致性读(consistent read),所谓一致性读就是在你开启事务的时候,innodb会保存一个时间戳,在此之后的改变都是不可见的。由于innodb是一个多版本存储引擎(multi-versioned storage engine),它会保存改变的行之前的旧的数据以支持一些事务特性,例如并发和回滚。这些数据被存储在表空间(tablespace)的一个叫rollback segment的数据结构里。这里的数据会被用来重建之前的值来保证一致性读(consistent read)。
    select ... from : 一致性读,不需要锁,除非隔离级别被设为串行化(serializable)。
    select ... from ... lock in share mode :在搜索条件里的每条记录设置共享的next-key lock, 如果有特定的索引值则为行级锁。
    select ... from ... for update :在搜索条件里的每条记录设置排它的next-key lock, 如果有特定的索引值则为行级锁。
    update ... where... 在搜索条件里的每条记录设置排它的next-key lock, 如果有特定的索引值则为行级锁。
    delete from ... where ... : 在搜索条件里的每条记录设置排它的next-key lock, 如果有特定的索引值则为行级锁。
    insert 语句设置一个排它锁在插入的行上,为行级锁。当有多个会话尝试插入相同主键发生主键冲突时,可能会发生死锁,因为在发生主键冲突时他们各自获得了共享锁,而都不能获得排它锁。
    insert ... on duplicate key update : 和之前的insert语句不同的是当发生主键冲突时,他们会获得排它锁而非共享锁,这样就避免了多个会话获得共享锁而发生死锁。

手动加锁
  select ... from ... lock in share mode
  select ... from ... for update

  lock tables tb_name [AS alias {read [local] | [low_priority] write }
    [,tb_name [AS alias {read [local] | [low_priority] write }...]
  unlock tables;
  read local允许在锁定被保持时,执行非冲突性insert语句
  low_priority write锁定来允许其它线程在该线程正在等待write锁时获得read锁

本文永久更新链接地址http://www.linuxidc.com/Linux/2017-12/149190.htm

linux
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为���直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款