真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

MySQL中如何使用MDL字典鎖

這篇文章將為大家詳細(xì)講解有關(guān)MySQL中如何使用MDL字典鎖,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

紫金網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),紫金網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為紫金1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的紫金做網(wǎng)站的公司定做!

  • 什么是MDL

         MDL,Meta Data lock,元數(shù)據(jù)鎖,一般稱為字典鎖。字典鎖與數(shù)據(jù)鎖相對(duì)應(yīng)。字典鎖是為了保護(hù)數(shù)據(jù)對(duì)象被改變,一般是一些DDL會(huì)對(duì)字典對(duì)象改變,如兩個(gè)TX,TX1先查詢表,然后TX2試圖DROP,字典鎖就會(huì)lock住TX2,知道TX1結(jié)束(提交或回滾)。數(shù)據(jù)鎖是保護(hù)表中的數(shù)據(jù),如兩個(gè)TX同時(shí)更新一行時(shí),先得到row lock的TX會(huì)先執(zhí)行,后者只能等待。

  • MDL的設(shè)計(jì)目標(biāo)

字典鎖在設(shè)計(jì)的時(shí)候是為了數(shù)據(jù)庫(kù)對(duì)象的元數(shù)據(jù)。到達(dá)以下3個(gè)目的。

1. 提供對(duì)并發(fā)訪問(wèn)內(nèi)存中字典對(duì)象緩存(table definatin cache,TDC)的保護(hù)。這是系統(tǒng)的內(nèi)部要求。

2. 確保DML的并發(fā)性。如TX1對(duì)表T1查詢,TX2同是對(duì)表T1插入。

3. 確保一些操作的互斥性,如DML與大部分DDL(ALTER TABLE除外)的互斥性。如TX1對(duì)表T1執(zhí)行插入,TX2執(zhí)行DROP TABLE,這兩種操作是不允許并發(fā)的,故需要將表對(duì)象保護(hù)起來(lái),這樣可以保證binlog邏輯的正確性。(貌似之前的版本存在字典鎖是語(yǔ)句級(jí)的,導(dǎo)致binlog不合邏輯的bug。)

  • 支持的鎖類型

        數(shù)據(jù)庫(kù)理論中的基本鎖類型是S、X,意向鎖IS、IX是為了層次上鎖而引入的。比如要修改表中的數(shù)據(jù),可能先對(duì)表上一個(gè)表級(jí)IX鎖,然后再對(duì)修改的數(shù)據(jù)上一個(gè)行級(jí)X鎖,這樣就可以保證其他試圖修改表定義的事物因?yàn)楂@取不到表級(jí)的X鎖而等待。

        MySQL中將字典鎖的類型根據(jù)不同語(yǔ)句的功能,進(jìn)一步細(xì)分,細(xì)分的依據(jù)是對(duì)字典的操作和對(duì)數(shù)據(jù)的操作。細(xì)分的好處是能在一定程度上提高并發(fā)效率,因?yàn)槿绻欢xX和S兩種鎖,必然導(dǎo)致兼容性矩陣的局限性。MySQL不遺余力的定義了如下的鎖類型。

          可以看到MySQL在ALTER TABLE的時(shí)候還是允許其他事務(wù)進(jìn)行讀表操作的。需要注意的是讀操作的事物需要在ALTER TABLE獲取MDL_SHARED_NO_WRITE鎖之后,否則無(wú)法并發(fā)。這種應(yīng)用場(chǎng)景應(yīng)該是對(duì)一個(gè)較大的表進(jìn)行ALTER時(shí),其他事物仍然可以讀,并發(fā)性得到了提高。

  • 鎖的兼容性

          鎖的兼容性就是我們經(jīng)??吹降哪切┘嫒菪跃仃嚕琗和S必然互斥,S和S兼容。MySQL根據(jù)鎖的類型我們也可以知道其兼容矩陣如下:

         1代表兼容,0代表不兼容。你可能發(fā)現(xiàn)X和IX竟然兼容,沒(méi)錯(cuò),其實(shí)這里的IX已經(jīng)不是傳統(tǒng)意義上的IX,這個(gè)IX是用在范圍鎖上,所以和X鎖不互斥。

  • 數(shù)據(jù)結(jié)構(gòu)

涉及到的和鎖相關(guān)的數(shù)據(jù)結(jié)構(gòu)主要是如下幾個(gè):

MDL_context:字典鎖上下文。包含一個(gè)事物所有的字典鎖請(qǐng)求。

MDL_request:字典鎖請(qǐng)求。包含對(duì)某個(gè)對(duì)象的某種鎖的請(qǐng)求。

MDL_ticket:字典鎖排隊(duì)。MDL_request就是為了獲取一個(gè)ticket。

MDL_lock:鎖資源。一個(gè)對(duì)象全局唯一??梢栽试S多個(gè)可以并發(fā)的事物同時(shí)獲得。

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

鎖資源

         鎖資源在系統(tǒng)中是共享的,即全局的,存放在static MDL_map mdl_locks;的hash鏈表中,對(duì)于中的一個(gè)對(duì)象,其hashkey必然是唯一的,對(duì)應(yīng)一個(gè)鎖資源。多個(gè)事務(wù)同時(shí)對(duì)一張表操作時(shí),申請(qǐng)的lock也是同一個(gè)內(nèi)存對(duì)象。獲取mdl_locks中的lock需要通過(guò)全局互斥量保護(hù)起來(lái)_mutex_lock(&m_mutex); m_mutex是MDL_map的成員。

上鎖流程

        一個(gè)會(huì)話連接在實(shí)現(xiàn)中對(duì)應(yīng)一個(gè)THD實(shí)體,一個(gè)THD對(duì)應(yīng)一個(gè)MDL_CONTEXT,表示需要的mdl鎖資源,一個(gè)MDL_CONTEXT中包含多個(gè)MDL_REQUEST,一個(gè)MDL_REQUEST即是對(duì)一個(gè)對(duì)象的某種類型的lock請(qǐng)求。每個(gè)mdl_request上有一個(gè)ticket對(duì)象,ticket中包含lock。

上鎖的也就是根據(jù)MDL_REQUEST進(jìn)行上鎖。

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本身去查看有沒(méi)有相等的或者stronger的ticket,如果存在,則直接使用。否則創(chuàng)建一個(gè)ticket,查找上鎖對(duì)象對(duì)應(yīng)的lock,沒(méi)有則創(chuàng)建。檢查lock是否可以被賦給本事務(wù),如果可以直接返回,否則等待這個(gè)lock;

鎖等待與喚醒

        字典對(duì)象的鎖等待是發(fā)生在兩個(gè)事物對(duì)同一對(duì)象上不兼容的鎖導(dǎo)致的。當(dāng)然,由于lock的唯一性,先到先得,后到的只能等待。

         如何判斷一個(gè)lock是否可以grant給一個(gè)TX?這需要結(jié)合lock結(jié)構(gòu)來(lái)看了,lock上有兩個(gè)成員,grant和wait,grant代表此lock允許的事物都上了哪些鎖,wait表示等待的事務(wù)需要上哪些鎖。其判斷一個(gè)事物是否可以grant的邏輯如下:

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

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

    return can_grant;

    End if

End if

         即首先判斷grant中的鎖類型和當(dāng)前事務(wù)是否兼容,然后判斷wait中的鎖類型和當(dāng)前事務(wù)是否兼容。細(xì)心的話,會(huì)想到,wait中的鎖類型是不需要和當(dāng)前事務(wù)進(jìn)行兼容性比較的,這是不是說(shuō)這個(gè)比較是多余的了?其實(shí)也不是,因?yàn)閣ait的兼容性矩陣和上面的矩陣是不一樣的,wait的兼容性矩陣感覺(jué)是在DDL等待的情況下,防止DML繼續(xù)進(jìn)來(lái)(wait矩陣就不寫出來(lái)了,大家可以去代碼里看下)。

比如:

TX1                                                      TX2                                                       TX3

SELECT T1

                                                             DROP  T1

                                                                                                                              SELECT T1

        這時(shí)候TX2會(huì)阻塞,TX3也會(huì)阻塞,被TX2阻塞,也就是說(shuō)被wait的事件阻塞了,這樣可能就是為了保證在DDL等待時(shí),禁止再做DML了,因?yàn)樵贒DL面前,DML顯得確實(shí)不是那么重要了。

          如何喚醒被等待的事務(wù)呢?比如喚醒TX2,當(dāng)TX1結(jié)束時(shí),會(huì)調(diào)用release_all_locks_for_name,對(duì)被鎖住的事務(wù)進(jìn)行喚醒,具體操作封裝在reschedule_waiters函數(shù)中,重置等待時(shí)間的標(biāo)記位進(jìn)行喚醒,重點(diǎn)代碼如下:

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

    {

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

      {

        /*

          Satisfy the found request by updating lock structures.

          It is OK to do so even after waking up the waiter since any

          session which tries to get any information about the state of

          this lock has to acquire MDL_lock::m_rwlock first and thus,

          when manages to do so, already sees an updated state of the

          MDL_lock object.

        */

        m_waiting.remove_ticket(ticket);

        m_granted.add_ticket(ticket);

    }

關(guān)于MySQL中如何使用MDL字典鎖就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。


文章題目:MySQL中如何使用MDL字典鎖
鏈接地址:http://weahome.cn/article/pssjdj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部