返回顶部
首页 > 资讯 > 数据库 >MySQL中如何使用MDL字典锁
  • 866
分享到

MySQL中如何使用MDL字典锁

2024-04-02 19:04:59 866人浏览 薄情痞子
摘要

这篇文章将为大家详细讲解有关Mysql中如何使用MDL字典锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 什么是MDL   

这篇文章将为大家详细讲解有关Mysql中如何使用MDL字典,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

  • 什么是MDL

         MDL,Meta Data lock,元数据锁,一般称为字典锁。字典锁与数据锁相对应。字典锁是为了保护数据对象被改变,一般是一些DDL会对字典对象改变,如两个TX,TX1先查询表,然后TX2试图DROP,字典锁就会lock住TX2,知道TX1结束(提交或回滚)。数据锁是保护表中的数据,如两个TX同时更新一行时,先得到row lock的TX会先执行,后者只能等待。

  • MDL的设计目标

字典锁在设计的时候是为了数据库对象的元数据。到达以下3个目的。

1. 提供对并发访问内存中字典对象缓存(table definatin cache,TDC)的保护。这是系统的内部要求。

2. 确保DML的并发性。如TX1对表T1查询,TX2同是对表T1插入。

3. 确保一些操作的互斥性,如DML与大部分DDL(ALTER TABLE除外)的互斥性。如TX1对表T1执行插入,TX2执行DROP TABLE,这两种操作是不允许并发的,故需要将表对象保护起来,这样可以保证binlog逻辑的正确性。(貌似之前的版本存在字典锁是语句级的,导致binlog不合逻辑的bug。)

  • 支持的锁类型

        数据库理论中的基本锁类型是S、X,意向锁IS、IX是为了层次上锁而引入的。比如要修改表中的数据,可能先对表上一个表级IX锁,然后再对修改的数据上一个行级X锁,这样就可以保证其他试图修改表定义的事物因为获取不到表级的X锁而等待。

        mysql中将字典锁的类型根据不同语句的功能,进一步细分,细分的依据是对字典的操作和对数据的操作。细分的好处是能在一定程度上提高并发效率,因为如果只定义X和S两种锁,必然导致兼容性矩阵的局限性。Mysql不遗余力的定义了如下的锁类型。

          可以看到MySQL在ALTER TABLE的时候还是允许其他事务进行读表操作的。需要注意的是读操作的事物需要在ALTER TABLE获取MDL_SHARED_NO_WRITE锁之后,否则无法并发。这种应用场景应该是对一个较大的表进行ALTER时,其他事物仍然可以读,并发性得到了提高。

  • 锁的兼容性

          锁的兼容性就是我们经常看到的那些兼容性矩阵,X和S必然互斥,S和S兼容。MySQL根据锁的类型我们也可以知道其兼容矩阵如下:

         1代表兼容,0代表不兼容。你可能发现X和IX竟然兼容,没错,其实这里的IX已经不是传统意义上的IX,这个IX是用在范围锁上,所以和X锁不互斥。

涉及到的和锁相关的数据结构主要是如下几个:

MDL_context:字典锁上下文。包含一个事物所有的字典锁请求。

MDL_request:字典锁请求。包含对某个对象的某种锁的请求。

MDL_ticket:字典锁排队。MDL_request就是为了获取一个ticket。

MDL_lock:锁资源。一个对象全局唯一。可以允许多个可以并发的事物同时获得。

涉及到的文件主要是sql/mdl.cc

锁资源

         锁资源在系统中是共享的,即全局的,存放在static MDL_map mdl_locks;的hash链表中,对于中的一个对象,其hashkey必然是唯一的,对应一个锁资源。多个事务同时对一张表操作时,申请的lock也是同一个内存对象。获取mdl_locks中的lock需要通过全局互斥量保护起来_mutex_lock(&m_mutex); m_mutex是MDL_map的成员。

上锁流程

        一个会话连接在实现中对应一个THD实体,一个THD对应一个MDL_CONTEXT,表示需要的mdl锁资源,一个MDL_CONTEXT中包含多个MDL_REQUEST,一个MDL_REQUEST即是对一个对象的某种类型的lock请求。每个mdl_request上有一个ticket对象,ticket中包含lock。

上锁的也就是根据MDL_REQUEST进行上锁。

Acquire_lock:

    if (mdl_request contains the needed ticket )

    return ticket;

    End if;

    Create a ticket;

    If (!find lock in lock_sys)

    Create a lock;

    End if

    If (lock can be granted to mdl_request)

    Set lock to ticket;

    Set ticket to mdl_request;

    Else

    Wait for lock

End if

          稍微解释下,首先是在mdl_request本身去查看有没有相等的或者stronger的ticket,如果存在,则直接使用。否则创建一个ticket,查找上锁对象对应的lock,没有则创建。检查lock是否可以被赋给本事务,如果可以直接返回,否则等待这个lock;

锁等待与唤醒

        字典对象的锁等待是发生在两个事物对同一对象上不兼容的锁导致的。当然,由于lock的唯一性,先到先得,后到的只能等待。

         如何判断一个lock是否可以grant给一个TX?这需要结合lock结构来看了,lock上有两个成员,grant和wait,grant代表此lock允许的事物都上了哪些锁,wait表示等待的事务需要上哪些锁。其判断一个事物是否可以grant的逻辑如下:

If(compatible(lock.grant, tx.locktype))

    If (compatible(lock.wait, tx.locktype))

    return can_grant;

    End if

End if

         即首先判断grant中的锁类型和当前事务是否兼容,然后判断wait中的锁类型和当前事务是否兼容。细心的话,会想到,wait中的锁类型是不需要和当前事务进行兼容性比较的,这是不是说这个比较是多余的了?其实也不是,因为wait的兼容性矩阵和上面的矩阵是不一样的,wait的兼容性矩阵感觉是在DDL等待的情况下,防止DML继续进来(wait矩阵就不写出来了,大家可以去代码里看下)。

比如:

TX1                                                      TX2                                                       TX3

SELECT T1

                                                             DROP  T1

                                                                                                                              SELECT T1

        这时候TX2会阻塞,TX3也会阻塞,被TX2阻塞,也就是说被wait的事件阻塞了,这样可能就是为了保证在DDL等待时,禁止再做DML了,因为在DDL面前,DML显得确实不是那么重要了。

          如何唤醒被等待的事务呢?比如唤醒TX2,当TX1结束时,会调用release_all_locks_for_name,对被锁住的事务进行唤醒,具体操作封装在reschedule_waiters函数中,重置等待时间的标记位进行唤醒,重点代码如下:

if (can_grant_lock(ticket->get_type(), ticket->get_ctx()))

    {

      if (! ticket->get_ctx()->m_wait.set_status(MDL_wait::GRANTED))

      {

       

        m_waiting.remove_ticket(ticket);

        m_granted.add_ticket(ticket);

    }

关于MySQL中如何使用MDL字典锁就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: MySQL中如何使用MDL字典锁

本文链接: https://lsjlt.com/news/58218.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MySQL中如何使用MDL字典锁
    这篇文章将为大家详细讲解有关MySQL中如何使用MDL字典锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 什么是MDL   ...
    99+
    2024-04-02
  • 如何使用mysql观测MDL锁
    如何使用mysql观测MDL锁,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在给一个小表加字段的时候,一直拿不到锁,报错:ERROR ...
    99+
    2024-04-02
  • Python中字典如何使用
    这期内容当中小编将会给大家带来有关Python中字典如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Python字典应用方式1)get(key,default=None) 返回键值key对应的值;如...
    99+
    2023-06-17
  • MySQL如何使用Navicat导出数据字典
    小编给大家分享一下MySQL如何使用Navicat导出数据字典,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!数据字典是一名DBA...
    99+
    2024-04-02
  • mysql锁如何使用
    mysql 提供多种锁类型,包括表锁和行锁(共享锁和排他锁)。表锁用于对整个表进行修改,而行锁用于并发事务中防止冲突。mysql 自动获取和释放锁,采用等待-回滚机制处理锁定冲突。优化锁...
    99+
    2024-06-15
    mysql
  • 如何使用python合并字典
    今天就跟大家聊聊有关如何使用python合并字典,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。python有哪些常用库python常用的库:1.requesuts;2.scrapy;...
    99+
    2023-06-14
  • 在Python字典中如何使用源文件
    在Python字典中如何使用源文件,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Python字典现已成为一种广泛应用的计算机语言,但是很多人对Python字典的相关应用方案还是...
    99+
    2023-06-17
  • Python中的集合和字典如何使用
    这篇文章主要讲解了“Python中的集合和字典如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python中的集合和字典如何使用”吧!1 集合集合可以使用大括号({})或者set()函...
    99+
    2023-06-29
  • mysql中如何使用乐观锁和悲观锁
    MySQL中可以使用SELECT ... FOR UPDATE语句来实现悲观锁。这个语句会在查询时锁定被查询的行,在事务结束前都不会释放锁。 例如,我们可以使用以下的 SQL 语句来锁定一个特定的行: ``` BEGIN; SELE...
    99+
    2023-09-18
    mysql
  • mysql如何使用表锁
    这篇文章给大家分享的是有关mysql如何使用表锁的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、全表更新。事务需要更新大部分或全部数据,且表又比较大。若使用行锁,会导致事务执行效率低,从而可能造成其他事务长时间...
    99+
    2023-06-15
  • 如何使用Hanlp加载大字典
    这篇文章将为大家详细讲解有关如何使用Hanlp加载大字典,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 问题因为需要加载一个 近 1G 的字典到Hanlp中,一开始使用了...
    99+
    2024-04-02
  • python如何使用字典get方法
    这篇文章将为大家详细讲解有关python如何使用字典get方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。字典 get 方法关于“python如何使用字典get方法”这...
    99+
    2024-04-02
  • python如何使用字典dict统计
    这篇文章主要介绍python如何使用字典dict统计,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!使用字典 dict 统计循环遍历出一个可迭代对象的元素,如果字典中没有该元素,那么就让该元素作为字典的键,并将该键赋值...
    99+
    2023-06-27
  • Python字典和集合如何使用
    这篇文章主要介绍“Python字典和集合如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python字典和集合如何使用”文章能帮助大家解决问题。字典简介Python 中字典和集合也是非常相近的...
    99+
    2023-07-04
  • python中字典update函数如何用
    在python中使用字典update函数的方法update:update()函数的作用是将字典dict2的键或值对更新到dict中。update()函数语法:dict.update(dict2)参数:dict2:添加到指定字典dict里的字...
    99+
    2024-04-02
  • 如何在mysql中使用悲观锁与乐观锁析
    如何在mysql中使用悲观锁与乐观锁析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、悲观锁顾名思义,就是对于数据的处理持悲观态度,总认...
    99+
    2024-04-02
  • 如何使用Python实现字典合并
    这篇文章给大家分享的是有关如何使用Python实现字典合并的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、用for循环把一个字典合并到另一个字典把a字典合并到b字典中,相当于用for循环遍历a字典,然后取出a字...
    99+
    2023-06-29
  • python如何使用字典来存储switch
    这篇文章主要为大家展示了“python如何使用字典来存储switch”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“python如何使用字典来存储switch”这篇文章吧。使用字典来存储 swit...
    99+
    2023-06-27
  • 如何用Navicat导出MySQL的数据字典
    方法如下: 利用mysql的information_schema 库中的COLUMNS表信息来实现 例如需要导出ixinnuo_zxpt库的数据字典信息: 打开Navicat,选择查询-->新建查询:...
    99+
    2024-04-02
  • 使用PHP生成MySQL数据字典
    一个项目完成之后,按照需求,我需要给这个项目写设计文档,数据库字典。 设计文档到时好说,但是数据库字典可真的是有点吓到我了。 项目开始的比较急,最开始建数据库的时候没有用excel写数据库字典。 这几十张表的数据库,一个一个的写,那真的是酸...
    99+
    2023-09-11
    php mysql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作