阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

关于MySQL InnoDB锁

121次阅读
没有评论

共计 2267 个字符,预计需要花费 6 分钟才能阅读完成。

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
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

行级锁 (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

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-22发表,共计2267字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中