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

你真的了解MySQL中的鎖嗎

數(shù)據(jù)庫(kù) MySQL
鎖是并發(fā)訪問(wèn)同一個(gè)共享資源時(shí)的同步機(jī)制,Synchronized、ReentrantLock和ReentrantReadWriteLock都用過(guò)的吧,都是一樣的道理.

[[436834]]

大家在學(xué)習(xí)mysql的時(shí)候,估計(jì)也聽(tīng)說(shuō)過(guò)數(shù)據(jù)庫(kù)中的鎖

鎖,大家應(yīng)該是很熟悉的了吧,就是多個(gè)線程同時(shí)對(duì)共享資源的訪問(wèn)的競(jìng)爭(zhēng)

那么大家對(duì)于mysql中的鎖又有多少了解呢

先說(shuō)一下mysql中的幾種語(yǔ)言,SQL語(yǔ)言共分為四大類(lèi)

數(shù)據(jù)查詢(xún)語(yǔ)言DQL,數(shù)據(jù)操縱語(yǔ)言DML,數(shù)據(jù)定義語(yǔ)言DDL,數(shù)據(jù)控制語(yǔ)言DCL。

1. 數(shù)據(jù)查詢(xún)語(yǔ)言DQL:數(shù)據(jù)查詢(xún)語(yǔ)言DQL基本結(jié)構(gòu)是由SELECT子句,F(xiàn)ROM子句,WHERE

2 .數(shù)據(jù)操縱語(yǔ)言DML:數(shù)據(jù)操縱語(yǔ)言DML主要有三種形式,插入,更新,刪除。

3. 數(shù)據(jù)定義語(yǔ)言DDL:數(shù)據(jù)定義語(yǔ)言DDL用來(lái)創(chuàng)建數(shù)據(jù)庫(kù)中的各種對(duì)象如:表 視圖 索引 同義詞 簇。DDL操作是隱性提交的,不能rollback

4. 數(shù)據(jù)控制語(yǔ)言DCL:數(shù)據(jù)控制語(yǔ)言DCL用來(lái)授予或回收訪問(wèn)數(shù)據(jù)庫(kù)的某種特權(quán),并控制數(shù)據(jù)庫(kù)操縱事務(wù)發(fā)生的時(shí)間及效果,對(duì)數(shù)據(jù)庫(kù)實(shí)行監(jiān)視等。

鎖是并發(fā)訪問(wèn)同一個(gè)共享資源時(shí)的同步機(jī)制,Synchronized、ReentrantLock和ReentrantReadWriteLock都用過(guò)的吧,都是一樣的道理

MySQL的鎖是在服務(wù)器層或者存儲(chǔ)引擎層實(shí)現(xiàn)的,保證數(shù)據(jù)訪問(wèn)的一致性和有序性

  • 按模式分類(lèi)為:樂(lè)觀鎖與悲觀鎖。
  • 按粒度分可以分為全局鎖、表級(jí)鎖、頁(yè)級(jí)鎖、行級(jí)鎖。
  • 按屬性可以分為:共享鎖、排它鎖。
  • 按狀態(tài)分為:意向共享鎖、意向排它鎖。
  • 按算法分為:間隙鎖、臨鍵鎖、記錄鎖。

樂(lè)觀鎖

一種思想,樂(lè)觀鎖建設(shè)數(shù)據(jù)一般情況下不會(huì)產(chǎn)生沖突,在數(shù)據(jù)的操作過(guò)程中不會(huì)對(duì)數(shù)據(jù)做任何鎖定,只有當(dāng)數(shù)據(jù)進(jìn)行提交跟新的時(shí)候,才會(huì)正式對(duì)數(shù)據(jù)的沖突與否進(jìn)行檢測(cè)

如果發(fā)生沖突了,則返回錯(cuò)誤,調(diào)用者決定如何操作,是回滾還是重試

比較適用于讀多寫(xiě)少的情況,如果寫(xiě)場(chǎng)景比較多,寫(xiě)沖突的可能性比較高,可能需要不斷重試,這樣會(huì)大大降低系統(tǒng)性能

這種可以通過(guò)增加一個(gè)數(shù)據(jù)版本字段Version來(lái)實(shí)現(xiàn),讀取數(shù)據(jù)的時(shí)候把這個(gè)字段一起讀出來(lái),數(shù)據(jù)每更新一次,對(duì)Version字段加一,當(dāng)我們提交更新數(shù)據(jù)的時(shí)候,判斷數(shù)據(jù)庫(kù)表中的對(duì)應(yīng)記錄的版本信息和第一次取出來(lái)的Version是否一致,一致則可以更新,不一致則過(guò)期

悲觀鎖

這個(gè)也是一種思想,悲觀的看法,認(rèn)為每次去取數(shù)據(jù)的時(shí)候都會(huì)有別人去修改,所以在整個(gè)數(shù)據(jù)處理過(guò)程中,數(shù)據(jù)處于鎖定狀態(tài)

適用于并發(fā)量不大,寫(xiě)入操作比較頻繁,數(shù)據(jù)一致性比較高的場(chǎng)景,MySQL中,共享鎖和排他鎖都是屬于悲觀鎖的不同實(shí)現(xiàn)

全局鎖

對(duì)整個(gè)數(shù)據(jù)庫(kù)實(shí)例進(jìn)行加鎖,一般用于全庫(kù)的邏輯備份

MySQL 提供了一個(gè)加全局讀鎖的方法,命令是Flush tables with read lock (FTWRL)。使用這個(gè)命令之后,整個(gè)庫(kù)處于只讀狀態(tài),其它線程的更新語(yǔ)句都會(huì)被阻塞

主庫(kù)備份,需要考慮影響業(yè)務(wù)系統(tǒng),從庫(kù)備份,在備份期間不能執(zhí)行主庫(kù)同步過(guò)來(lái)的binlog,主從同步會(huì)有延遲

解決辦法,mysqldump使用參數(shù)--single-transaction,啟動(dòng)一個(gè)事務(wù),確保拿到一致性視圖。而由于MVCC的支持,這個(gè)過(guò)程中數(shù)據(jù)是可以正常更新的。

表級(jí)鎖

對(duì)操作的數(shù)據(jù)表加鎖,MyISAM和InnoDB引擎都支持表級(jí)鎖定,這里分為兩種,一種是表鎖,一種是元數(shù)據(jù)鎖,即meat data lock,MDL鎖

  1. lock tables 表名 read #該表可以讀,不能ddl 和 dml 中增刪改,只能讀取表數(shù)據(jù) 
  2. lock tables 表名 write # 既不能讀,也不能寫(xiě) 

表鎖的語(yǔ)法是 lock tables … read/write。與 FTWRL 類(lèi)似,可以用 unlock tables 主動(dòng)釋放鎖,也可以在客戶(hù)端斷開(kāi)的時(shí)候自動(dòng)釋放。需要注意,lock tables 語(yǔ)法除了會(huì)限制別的線程的讀寫(xiě)外,也限定了本線程接下來(lái)的操作對(duì)象。

MDL鎖

防止DDL和DML并發(fā)的沖突,你想啊,一個(gè)查詢(xún)正在遍歷表中數(shù)據(jù),而執(zhí)行期間另一個(gè)線程對(duì)這個(gè)表結(jié)構(gòu)進(jìn)行了變更,刪除了一列,查詢(xún)線程拿到的結(jié)果跟表結(jié)構(gòu)對(duì)不上,就亂套了

MDL鎖不是顯示的,MDL鎖是在5.5版本引入的

對(duì)一個(gè)表做增刪改查操作的時(shí)候,加MDL讀鎖,讀鎖之間不沖突,所以多個(gè)線程可以同時(shí)對(duì)一個(gè)表進(jìn)行增刪改查

當(dāng)要對(duì)表結(jié)構(gòu)變更操作的時(shí)候,加MDL寫(xiě)鎖,讀鎖和寫(xiě)鎖、寫(xiě)鎖和寫(xiě)鎖都是沖突的,用來(lái)保證變更結(jié)構(gòu)操作的安全性

兩個(gè)線程同時(shí)對(duì)一個(gè)表中加字段,其中一個(gè)要等另一個(gè)執(zhí)行完才可以開(kāi)始。一個(gè)線程A先在查詢(xún)數(shù)據(jù),另一個(gè)線程B想要加一列數(shù)據(jù),需要等A線程執(zhí)行完才可以執(zhí)行線程B,就解決了上面的問(wèn)題

MDL鎖是系統(tǒng)默認(rèn)加的,我們理解了上面的機(jī)制之后,一定要注意MDL寫(xiě)鎖之后的讀鎖和寫(xiě)鎖都會(huì)阻塞,所以在給一些表加字段的時(shí)候一定要注意,盡量避開(kāi)業(yè)務(wù)系統(tǒng)比較繁忙的時(shí)候

即使小表,操作不慎,如果一個(gè)表的查詢(xún)語(yǔ)句頻繁,而且客戶(hù)端有重試機(jī)制,也就是超時(shí)之后還會(huì)再起一個(gè)新session,庫(kù)的線程很容易就慢了,這時(shí)系統(tǒng)就崩了

千萬(wàn)不要在長(zhǎng)事務(wù)中對(duì)表結(jié)構(gòu)進(jìn)行修改,事務(wù)不提交會(huì)一直占用MDL寫(xiě)鎖,那后面的語(yǔ)句就需要一直等待

頁(yè)級(jí)鎖

頁(yè)級(jí)鎖是 MySQL 中鎖定粒度介于行級(jí)鎖和表級(jí)鎖中間的一種鎖。表級(jí)鎖速度快,但沖突多,行級(jí)沖突少,但速度慢。因此,采取了折衷的頁(yè)級(jí)鎖,一次鎖定相鄰的一組記錄。BDB 引擎支持頁(yè)級(jí)鎖。

行級(jí)鎖

MySQL中只有InnoDB支持行級(jí)鎖,行級(jí)鎖分為共享鎖和排他鎖。

行級(jí)鎖是粒度最低的鎖,鎖沖突概率最低。但加鎖慢、開(kāi)銷(xiāo)大,容易發(fā)生死鎖現(xiàn)象。

行鎖并不是直接鎖記錄,而是鎖索引

索引分為主鍵索引和非主鍵索引,一條sql語(yǔ)句操作了主鍵索引,MySQL就會(huì)鎖定這條主鍵索引;如果一條語(yǔ)句操作了非主鍵索引,MySQL會(huì)先鎖定該非主鍵索引,再鎖定相關(guān)的主鍵索引

共享鎖

共享鎖,也就是我們常說(shuō)的讀鎖,一個(gè)事務(wù)對(duì)數(shù)據(jù)加上讀鎖之后,其它事務(wù)只能對(duì)該數(shù)據(jù)加讀鎖,不能做任何修改,不能加寫(xiě)鎖

這樣可以更好的支持并發(fā)中的讀取數(shù)據(jù),讀取數(shù)據(jù)的時(shí)候,不允許其他事物對(duì)當(dāng)前數(shù)據(jù)進(jìn)行修改操作,從而避免不可重復(fù)讀的問(wèn)題的出現(xiàn)

  1. select … lock in share mode 

排它鎖

排它鎖,也就是寫(xiě)鎖,當(dāng)對(duì)數(shù)據(jù)加上寫(xiě)鎖之后,其它事務(wù)不能對(duì)該數(shù)據(jù)讀寫(xiě),這個(gè)時(shí)候讀鎖和寫(xiě)鎖都不可以加了,也就是全部阻塞了

寫(xiě)鎖就是為了解決在數(shù)據(jù)修改的時(shí)候,不允許其它事務(wù)對(duì)當(dāng)前數(shù)據(jù)進(jìn)行修改和讀取操作,從而可以避免臟讀問(wèn)題的產(chǎn)生

共享鎖可以避免不可重復(fù)讀的問(wèn)題,排它鎖可以避免臟讀問(wèn)題的產(chǎn)生

意向共享鎖和意向排它鎖

意向鎖的出現(xiàn)就是為了協(xié)調(diào)表鎖和行鎖,支持多粒度的并存

事務(wù)A有行鎖的時(shí)候,MySQL會(huì)自動(dòng)給該表加上意向鎖,事務(wù)B如果想申請(qǐng)整個(gè)表的寫(xiě)鎖,就不用遍歷去每一行判斷是否存在行鎖,只需要判斷是否存在意向鎖,即可決定是否可以加表的寫(xiě)鎖

意向鎖的互斥性

當(dāng)然,表格中的共享鎖和排他鎖都是表鎖,即表鎖和意向鎖的關(guān)系

意向鎖是不會(huì)和行級(jí)的共享排他鎖互斥的

給大家再解釋一下,就是有行級(jí)共享鎖,那就加上意向共享鎖,當(dāng)需要加表級(jí)的共享鎖的時(shí)候,兼容,即行讀表讀共存;相反,表級(jí)的排他鎖加不上,也就是行讀表寫(xiě)不共存

相應(yīng)的行級(jí)的排他鎖,也就是寫(xiě)鎖加上之后,表級(jí)的讀鎖和寫(xiě)鎖都是不能加上的了,也就是行寫(xiě)表既不可讀也不可寫(xiě)

總結(jié)

  • 行讀表讀共存
  • 行讀表寫(xiě)不共存
  • 行寫(xiě)既不可讀也不可寫(xiě)

記錄鎖

記錄鎖是封鎖記錄,記錄鎖也叫行鎖

間隙鎖

間隙鎖基于非唯一索引,它鎖定一段范圍內(nèi)的索引記錄。使用間隙鎖鎖住的是一個(gè)區(qū)間,而不僅僅是這個(gè)區(qū)間中的每一條數(shù)據(jù)

臨鍵鎖

臨鍵鎖,是記錄鎖與間隙鎖的組合,它的封鎖范圍,既包含索引記錄,又包含索引區(qū)間,是一個(gè)左開(kāi)右閉區(qū)間。臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read)。如果把事務(wù)的隔離級(jí)別降級(jí)為RC,臨鍵鎖則也會(huì)失效。

每個(gè)數(shù)據(jù)行上的非唯一索引列上都會(huì)存在一把臨鍵鎖,當(dāng)某個(gè)事務(wù)持有該數(shù)據(jù)行的臨鍵鎖時(shí),會(huì)鎖住一段左開(kāi)右閉區(qū)間的數(shù)據(jù)。

需要強(qiáng)調(diào)的一點(diǎn)是,InnoDB 中行級(jí)鎖是基于索引實(shí)現(xiàn)的,臨鍵鎖只與非唯一索引列有關(guān),在唯一索引列(包括主鍵列)上不存在臨鍵鎖。

 

責(zé)任編輯:姜華 來(lái)源: Java賊船
相關(guān)推薦

2024-01-29 10:09:59

數(shù)據(jù)庫(kù)INT(3)INT(11)

2022-07-26 00:00:22

HTAP系統(tǒng)數(shù)據(jù)庫(kù)

2014-04-17 16:42:03

DevOps

2025-01-03 08:09:15

2018-12-21 11:24:55

Java時(shí)間處理編程語(yǔ)言

2021-01-15 07:44:21

SQL注入攻擊黑客

2021-11-09 09:48:13

Logging python模塊

2019-09-16 08:40:42

2014-11-28 10:31:07

Hybrid APP

2020-02-27 10:49:26

HTTPS網(wǎng)絡(luò)協(xié)議TCP

2023-03-16 10:49:55

2023-11-01 13:48:00

反射java

2018-01-06 10:38:51

Ping抓包 ICMP協(xié)議

2017-10-18 22:01:12

2023-10-24 08:53:24

FutureTas并發(fā)編程

2012-05-31 09:56:54

云安全

2015-07-31 10:35:18

實(shí)時(shí)計(jì)算

2022-12-12 08:46:11

2019-11-06 09:52:01

JavaScript單線程非阻塞

2022-03-14 07:53:27

ELTETL大數(shù)據(jù)
點(diǎn)贊
收藏

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