自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么執(zhí)行 Alter 更新表要慎重?

數(shù)據(jù)庫 MySQL
天我想和大伙分享一個經(jīng)常容易被忽略的鎖,那就是 MDL,這個鎖如果忽略了,可能會導(dǎo)致大問題,一起來看下。

[[442094]]

說到 MySQL 中的鎖,相信小伙伴們多多少少都能說出來一些,例如全局鎖、表鎖、行鎖等等。

今天我想和大伙分享一個經(jīng)常容易被忽略的鎖,那就是 MDL,這個鎖如果忽略了,可能會導(dǎo)致大問題,一起來看下。

1. MDL 鎖介紹

MDL 全稱為 meta data lock,中文稱作元數(shù)據(jù)鎖,這是從 MySQL5.5 開始引入的鎖,MDL 是為了解決 DDL 操作和 DML 操作之間的一致性。從鎖的作用范圍上來說,MDL 算是一種表級鎖,是一個 server 層的鎖。

大家想想這樣一個場景:當(dāng)我們通過 alter 語句更新一張表的時候,同時又針對這張表執(zhí)行了查詢語句,假設(shè)兩者同時執(zhí)行,那么將來查詢到的結(jié)果可能就并不是我們想要的結(jié)果,也就是數(shù)據(jù)一致性出了問題。

為了解決這個問題,從 MySQL5.5 開始推出了 MDL。

可能有小伙伴會說好像我從來沒寫過跟 MDL 有關(guān)的鎖呀?

其實(shí) MDL 加鎖過程是系統(tǒng)自動控制,無法直接干預(yù),也不需要直接干預(yù),當(dāng)我們對一個表做增刪改查操作的時候,會自動加 MDL 讀鎖;當(dāng)我們要更新表結(jié)構(gòu)的時候,加 MDL 寫鎖。加讀鎖則所有線程可正常讀表的元數(shù)據(jù),并且讀鎖不影響表的增刪改查操作,只是不能修改表結(jié)構(gòu);而加寫鎖則只有擁有鎖的線程可以讀寫元數(shù)據(jù),即只有擁有鎖的線程才能更新表結(jié)構(gòu),其它線程不能修改表結(jié)構(gòu)也不能執(zhí)行相應(yīng)的增刪改查。

2. MDL 鎖演示

接下來松哥通過一個簡單的例子,來和大家演示 MDL 鎖。

首先我們開啟一個會話,開啟一個事務(wù),執(zhí)行一個更新 SQL:

大家注意,由于事務(wù)沒有提交,所以現(xiàn)在這個更新 SQL 還持有一個 MDL 讀鎖。

接下來我們開啟一個新的會話,執(zhí)行一個 alter 語句:

大家看到,在新的會話中執(zhí)行 alter,就會卡住??ㄗ〉脑蛟谟?DDL 操作需要獲取 MDL 寫鎖,而在 MDL 中,讀讀共享,讀寫互斥,寫寫互斥。

所以現(xiàn)在獲取 MDL 寫鎖就會被卡住,進(jìn)而導(dǎo)致 alter 語句被阻塞,除非前面的 update 事務(wù)提交了,釋放了 MDL 讀鎖,那么 alter 語句就可以順利拿到寫鎖,進(jìn)而完成表的更新。

這就是 MDL 鎖,不需要我們手動添加手動釋放,系統(tǒng)會自動添加自動釋放。

3. Online DDL

MySQL5.6 開始引入了 Online DDL,很多小伙伴可能對 Online DDL 有一些了解但是不夠全面,松哥這里也和大家說一下,加深大家對 MDL 的理解。

Online DDL 從名字上就可以看出來是可以在線執(zhí)行 DDL,不和其他操作沖突,具體執(zhí)行流程如下:

  • DDL 操作需要首先獲取 MDL 寫鎖。
  • 接下來將 MDL 寫鎖降級成 MDL 讀鎖。
  • 做真正的 DDL 操作,這一步也是最耗時的,由于此時我們持有的是 MDL 讀鎖,因此并不會阻塞其他的增刪改查操作。
  • 做完 DDL 操作之后,接下來將 MDL 讀鎖升級成 MDL 寫鎖。
  • 釋放 MDL 鎖。

看了上面的分析大家就明白了,Online DDL 并不是讓你隨時隨地可以更新表結(jié)構(gòu),也還是有限制的,只有在第三步那里可以繼續(xù)執(zhí)行增刪改查,當(dāng)然即使在第三步,更新表結(jié)構(gòu)也是不允許的。在我們第二小節(jié)的案例中,第一步獲取 MDL 寫鎖就被卡住了。

4. 一個隱藏的問題

和 MDL 鎖相關(guān)的還有一個隱藏問題,如果不了解這個知識點(diǎn),將來可能也會犯一些錯誤。

有小伙伴看了松哥上面的例子,可能會自己做下面這個實(shí)驗(yàn):

首先在一個會話中開啟事務(wù),然后執(zhí)行 alter,如下:

注意這個事務(wù)沒有提交。

接下來執(zhí)行開啟另外一個會話,執(zhí)行一條更新 SQL:

發(fā)現(xiàn)更新 SQL 竟然成功執(zhí)行了,沒有發(fā)生阻塞!!!這是怎么回事呢?

這里其實(shí)就涉及到 MySQL 事務(wù)的隱式提交:所有的 DDL 語句都會導(dǎo)致事務(wù)隱式提交,換句話說,當(dāng)你在執(zhí)行 DDL 語句前,事務(wù)就已經(jīng)提交了。

這就意味著帶有 DDL 語句的事務(wù)將來沒有辦法 rollback。

假設(shè)一個有一個 SQL 事務(wù),類似下面這樣:

  1. begin
  2. A-SQL 
  3. alter 
  4. B-SQL 

對于上面這個 SQL 而言,執(zhí)行 alter 的時候,就會提交 A-SQL 所在的事務(wù),執(zhí)行 B-SQL 時,已經(jīng)不在事務(wù)里邊了。

這就要求我們在設(shè)計(jì) DML 數(shù)據(jù)操作的事務(wù)時,盡量不要在 DML 中包含 DDL 語句。

好啦,和小伙伴們隨便聊一聊 MDL 鎖的問題,感興趣的小伙伴可以自己動手嘗試下哦。

參考資料:

 

http://dev.mysql.com/doc/refman/5.7/en/cannot-roll-back.html

 

責(zé)任編輯:武曉燕 來源: 江南一點(diǎn)雨
相關(guān)推薦

2021-01-26 05:37:08

分庫分表內(nèi)存

2021-10-27 20:54:24

分庫分表高并發(fā)

2019-09-09 08:28:48

互聯(lián)網(wǎng)數(shù)據(jù)磁盤

2011-08-15 10:10:47

編程

2014-08-28 11:12:14

谷歌

2015-08-06 10:14:15

造輪子facebook

2022-08-15 08:27:02

基站網(wǎng)絡(luò)

2013-03-12 14:30:09

Ubuntu操作系統(tǒng)

2010-12-27 16:02:50

管理軟件云計(jì)算

2017-09-08 08:35:16

Android代碼API設(shè)計(jì)

2024-10-17 16:41:57

KafkaZooKeeper

2014-08-25 10:00:18

開源

2015-05-12 11:04:42

Java EE學(xué)習(xí)Java EE

2019-03-19 08:59:13

物聯(lián)網(wǎng)IOT技術(shù)

2019-11-27 10:25:15

SaaS云端IT架構(gòu)

2021-02-11 13:30:56

Nodejs源碼c++

2017-04-05 16:40:45

2019-01-14 07:28:56

大數(shù)據(jù)云計(jì)算互聯(lián)網(wǎng)

2019-09-30 07:50:51

ITOps云端ITOM

2018-05-23 00:20:29

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號