MySQL进阶:锁

数据库锁的设计是处理并发问题,当出现并发访问的时候,数据需要合理地控制资源访问规则。

一、全局锁

全局锁是对整个数据库加锁。MySQL提供一个加全局锁的方法:

Flush tables with read lock,之后数据库的更新语句(数据增删改),定义语句(建表、修改表结构等)和更新类事务的提交语句都会被阻塞。

使用场景:全库逻辑备份,整个库完全处于只读状态。

二、表级锁

表级别的锁有两种:一种是表锁,一种是元数据锁

  • 表锁:lock tables 表名 read, 表2 write;unlock tables(一般不使用)
  • MDL:不需要显式使用,访问一个表会自动加上,对一个表增删改查操作时,加MDL读锁,对表结构变更时,加MDL写锁。读读不互斥,读写、写写互斥。

MDL会出现的问题:事务A加上读锁增删改查数据,事务B想要修改表结构加写锁,但事务B被阻塞,事务C想读但是会被事务B锁阻塞。

MDL锁直到事务不提交才会释放,做表结构变更的时候,一定不要导致线上查询。

三、行锁

InnoDB支持行锁,MyISAM不支持行锁。

3.1 两阶段锁

行锁是在需要的时候才加锁,但并不是不需要了立马释放,而是等待事务结束时才释放。

3.2 死锁和死锁检测

出现死锁后有两种策略:

  • 直接进入等待,直到超时。通过参数:innodb_lock_wait_timeout来设置,默认50s
  • 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一事务,让其他食物得以继续进行,将参数innodb_deadlock_dect设置on

3.2 行锁和间隙锁(前提是当前读)

间隙锁唯一的作用就是阻止其他事务在间隙上的更改,一个事务在一个记录上有间隙锁不阻止其他事务在此间隙上获得间隙锁。谈论上述上锁的前提是,做当前读的操作。

读未提交和读提交

在这两个隔离级别上,间隙锁不被使用,未找到符合查询条件的行时,行锁被释放。无论条件列上是否有索引,都不会锁表,只锁行!具体情况:

  • 在条件列是聚集索引,聚簇索引树上查询,在聚簇索引上加行级锁
  • 在条件列是非聚簇索引时,在非聚簇索引记录上加行级锁。接着,去聚簇索引树上查询,在聚簇索引上加行级锁,采用当前读。
  • 在条件列没有索引的情况下,尽管通过聚簇索引来扫描全表,进行全表加锁。但是,MySQL Server层会进行过滤并把不符合条件的锁当即释放掉,因此你看起来最终结果是一样的。但是条件列非索引条件列有索引多了一个释放不符合条件的锁的过程!

可重复读

  • 在条件列是聚集索引,如果where后的条件为精确查询(=的情况),那么只存在行锁。如果where后的条件为范围查询(>或<的情况),那么存在的是行锁和间隙锁,在对应范围加间隙锁。
  • 在条件列是非聚簇索引时,
    • 如果是唯一索引,情况和聚簇索引类似,唯一有区别的是:这个时候有两棵索引树,加锁是加在对应的非聚簇索引树和聚簇索引树上
    • 如果是非唯一索引,通过索引进行精确查询以后,在聚簇索引树上,非唯一索引树上加间隙锁和行锁。
  • 条件列没有索引无论你怎么查都是锁全表

1、快照读能解决部分幻读问题,就是当sessionA查询的时候,sessionB insert多少条都是一样;但sessionA update的时候,就是当前读,会生成新的快照点,导致幻读问题出现。

2、用next-key lock解决当前读下的幻读问题,如果是走索引,他会锁住索引本身的行锁;如果是范围,就会成为一个行锁+间隙锁,导致范围内的无法插入;如果是无索引的,直接全表加上了间隙锁,无法插入,阻塞

四、意向锁

InnoDB存储引擎才支持意向锁

  • 意向锁也分为共享/排他两种
  • InnoDB允许行级锁与表级锁共存,而意向锁就是表锁(但它并不是真的加了表锁)

为什么需要意向锁

  • 假设事务A获取了某一行的排它锁,尚未提交,此时事务B想要获取表锁,则必须确认表中的每一行都不存在排它锁,很明显这样一行行检查效率会很低,所以引入了意向锁
  • 引入意向锁之后,如果事务A对每一行加了排它锁,实际上是此表上会存在两种锁,表中某一行的排它锁和表上的意向排它锁;如果事务B此时再企图再该表上加锁时,则会看见表上有一个意向排它锁,则会直接阻塞这个企图加锁过程。这样不用检查表中的每一行是否加了锁,只需要检查表上的意向锁。
     

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值