• MDL--元数据锁的锁请求与锁等待+元数据锁类对象


    1 元数据锁的锁请求与锁等待

        元数据锁在MySQL Server层,依照锁的状态被细分为两种。一种是已经施加的锁。一种是等待施加的锁即锁请求,这样被区分的原因,如MySQL对“class MDL_request”的代码凝视作了解释:

    /**

      A pending metadata lock request.

     

      A lock request and a granted metadata lock are represented by

      different classes because they have different allocation

      sites and hence different lifetimes. The allocation of lock requests is     //注意这里给出的原因是从project实践中对锁的实现的角度区分的

      controlled from outside of the MDL subsystem, while allocation of granted   //体现了project与理论的不同

      locks (tickets) is controlled within the MDL subsystem.

     

      MDL_request is a C structure, you don't need to call a constructor

      or destructor for it.

    */

    class MDL_request{...}  //锁请求

        所以,元数据锁在使用的过程中又被细分为“lock granted metadata” (代码中使用“class MDL_ticket”表示。

    ticket,入场卷。即要被授予的锁)和“lock request metadata”(代码中使用“class MDL_request”表示加锁的请求)。

    这样,MySQL Server分别使用两个类来表示这两种被细分的锁。

        当锁请求要求施加锁不成功的时候,则产生锁等待,而锁等待则用MDL_wait表示。

    /**A reliable way to wait on an MDL lock. */

    class MDL_wait{...  //锁等待。在获取锁的过程中,须要为是否获得锁做标志。採用的就是锁等待的状态值

    enum enum_wait_status { //锁等待的状态,在锁等待在生命周期内因不同操作产生不同结果

        EMPTY = 0, //空状态。初始值

        GRANTED,   //锁被授予的状态

        VICTIM,    //某个会话被选为了受害者

        TIMEOUT,   //超时状态,申请加锁却发生超时

        KILLED };  //killed状态,发起锁请求的会话被killed掉。所以不仅是发起加锁请求的事务应终止,事务的属主会话也被终止

    ...}

    2 元数据锁类对象

        保存每一MDL_key相应的全部已经授予的MDL锁信息,由于MDL_key标识了不同的数据库对象类,不同的数据库对象类上所施加的锁之间的兼容性因对象存在区别,所以定义了不同的策略来区分这些区别。请注意,MDL_lock不是一个详细的锁,而是一类锁的集合

    GLOBALCOMMIT类的锁。是全局唯一的。除此之外的其它类型的锁,能够有多个。

    /**

    The lock context. Created internally for an acquired lock.

     For a given name, there exists only one MDL_lock instance,and it exists only when the lock has been granted. 

    Can be seen as an MDL subsystem's version of TABLE_SHARE.  //能够被存储层的TABLE_SHARE使用这个锁对象

     

    This is an abstract class which lacks information aboutcompatibility rules for lock types.

     They should be specifiedin its descendants. 

    */

    class MDL_lock  //当须要施加元数据锁的时候。生成一个MDL_lock锁对象

    {...

        class Ticket_list{...}  //MDL_ticket封装为一个 List对象,用以存放多个MDL_ticket锁对象(MDL_ticket參见下一小节)

     

        /**  //对于锁的操作,又存在两种策略。这是依据被加锁的对象的特定区分的。

    每一种策略分别有各自的锁兼容规则

          Helper struct which defines how different types of locks are handledfor a specific MDL_lock.

          In practice we use only two strategies:

          "scoped"lock strategy for locks in GLOBAL, COMMIT, TABLESPACE and SCHEMA namespaces  //范围锁策略:范围带有空间的意味

          and "object" lock strategy for all other namespaces.                                 //对象锁策略:数据库内部的各种对象

         */

        struct MDL_lock_strategy //锁的施加策略。如上所述,锁被分为两种类型,所以统一用策略数据结构来管理和描写叙述这两类锁的特性

        {

            /**Compatibility (or rather "incompatibility") matrices for lock types. //新申请的锁向已经授予的锁进行锁的相容性推断

                Array of bitmaps which elements specify which granted locks areincompatible with the type of lock being requested.*/   

            bitmap_tm_granted_incompatible[MDL_TYPE_END];  //已经被授予的锁的数组中保存有不兼容的、准备申请此对象的请求锁,位图数组结构

     

            //新申请的锁向已经正在等待的锁进行锁的相容性(优先级)推断。此数组的作用有两个:

            //一是通过m_waiting_incompatible[0]

            //二是防止产生锁饥饿现象,

            //所以添加了对低优先级锁的申请次数的计数。当计数到一定程度时,唤醒低优先级的尚没获得锁的会话。

            //能够关注MDL_lock::reschedule_waiters()函数。查看对等待的锁的处理方式;看其调用者查看唤醒条件。

            //另外看此函数中封锁粒度较强的锁释放而封锁粒度较弱的锁得以有机会被授予的时候,

            //m_hog_lock_count/m_piglet_lock_count有机会被重置

            //(注意强弱是相对的,取决于11.4.1节中第3小节中定义的enum_mdl_type中的锁的粒度值。据这些值比較大小)

             /** Arrays of bitmaps which elements specify which waiting locks areincompatible with the type of lock being requested.

                Basically, eacharray defines priorities between lock types.

               We need 4 separate arrays since in order to prevent starvation for some of lock request types, we use different priority matrices:

              0) in "normal" situation.  //正常优先级

              1) in situation when the number of successively granted "piglet" requestsexceeds the max_write_lock_count limit. //小猪优先级

              2) in situation when the number of successively granted "hog" requestsexceeds the max_write_lock_count limit. //猪优先级

              3) in situation when both "piglet" and "hog" counters exceed limit.*/  //小猪和猪之和

            //这个矩阵是某个锁请求与处于等待状态的锁的优先级比較表

             //第一个数组是正常情况,其它三个数组是为解决锁饥饿而设置的

             //m_piglet_lock_count的值大于了max_write_lock_count。则m_waiting_incompatible[1][x]被置位

            //m_hog_lock_count的值大于了max_write_lock_count。则m_waiting_incompatible[2][x]被置位

            //在等待的锁的数组中保存有不兼容的、准备申请此对象的请求锁,二维位图数组结构

            bitmap_tm_waiting_incompatible[4][MDL_TYPE_END];//piglet,会申请SW锁;hog。会申请XSNRWSNW这三者其一

     

            /**Array of increments for "unobtrusive" types of lock requests for locks.

               @sa MDL_lock::get_unobtrusive_lock_increment().*/

            //“unobtrusive”类型相关的锁粒度包含: SSHSR SW。相应“Fast path”的訪问方式,主要用于DML类操作

            //obtrusive” 类型相关的锁粒度包含:SUSROSNWSNRWX。相应“slow path”的訪问方式,主要用于非DML类操作

            fast_path_state_tm_unobtrusive_lock_increment[MDL_TYPE_END]; //高速訪问“unobtrusive”类型的锁

     

            /**Indicates that locks of this type are affected bythe max_write_lock_count limit.*/

            bool m_is_affected_by_max_write_lock_count;

     

            /**Pointer to a static method which determines if the type of lockrequested requires notification of conflicting locks.

               NULL if thereare no lock types requiring notification.*/

            //当有冲突锁的时候,是否要被通知。

    scopedlock”不要求被通知。而“object lock”施加排它锁时才须要被通知

            bool (*m_needs_notification)(const MDL_ticket *ticket);

     

            /**Pointer to a static method which allows notification of owners ofconflicting locksabout the fact

               that a type of lock requiringnotification was requested.*/

            //对于“object lock”,通知持有SSH类锁的会话线程(可能与待定的X锁冲突。pending lock

            void (*m_notify_conflicting_locks)(MDL_context *ctx, MDL_lock *lock); //发出通知的函数,含义相似上面

     

            /**Pointer to a static method which converts information aboutlocks granted using "fast" path

               from fast_path_state_trepresentation to bitmap of lock types.*/

            //SSRSW粒度的锁能够被使用“fast path”方式高速处理

            bitmap_t (*m_fast_path_granted_bitmap)(const MDL_lock &lock);

     

             /**Pointer to a static method which determines if waiting for the lockshould be aborted

               when connection is lost. NULL if locks ofthis type don't require such aborts.*/ //当连接断开的时候,锁是否应该被撤销。

            //LOCKING_SERVICEUSER_LEVEL_LOCK加锁的情况可被撤销,如通过GET_LOCK()施加的锁

            bool (*m_needs_connection_check)(const MDL_lock *lock);

        };

     

    public:

        /** The key of the object (data) being protected. */

         MDL_key key;   //元数据锁所属的类型(在MDL_key中把元数据这种对象分为了几类,给每类定义一个keyenum_mdl_namespace枚举中)

        /** List of granted tickets for this lock. */

        Ticket_list m_granted;  //对于本锁而言,在系统内部存在的已经被授予的全部锁list

        /** Tickets for contexts waiting to acquire a lock. */

    Ticket_list m_waiting; //对于本锁而言,在系统内部存在的正在等待被授予的全部锁list

    //如上两个list,配合使用:

    //当要获取一个锁(入通过acquire_lock()函数)不成功时。把新生成的一个MDL_ticket对象放入等待队列。获取成功。则放入m_granted

    //当一个处于等待状态的锁能够被授予的时候(can_grant_lock()推断能否够被授予)。就从m_waitingremove掉,然后添加到m_granted中,

    //这种事情,当获取锁或释放锁时,或因ALTER TABLE等操作须要降级锁时,通过reschedule_waiters()函数进行

    ...

        /** Pointer to strategy object which defines how different types of lock

            requests should be handled for the namespace to which this lock belongs.

            @sa MDL_lock::m_scoped_lock_strategy and MDL_lock:m_object_lock_strategy. */

        const MDL_lock_strategy *m_strategy; //注意这是一个指针。运行哪个类型的策略就表示使用被指向的策略对象之策略(指向以下两个策略对象之中的一个)

    ...

        static const MDL_lock_strategy m_scoped_lock_strategy; //范围锁相应的策略

        static const MDL_lock_strategy m_object_lock_strategy; //对象锁相应的策略

    };

  • 相关阅读:
    Siege 3.0 正式版发布,压力测试工具
    Pomm 1.1.2 发布,专为 PG 设计的 ORM 框架
    Whonix 0.5.6 发布,匿名通用操作系统
    国内开源 java cms,Jspxcms 2.0 发布
    EZNamespaceExtensions.Net v2013增加对上下文菜单、缩略图、图标、属性表的支持
    GNU Guile 2.0.9 发布,Scheme 实现
    jdao 1.0.4 发布 轻量级的orm工具包
    OpenSearchServer 1.4 RC4 发布
    Percona Server for MySQL 5.5.3030.2
    Samba 4.0.5 发布
  • 原文地址:https://www.cnblogs.com/llguanli/p/8385760.html
Copyright © 2020-2023  润新知