Innodb中的锁

2018-06-18 00:37:25来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

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锁

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:mysql安装后服务启动不了(总结)

下一篇:mysql导入导出命令(Linux+Windows)