• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
gaohuan30
博客园    首页    新随笔    联系   管理    订阅  订阅
MySQL锁概述

  锁(locking)的机制是区分数据库系统和文件系统的一个关键特征。

  锁机制用于管理对共享资源的并发访问。InnoDB存储引擎会在行级别上对表数据上锁,这固然不错。不过InnoDB存储引擎也会在数据库内部其他多个地方使用锁,从而允许对多种不同资源提供并发访问。例如:操作缓冲池中的LRU(Least Recently Used的缩写,即最近最少使用)列表,删除,添加,移动LRU列表中的元素,为了保证一致性,必须有锁的介入。数据库系统使用锁是为了对共享资源进行并发访问。保证数据的完整性和一致性。

     一、各数据库不同或存储引擎不同,锁实现也不同

  对于MyISAM引擎,其锁是表锁设计,并发情况下读没有问题,但是并发插入时的性能就要差一些了。

  对于Microsoft SQL Server数据库,在Microsoft SQL Server2005版之前其都是页锁的,相对表锁的MyISAM引擎来说,并发性能有所提升。页锁容易实现,然而对于热点数据页的并发问题依然不能为例。

                 到了2005版本,Microsoft SQL Server开始支持乐观并发和悲观并发,在乐观并发下开始支持行级锁,但是其实现方式与InnoDB存储引擎的实现方式完全不同。在Microsoft SQL Server下,锁是一种稀有的资源,锁越多开销就越大,因此它会有锁升级,这种情况下,行锁会升级到表锁,这时并发的性能又回到了从前。

  Oracle和InnoDB存储引擎锁的实现类似,提供一致性的非锁定读、行级锁支持。行锁没有额外相关开销,并可以同时得到并发性和一致性。

      二、lock 与 latch

  在数据库中,lock与latch都可以被成为“锁”,但是二者有着截然不同的含义。

  latch一般称为闩(shuan)锁(轻量级的锁),因为其要求锁定的时间必须非常短,若持续的时间长,则应用的性能会非常差。在InnoDB存储引擎中,latch又可以被分为mutex(互斥锁)和rwlock(读写锁)。其目的是用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。

  lock的对象是事务,用来锁定的是数据库中的对象,如 表、页、行。并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离界别释放的时间可能不同)。此外,lock正如大多数数据库中一样,是有死锁机制的。

  (

当出现死锁以后,有两种策略:

  • 一种策略是,直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。
  • 另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑。

  )

                     lock 与latch的对比

  lock latch
对象  事务 线程
保护 数据库内容 内存数据结构
持续时间 整个事务过程 临界资源
模式 行锁、表锁、意向锁 读写锁,互斥锁
死锁 通过waits-for graph、time out等机制进行死锁检测与处理 无死锁检测与处理机制,仅通过应用程序加锁的顺序(lock leveling)保证无死锁的情况发生
存在于 lock Manager的哈希表中 每个数据结构的对象中

                  show engineinnodb mutex; 查看latch信息

      三、InnoDB引擎中的锁

    3.1 锁的类型

      InnoDB存储引擎实现了如下两种标准的行级锁:

      共享锁(S Lock),允许事务读一行数据。    select.....lock in share mode

      排他锁(X Lock),允许事务删除或更新一行数据  select .......for update

    锁兼容:如果一个事务T1已经获得了行r的共享锁,那么另外的事务T2可以立即执行获取行r的共享锁,因为读取并没有改变行r的数据。

    锁不兼容:但若有其他事务T3想获得r的排他锁,则其必须等待事务T1 T2释放行r上的共享锁。

                   排他锁和共享锁的兼容性

  X S
X 不兼容 不兼容
S 不兼容 兼容

    可以发现,X锁与任何的锁都不兼容,而S锁仅与S锁兼容。

    此外,InnoDB存储引擎支持多粒度(granular)锁定,这种锁定允许事务在行级上和表级上的锁同时存在。为了支持在不同粒度上进行加锁操作,InnoDB存储引擎支持一种额外的锁方式,称之为意向锁(Intention Lock)。意向锁是将锁定的对象分为多个层次,意向锁意味着事务希望在更细粒度(fine granularity)上进行加锁。

  若将上锁的对象堪称一棵树,那么对最下层的对象上锁,也就是对最细粒度的对象进行上锁,那么首先需要对粗粒度的对象上锁。如下图:如果需要对页上的记录r上X锁,那么需要分别对数据库A、表、页上意向锁IX,最后对记录r上X锁。若其中任何一个部分导致等待,那么该操作需要等待粗粒度锁的完成。

     InnoDB存储引擎支持意向锁设计比较简练,其意向锁即为表级别的锁。设计目的的主要是为了在一个事务中揭示下一行将被请求的锁类型。

     1)意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁

     2)意向排他锁(IX Lock),事务想要获得一张表中某几行的排他锁

  IS IX S X
IS 兼容 兼容 兼容 不兼容
IX 兼容 兼容 不兼容 不兼容
S 兼容 不兼容 兼容 不兼容
X 不兼容 不兼容 不兼容 不兼容

     检查MySQL锁请求状态  show engine innodb status

    information_schema.INNODB_TAX 描述当前事务状态

    information_schema.INNODB_LOCKS 描述当前锁状态

    information_schema.INNODB_LOCK_WAITS 描述事务和锁的对应关系

        3.2 一致性非锁定读

        3.3 一致性锁定读

        3.4  自增长与锁

        3.5  外键和锁

      四、锁的算法

        4.1 行锁的三种算法

        4.2 解决 Phantom Problem (幻读问题)

      五、锁问题

        5.1 脏读

        5.2 不可重复度

        5.3 幻读

      六、阻塞

     七、死锁

     八、锁升级

posted on 2020-02-14 21:10  gaohuan30  阅读(266)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3