01.24 Day 5 - MySQL 的全局锁、表锁、行锁

大家好,我是 Snow Hide,作为《MySQL 实战》这个专栏的学员之一,这是我打卡的第 5 天,也是我第 45 次进行这种操作。

今天我温习了该专栏里叫《全局锁和表锁 :给表加个字段怎么有这么多阻碍?》、《行锁功过:怎么减少行锁对性能的影响?》的文章。

关键词总结:锁分类、全局锁(加锁方法、应用场景、风险、建议使用 FTWRL 方式的两个原因)、表级锁(表级锁种类(表锁、元数据锁、MDL 读写锁))、支持行锁的引擎、两阶段锁(行锁的释放时间)、死锁和死锁检测(解决死锁的两种策略、解决热点行更新导致的性能问题)。

所学总结:

锁分类

全局锁、表级锁、行锁。
 

全局锁

加锁方法

FTWRL(Flush Tables With Read Lock),让整库处于只读状态,此时其他线程所运行的一些语句会被阻塞:数据更新(增删改)、数据定义(建表、修改表结构)、更新类事务提交。

应用场景

全库逻辑备份。

风险

  • 主库加锁期间不能执行更新,业务暂停运作;
  • 从库加锁期间不能执行主库同步过来的 binlog,导致主从延迟。

建议使用 FTWRL 方式的两个原因

  • readonly 在一些系统中会被用作其他逻辑,例如判断是主库还是备库。因此修改 global 变量的影响比较大;
  • 执行 FTWRL 后客户端如果发生异常断开,库全局锁会自动释放,并回到正常状态。如果设置为 readonly 期间客户端发生异常,库会一直保持 readonly 状态,不会回到正常状态。
     

表级锁

表级锁种类

表锁、元数据锁(MDL,Meta Data Lock)

表锁

lock tables … read/write。与 FTWRL 类似,可以借助 unlock tables 来释放锁或在客户端断开时自动释放锁。lock tables 除了限制其他线程的读写外,还会限制本线程接下来的操作对象。

元数据锁

无须显式声明,访问表时自动上锁,并保证读写正确性。

MDL 读写锁

  • 读锁不互斥,可以多线程对表进行增删改查;
  • 读写锁的写锁互斥,保证表结构变更的安全性。多线程按顺序操作表结构。
     

支持行锁的引擎

InnoDB 支持行锁。
 

两阶段锁

行锁的释放时间

等到事务结束时才释放。
 

死锁和死锁检测

解决死锁的两种策略

  • 等待超时。设置超时参数:innodb_lock_wait_timeout;
  • 发起死锁检测,回滚死锁链条的一个事务,让其他事务可以继续。设置参数 innodb_deadlock_detech 为 on。

解决热点行更新导致的性能问题

  • 在确保业务不会出现死锁的情况下临时关掉死锁检测,关掉死锁检测可能会出现大量超时;
  • 控制并发度。同行更新在进入引擎之前排队,以减少 InnoDB 内部的死锁检测工作;
  • 通过将一行改成逻辑上的多行来减少冲突,以减少锁等待个数。

末了

重新总结了一下文中提到的内容:全局锁、表级锁、全局锁应用场景、表锁应用场景、MDL 元数据锁、行锁、两阶段锁协议、死锁以及死锁检测、控制访问相同资源的并发事务量。

发布了81 篇原创文章 · 获赞 6 · 访问量 1850

猜你喜欢

转载自blog.csdn.net/stevenchen1989/article/details/104079261