Mysql锁机制及原理简析

本文深入探讨了MySQL的锁机制,包括前言、锁的分类(悲观锁、乐观锁、共享锁/读锁、排他锁/写锁、行锁、表锁、页面锁、全局锁、记录锁、间隙锁、临键锁、意向锁)、存储引擎的锁支持、InnoDB行锁的实现原理、InnoDB的加锁方法(隐式锁定、显式锁定)以及死锁的避免和处理。内容覆盖了锁在数据库并发控制中的重要性和不同类型的锁在不同场景下的应用,旨在帮助读者理解和优化数据库的并发性能。
摘要由CSDN通过智能技术生成

Mysql锁机制及原理简析

一.前言

1.什么是锁?

锁是计算机协调多个进程或线程并发访问某一资源的机制

  • 锁保证数据并发访问的一致性、有效性;
  • 锁冲突也是影响数据库并发访问性能的一个重要因素。
  • 锁是Mysql在服务器层和存储引擎层的的并发控制

2.为什么要加锁?

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

锁是用于管理对公共资源的并发控制。也就是说在并发的情况下,会出现资源竞争,所以需要加锁。

加锁解决了 多用户环境下保证数据库完整性和一致性

Lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同)。

二.锁的分类

总共可以按照四个方向对锁进行分类

1.按照加锁的机制进行分类
1).悲观锁
  • 假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。悲观锁是数据库层面加锁,都会阻塞去等待锁。
2).乐观锁
  • 假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。
  • 乐观锁是一种思想,具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段。处理完业务逻辑开始更新的时候,需要再次查看该字段的值是否和第一次的一样。如果一样更新,反之拒绝。之所以叫乐观,因为这个模式没有从数据库加锁,等到更新的时候再判断是否可以更新。
  • 缺点:并发很高的时候,多了很多无用的重试。乐观锁,不能解决脏读的问题。
2.按照锁的兼容性或锁的可重入性进行分类
1).共享锁/读锁/S 锁(share lock)
  • 其他事务可以读,但不能写。允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
2).排他锁/写锁/X 锁(exclusive)
  • 其他事务不能读取,也不能写。允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。
3.按照锁的粒度进行分类
1).行锁(row-level locking)
  • 即只允许事务读一行数据。行锁的粒度实在每一条行数据,当然也带来了最大开销,但是行锁可以最大限度的支持并发处理。
  • 开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
  • 最大程度的支持并发,同时也带来了最大的锁开销。
  • 行级锁更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统
  • 在 InnoDB 中,除单个 SQL 组成的事务外,锁是逐步获得的,这就决定了在 InnoDB 中发生死锁是可能的。
  • 行级锁只在存储引擎层实现,而Mysql服务器层没有实现。
2).表锁
  • 允许事务在行级上的锁和表级上的锁同时存在。锁定整个表,开销最小,但是也阻塞了整个表。
  • 开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。这些存储引擎通过总是一次性同时获取所有需要的锁以及总是按相同的顺序获取表锁来避免死锁。
  • 表级锁更适合于以查询为主,并发用户少,只有少量按索引条件更新数据的应用,如Web 应用。
    • 若一个用户正在执行写操作,会获取排他的“写锁”,这可能会锁定整个表,阻塞其他用户的读、写操作;
    • 若一个用户正在执行读操作,会先获取共享锁“读锁”,这个锁运行其他读锁并发的对这个表进行读取,互不干扰。只要没有写锁的进入,读锁可以是并发读取统一资源的。
  • Mysql的表级别锁分为两类:元数据锁(Metadata Lock,MDL)、表锁。
    • 元数据锁/MDL锁
      • 元数据锁(MDL) 不需要显式使用,在访问一个表的时候会被自动加上。这个特性需要MySQL5.5版本以上才会支持
      • 当对一个表做增删改查的时候,该表会被加MDL读锁,当对表做结构变更的时候,加MDL写锁
      • MDL锁的规则:
        • 读锁之间不互斥,所以可以多线程多同一张表进行增删改查。
        • 读写锁、写锁之间是互斥的,为了保证表结构变更的安全性,所以如果要多线程对同一个表加字段等表结构操作,就会变成串行化,需要进行锁等待。
        • MDL的写锁优先级比MDL读锁的优先级,但是可以设置max_write_lock_count系统变量来改变这种情况,当写锁请求超过这个变量设置的数后,MDL读锁的优先级会比MDL写锁的优先级高。(默认情况下,这个数字会很大,所以不用担心写锁的优先级下降)
        • MDL的锁释放必须要等到事务结束才会释放
3).页面锁
  • 页级锁定是 MySQL 中比较独特的一种锁定级别,在其他数据库管理软件中也并不是太常见。
  • 页面锁开销和加锁时间界于表锁和行锁之间&
  • 3
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值