微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MySQL-锁

全局锁 FTWL

使用全局锁后数据库只允许读不允许写。

# 1. 
FLUSH TABLE WITH READ LOCK; # 加锁

UNLOCK TABLES;# 解锁

# 2. 
SET GLOBAL READ_ONLY=TRUE

# 第一种方式在客户端断开后会自动释放

表锁

MyISAM引擎只有表锁。
表锁分为两种 LOCK命令加锁和MDL锁

LOCK锁

通过LOCK命令加锁

LOCK TABLE user_job READ; # 本线程和其它线程只能读表
LOCK TABLE user_job WRITE; # 本线程可以读写,其它线程不能读写

UNLOCK user_job; 解锁

MDL锁

MDL锁 Metadata lokc 即元数据锁,5.5之后引进的表级锁,保证读写正确性。

MDL锁不能手动添加,由MysqL自动添加

  1. 对表作增删改查,加MDL读锁。
  2. 对表结果作变更操作时,加MDL写锁。
    MDL锁会在事务提交后自动释放。

MDL读锁不互斥,可以对表加多个MDL读锁,读写锁之间互斥。

MDL锁是在Server层实现的。

行锁

  1. 共享锁
    Shared Lock 又叫做S锁。一条数据加了S锁之后,其它事务也可以读数据,共享一把锁。
select * from user_job where id = 1 LOCK IN SHARE MODE
  1. 行排他锁
    Exclusive Lock,又称为写锁,X锁。一条数据加了X锁后,其它事务只能阻塞。
    修改数据,insert, update,delete时MysqL自动排它锁
select * from user_job where id =1 for update

意向锁

InnoDB行锁和表锁是可以共存的,当加表锁的时候需要遍历每一行看是否有行锁,效率会降低。为解决这个问题引入了意向锁。

  1. 意向共享锁
    Intention Shared Lock 意向共享锁 IS锁
  2. 意向排他锁
    Intention Exclusive Lock 意向排它锁 IX锁

意向锁右MysqL自动维护:

  1. 当对行数据加S锁时,对整个表加IS锁
  2. 当对行数据加X锁时,对整个表加IX锁
    当加表锁时执行检查是否有意向锁即可。


    IX锁与X锁和S锁互斥,Is锁与X锁互斥,与S锁共享。

InnoDB如何解决幻读问题

通过行数来解决。锁住的时索引,没有索引时锁表。

辅助索引被锁后,对应主键索引也会被锁,InnoDB主键索引即数据。主键索引被锁整条数据都会被锁。
即便覆盖索引也会锁整条数据。

行锁有三种算法:记录锁,间隙锁和临键锁,MysqL就是通过临键锁解决幻读问题。

  1. 记录锁:Record Lock,即锁住一条数据
  2. 间隙锁: Gap Lock, 索引间隙上的锁。匹配记录的第一条的上一条到最后一条的后一条的中间,开区间。如当where 条件时范围时,整个范围都会被锁,这也造成不存在的记录也会被锁定。
  3. 临键锁:Next-Key Lock , 记录锁和间隙锁的结合。区间左开右闭,范围查询时,会锁住记录和间隙,InnoDB行锁的认算法。
    RR级别才会有临键锁,RC只有记录锁。

行锁的加锁规则

  1. MysqL认是RR级别,使用临键锁
  2. 使用主键或唯一索引命中一条记录的时候会退化为记录锁。
  3. 没有命中记录会退化为间隙锁
  4. 查找过程访问到对象时才会加锁
  5. 索引上进行等值查询时,向右遍历发现最后一个值不满足条件的时候,临键锁会退化为间隙锁。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐