MySQL 锁结构

全局锁

概念
   全局锁是对整个数据库实例进行加锁,如全局读锁(Flush table with read lock(GTWRL))。
  加了全局读锁之后,整个数据库就处于只读状态,这个时候其他线程的数据更新语句(包括数据的增删改),数据定义语句(包括建表,修改表结构)和更新类的事务提交语句都会被阻塞

使用场景
  全库的逻辑备份,把整个库的所有表都 select 出来存成文本。
优缺点

  • 优点:
    • 可以保证备份的数据的一致性
    • 在不支持事务的存储引擎中也可以使用。如 MVCC 就只使用存储引擎支持事务的情况下才可以使用
  • 缺点:
    • 备份过程中整个库都是只读状态。业务基本是停摆状态。在做主从备份的时候,如果在主库备份,那么备份期间都不能执行更新,业务基本停摆。在从库备份的时候,那么备份期间不能执行主库同步过来的 binlog,会导致主从延迟

与全库只读 set global readonly = true 方式的比较

  • readonly 方式也可以让全库进入只读状态,但是 readonly 的值也会被用来做其他逻辑,比如用来判断一个库是主库还是备库。因此 修改 global 变量的方式影响面更大
  • 在异常处理机制上的差异。如果执行 FLTWL 命令之后由于客户端发生异常断开,那么 MySQL 会自动释放这个全局锁,整个库回到可以正常更新的状态。但是将整个库设置为
    readonly 状态之后,即使客户端发生异常,数据库也并不会释放锁,他会一直保持 readonly 状态,这样会导致整个库长时间处于只读状态,风险较高

表级锁

概念
  MySQL 里面的表级锁有两种,一种是表锁,一种是元数据锁(meta data lock(MDL))
语法

  • 表锁
    表锁的语法是 lock tables … read/write。与 FTWRL 类似,可以用 unlock tables 主动释放锁,也可以在客户端断开的时候自动释放。需要注意的是,lock tables 不仅仅限制了别的线程的读写,同样的也限制了当前线程
  • MDL(medadata lock)
    MDL 不需要显示使用,在访问一个表的时候会被自动加上。MDL 的作用的是,保证读写的正确性。MySQL 5.5 之后引入了 MDL ,当对一个表做增删改查操作的时候,加 MDL 读锁,当要对表做结构变更操作的时候,加 MDL 写锁

行级锁

MySQL 的行锁是在引擎层的,由各个引擎自己实现。但并不是所有的引擎都支持行锁,MyISAM 引擎就不支持行锁。

概念
行锁是针对数据表中行记录的锁。比如事务 A 更新了一行,事务 B 也要更新同一行,那么事务 B 必须要等事务 A 操作完成之后才能更新

两阶段锁

  • 概念
    在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束的时候才释放,这就是两阶段锁协议

  • 可以解决的问题
    如果事务需要锁住多行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放,最大程度减少事务之间的锁等待,提升了并发度

死锁与死锁检测

概念
  当并发系统中不同线程之间出现循环依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。

解决死锁的策略

  • 直接进入等待,直到超时。超时时间可以通过参数 innodb_lock_wait_timeout 参数来设置

  • 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。
    将 innodb_deadlock_detect 设置为 on ,表示开启这个逻辑

    两种策略比较

    • 在 InnoDB 中,innodb_lock_wait_timeout 的默认值是 50s,等待时间过长,如果把这个时间设置成一个很小的值,又容易误伤。
    • innodb_deadlock_detect 默认值就是 on,主动死锁检测在发生死锁的时候,能够快速发现并进行处理,但也有额外的负担。如:每当一个事务被锁的时候,就要看它所依赖的线程有没有被锁住,如此循环进行判断。这样做的时间复杂度是 O(n),这样会消耗大量的 CPU 资源

参考资料: 极客时间 ,林晓斌 的《MySQL实战45讲》 课程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值