zoukankan      html  css  js  c++  java
  • 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 幻读

          六、阻塞

         七、死锁

         八、锁升级

  • 相关阅读:
    Arduino uno 教程~持续更新~
    Arduino uno LED灯实验
    Arduino uno 引脚说明
    面包板的使用
    数量经济学推荐的Julia教程
    已知一点经纬度和距离,方位角;求另外一点的经纬度
    a recipe kindly provided by Dimas for kikuchi
    发现了拯救“文献多的一团麻”的工具
    matlab中diff的用法
    matlabR2017安装
  • 原文地址:https://www.cnblogs.com/huan30/p/12295976.html
Copyright © 2011-2022 走看看