zoukankan      html  css  js  c++  java
  • MDL锁

    mdl锁的主要作用是用来维护表元数据的一致性。在表上有活动事务的时候,不可以对表元数据进行修改操作。

    如果没有MDL锁的保护,那么session2可以直接执行,并导致session1出错。

    MDL锁是server层级的锁,每执行一条DDL DML语句事都会申请MDL锁,MDL加锁过程事系统自动控制,无法直接干预,申请MDL锁的操作会形成1个队列,队列中写锁的优先级高于读锁的优先级。一旦出现写锁等待,不但当前操作会阻塞,同时还会阻塞针对该表的其他后续操作。

                                   MDL锁类型

                            锁的兼容性

    由于所有的mdl对象存放在全局对象中,并发量大的时候容易出现热点,出现并发瓶颈,mysql5.6中对其进行了优化:

      metadata_locks_cache_size: MDL锁的缓存大小,设定MDL缓存的上限,用来避免创建或销毁同步对象

      metadata_locks_hash_instances:通过分片来提高并发度,与InnoDB AHI类似

    MySQL5.7对MDL锁的优化:

    1. MySQL56以库名+表名的方式作为key进行分区,如果查询或者DML都集中在同一张表上,就会hash到相同的分区,依然会出现热点

    针对这点,MySQL57引入 LOCK FREE的 HASH来存储 mdl lock。

    2. 优化DML操作对于MDL锁的开销。

    大致思路是将MDL锁拆分为两类,一类是DML操作的mdl,之间相互兼容,一类是DDL操作的mdl,与其他锁互斥。

    为了实现针对DML类型的快速加锁,改用使用计数器的方式来实现,称为 FAST-PATH,如果FAST-PATH加锁失败,则走 SLOW-PATH来进行加锁。

    每个MDL锁对象都维持了一个 long long类型的状态值来标识当前的加锁 状态,变量名为 MDL_lock::m_fast_path_state。

    Session 1:BEGIN;
    Session 1: SELECT * FROM sbtest1 WHERE id =1; //m_fast_path_state = 1048576, MDL ticket 不加MDL_lock::m_granted队列


    Session 2: BEGIN;
    Session 2: SELECT * FROM sbtest1 WHERE id =2; //m_fast_path_state=1048576+1048576=2097152,同上,走FAST PATH

    Session 3: ALTER TABLE sbtest1 ENGINE = INNODB; //DDL请求加的MDL_SHARED_UPGRADABLE类型锁被视为unobtrusive lock,可以认为这个是比上述SQL的MDL锁级别更高的锁,并且不相容,因此被强制走slow path。而slow path是需要加MDL_lock::m_rwlock的写锁。
    m_fast_path_state = m_fast_path_state | MDL_lock::HAS_SLOW_PATH | MDL_lock::HAS_OBTRUSIVE


    Session 4: SELECT * FROM sbtest1 WHERE id =3; // 检查m_fast_path_state &HAS_OBTRUSIVE,如果DDL还没跑完,就会走slow path。 

    3. 彻底移除THR LOCK,完全使用MDL锁来实现。

    参考:

    https://blog.csdn.net/weixin_34204722/article/details/90618941

    http://mysql.taobao.org/monthly/2014/11/05/

    https://www.cnblogs.com/zengkefu/p/5690385.html

  • 相关阅读:
    OpenWrt VTun Client
    LibreSpeed install on centos
    信号频道带宽、符号率、速率对应关系
    DVB相关标准
    Cisco Switch STP
    TROUBLESHOOTING MULTICAST ROUTING
    企业ERP核心模型与云计算生态
    Istio介绍(1)
    ServiceMesh案例
    Jenkins流水线发布实现CICD到Kubernetes
  • 原文地址:https://www.cnblogs.com/juanmaofeifei/p/13357200.html
Copyright © 2011-2022 走看看