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

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

mysql元數(shù)據(jù)鎖怎么用 mysql元數(shù)據(jù)表

mysql中的鎖都有哪些

MySQL 中有哪些鎖?

創(chuàng)新互聯(lián)網(wǎng)站建設(shè)由有經(jīng)驗(yàn)的網(wǎng)站設(shè)計(jì)師、開發(fā)人員和項(xiàng)目經(jīng)理組成的專業(yè)建站團(tuán)隊(duì),負(fù)責(zé)網(wǎng)站視覺設(shè)計(jì)、用戶體驗(yàn)優(yōu)化、交互設(shè)計(jì)和前端開發(fā)等方面的工作,以確保網(wǎng)站外觀精美、做網(wǎng)站、網(wǎng)站建設(shè)易于使用并且具有良好的響應(yīng)性。

數(shù)據(jù)庫中鎖的設(shè)計(jì)初衷處理并發(fā)問題,作為多用戶共享資源,當(dāng)出現(xiàn)并發(fā)訪問的時(shí)候,數(shù)據(jù)庫需要合理控制資源訪問規(guī)則。鎖就是實(shí)現(xiàn)這些訪問規(guī)則中的重要數(shù)據(jù)。

鎖的分類

根據(jù)加鎖范圍,MySQL 里面的鎖可以分成 全局鎖 、 表級(jí)鎖 、 行鎖 三類。

全局鎖

全局鎖,就是對(duì)整個(gè)數(shù)據(jù)庫實(shí)例加鎖,MySQL 提供了一個(gè)加全局讀鎖的方法,命令是:

Flush tables with read lock (FTWRL)

當(dāng)需要整個(gè)庫只讀狀態(tài)的時(shí)候,可以使用這個(gè)命令,之后其他線程的:數(shù)據(jù)更新語句(增刪改),數(shù)據(jù)定義語句(建表,修改表結(jié)構(gòu))和更新事務(wù)的提交語句將會(huì)被阻塞。

全局鎖的使用場(chǎng)景

全局鎖的定型使用場(chǎng)景,做 全庫邏輯備份 。也就是把整個(gè)庫每個(gè)表都 Select 出來,然后存成文本。

如何整個(gè)庫都只讀,會(huì)有什么問題? 如果你在主庫上備份,那么在備份期間都不能執(zhí)行更想,業(yè)務(wù)就基本上停擺。 如果在從庫上備份,那么備份期間從庫不能執(zhí)行主庫同步過來的 binlog ,會(huì)導(dǎo)致從延遲。 既然要全庫只讀, 為什么不使用set global readonly=true的方式呢?

readonly 方式也可以讓全庫進(jìn)入只讀狀態(tài),但我還是會(huì)建議你用FTWRL方式, 主要有兩個(gè)原因:

一是, 在有些系統(tǒng)中, readonly的值會(huì)被用來做其他邏輯,比如用來判斷一個(gè)庫是主庫還是備庫。因此,修改global變量的方式影響面更大, 我不建議你使用。 二是, 在異常處理機(jī)制上有差異。如果執(zhí)行FTWRL命令之后由于客戶端發(fā)生異常斷開, 那么MySQL會(huì)自動(dòng)釋放這個(gè)全局鎖, 整個(gè)庫回到可以正常更新的狀態(tài)。而將整個(gè)庫設(shè)置為readonly之后, 如果客戶端發(fā)生異常, 則數(shù)據(jù)庫就會(huì)一直保持readonly狀態(tài), 這樣會(huì)導(dǎo)致整個(gè)庫長(zhǎng)時(shí)間處于不可寫狀態(tài), 風(fēng)險(xiǎn)較高 表級(jí)別鎖

MySQL 里面表級(jí)別的鎖有兩種:一種是表鎖,一種是元數(shù)據(jù)鎖(meta data lok, MDL)。表鎖的語法是 :

lock tables ... read/write

與 FTWRL 類似,可以使用 unlock tables 主動(dòng)釋放鎖,也可以在客戶端斷開的時(shí)候自動(dòng)釋放。需要注意的是,lock tables語法除了會(huì)限制別的線程的讀寫外,也限定了本線程接下來的操作對(duì)象。

MDL 表級(jí)鎖

MDL 不需要顯示使用,在訪問一個(gè)表的時(shí)候自動(dòng)加上, MDL 保證讀寫的正確性,也就是說在查詢數(shù)據(jù)時(shí),不允許有其他線程對(duì)這個(gè)表結(jié)構(gòu)做變更。

什么操作會(huì)加 MDL 鎖?

在MySQL 5.5版本中引入了MDL, 當(dāng)對(duì)一個(gè)表做增刪改查操作的時(shí)候,加 MDL讀鎖 ;當(dāng)要對(duì)表做結(jié)構(gòu)變更操作的時(shí)候,加 MDL寫鎖 。

讀鎖之間不互斥,因此可以有多個(gè)線程同時(shí)對(duì)一張表增刪改查。 讀寫之間、寫鎖之間是互斥的,用來保證變更表結(jié)構(gòu)操作的安全性,如果有兩個(gè)線程要同時(shí)給一個(gè)表加字段,其中一個(gè)要等另外一個(gè)執(zhí)行完才能執(zhí)行。 更改表結(jié)構(gòu)要注意哪些?

給一個(gè)表加字段, 或者修改字段, 或者加索引, 需要掃描全表的數(shù)據(jù)。在對(duì)大表操作的時(shí)候, 你肯定會(huì)特別小心, 以免對(duì)線上服務(wù)造成影響。而實(shí)際上, 即使是小表, 操作不慎也會(huì)出問題,導(dǎo)致整個(gè)庫的線程爆滿。

舉個(gè)例子

我們來看一下下面的操作序列, 假設(shè)表t是一個(gè)小表。

image

session A先啟動(dòng), 這時(shí)候會(huì)對(duì)表t加一個(gè) MDL讀鎖 。由于session B需要的也是 MDL讀鎖 , 因此可以正常執(zhí)行。 session C會(huì)被blocked, 是因?yàn)閟ession A的MDL讀鎖還沒有釋放, 而session C需要MDL寫鎖, 因此只能被阻塞,讀寫鎖互斥。 如果只有session C自己被阻塞還沒什么關(guān)系, 但是之后所有要在表t上新申請(qǐng)MDL讀鎖的請(qǐng)求也會(huì)被session C阻塞。前面我們說了,所有對(duì)表的增刪改查操作都需要先申請(qǐng)MDL讀鎖, 就都被鎖住, 等于這個(gè)表現(xiàn)在完全不可讀寫了。

如果某個(gè)表上的查詢語句頻繁, 而且客戶端有重試機(jī)制,也就是說超時(shí)后會(huì)再起一個(gè)新session 再請(qǐng)求的話, 這個(gè) 庫的線程很快就會(huì)爆滿 。事務(wù)中的MDL鎖, 在語句執(zhí)行開始時(shí)申請(qǐng), 但是語句結(jié)束后并不會(huì)馬上釋放, 而會(huì)等到整個(gè)事務(wù)提交后再釋放。

怎么解決這個(gè) 更改表結(jié)構(gòu)問題

比較理想的機(jī)制是, 在alter table語句里面設(shè)定等待時(shí)間, 如果在這個(gè)指定的等待時(shí)間里面能夠拿到MDL寫鎖最好, 拿不到也不要阻塞后面的業(yè)務(wù)語句, 先放棄。

ALTER TABLE tbl_name NOWAIT add column ... ALTER TABLE tbl_name WAIT N add column ...

MySQL數(shù)據(jù)庫表被鎖、解鎖,刪除事務(wù)

在程序員的職業(yè)生涯中,總會(huì)遇到數(shù)據(jù)庫表被鎖的情況,前些天就又撞見一次。由于業(yè)務(wù)突發(fā)需求,各個(gè)部門都在批量操作、導(dǎo)出數(shù)據(jù),而數(shù)據(jù)庫又未做讀寫分離,結(jié)果就是:數(shù)據(jù)庫的某張表被鎖了!

用戶反饋系統(tǒng)部分功能無法使用,緊急排查,定位是數(shù)據(jù)庫表被鎖,然后進(jìn)行緊急處理。這篇文章給大家講講遇到類似緊急狀況的排查及解決過程,建議點(diǎn)贊收藏,以備不時(shí)之需。

用戶反饋某功能頁面報(bào)502錯(cuò)誤,于是第一時(shí)間看服務(wù)是否正常,數(shù)據(jù)庫是否正常。在控制臺(tái)看到數(shù)據(jù)庫CPU飆升,堆積大量未提交事務(wù),部分事務(wù)已經(jīng)阻塞了很長(zhǎng)時(shí)間,基本定位是數(shù)據(jù)庫層出現(xiàn)問題了。

查看阻塞事務(wù)列表,發(fā)現(xiàn)其中有鎖表現(xiàn)象,本想利用控制臺(tái)直接結(jié)束掉阻塞的事務(wù),但控制臺(tái)賬號(hào)權(quán)限有限,于是通過客戶端登錄對(duì)應(yīng)賬號(hào)將鎖表事務(wù)kill掉,才避免了情況惡化。

下面就聊聊,如果當(dāng)突然面對(duì)類似的情況,我們?cè)撊绾尉o急響應(yīng)?

想象一個(gè)場(chǎng)景,當(dāng)然也是軟件工程師職業(yè)生涯中會(huì)遇到的一種場(chǎng)景:原本運(yùn)行正常的程序,某一天突然數(shù)據(jù)庫的表被鎖了,業(yè)務(wù)無法正常運(yùn)轉(zhuǎn),那么我們?cè)撊绾慰焖俣ㄎ皇悄膫€(gè)事務(wù)鎖了表,如何結(jié)束對(duì)應(yīng)的事物?

首先最簡(jiǎn)單粗暴的方式就是:重啟MySQL。對(duì)的,網(wǎng)管解決問題的神器——“重啟”。至于后果如何,你能不能跑了,要你自己三思而后行了!

重啟是可以解決表被鎖的問題的,但針對(duì)線上業(yè)務(wù)很顯然不太具有可行性。

下面來看看不用跑路的解決方案:

遇到數(shù)據(jù)庫阻塞問題,首先要查詢一下表是否在使用。

如果查詢結(jié)果為空,那么說明表沒在使用,說明不是鎖表的問題。

如果查詢結(jié)果不為空,比如出現(xiàn)如下結(jié)果:

則說明表(test)正在被使用,此時(shí)需要進(jìn)一步排查。

查看數(shù)據(jù)庫當(dāng)前的進(jìn)程,看看是否有慢SQL或被阻塞的線程。

執(zhí)行命令:

該命令只顯示當(dāng)前用戶正在運(yùn)行的線程,當(dāng)然,如果是root用戶是能看到所有的。

在上述實(shí)踐中,阿里云控制臺(tái)之所以能夠查看到所有的線程,猜測(cè)應(yīng)該使用的就是root用戶,而筆者去kill的時(shí)候,無法kill掉,是因?yàn)榈卿浀挠脩舴莚oot的數(shù)據(jù)庫賬號(hào),無法操作另外一個(gè)用戶的線程。

如果情況緊急,此步驟可以跳過,主要用來查看核對(duì):

如果情況緊急,此步驟可以跳過,主要用來查看核對(duì):

看事務(wù)表INNODB_TRX中是否有正在鎖定的事務(wù)線程,看看ID是否在show processlist的sleep線程中。如果在,說明這個(gè)sleep的線程事務(wù)一直沒有commit或者rollback,而是卡住了,需要手動(dòng)kill掉。

搜索的結(jié)果中,如果在事務(wù)表發(fā)現(xiàn)了很多任務(wù),最好都kill掉。

執(zhí)行kill命令:

對(duì)應(yīng)的線程都執(zhí)行完kill命令之后,后續(xù)事務(wù)便可正常處理。

針對(duì)緊急情況,通常也會(huì)直接操作第一、第二、第六步。

這里再補(bǔ)充一些MySQL鎖相關(guān)的知識(shí)點(diǎn):數(shù)據(jù)庫鎖設(shè)計(jì)的初衷是處理并發(fā)問題,作為多用戶共享的資源,當(dāng)出現(xiàn)并發(fā)訪問的時(shí)候,數(shù)據(jù)庫需要合理地控制資源的訪問規(guī)則,而鎖就是用來實(shí)現(xiàn)這些訪問規(guī)則的重要數(shù)據(jù)結(jié)構(gòu)。

根據(jù)加鎖的范圍,MySQL里面的鎖大致可以分成全局鎖、表級(jí)鎖和行鎖三類。MySQL中表級(jí)別的鎖有兩種:一種是表鎖,一種是元數(shù)據(jù)鎖(metadata lock,MDL)。

表鎖是在Server層實(shí)現(xiàn)的,ALTER TABLE之類的語句會(huì)使用表鎖,忽略存儲(chǔ)引擎的鎖機(jī)制。表鎖通過lock tables… read/write來實(shí)現(xiàn),而對(duì)于InnoDB來說,一般會(huì)采用行級(jí)鎖。畢竟鎖住整張表影響范圍太大了。

另外一個(gè)表級(jí)鎖是MDL(metadata lock),用于并發(fā)情況下維護(hù)數(shù)據(jù)的一致性,保證讀寫的正確性,不需要顯式的使用,在訪問一張表時(shí)會(huì)被自動(dòng)加上。

常見的一種鎖表場(chǎng)景就是有事務(wù)操作處于:Waiting for table metadata lock狀態(tài)。

MySQL在進(jìn)行alter table等DDL操作時(shí),有時(shí)會(huì)出現(xiàn)Waiting for table metadata lock的等待場(chǎng)景。

一旦alter table TableA的操作停滯在Waiting for table metadata lock狀態(tài),后續(xù)對(duì)該表的任何操作(包括讀)都無法進(jìn)行,因?yàn)樗鼈円矔?huì)在Opening tables的階段進(jìn)入到Waiting for table metadata lock的鎖等待隊(duì)列。如果核心表出現(xiàn)了鎖等待隊(duì)列,就會(huì)造成災(zāi)難性的后果。

通過show processlist可以看到表上有正在進(jìn)行的操作(包括讀),此時(shí)alter table語句無法獲取到metadata 獨(dú)占鎖,會(huì)進(jìn)行等待。

通過show processlist看不到表上有任何操作,但實(shí)際上存在有未提交的事務(wù),可以在information_schema.innodb_trx中查看到。在事務(wù)沒有完成之前,表上的鎖不會(huì)釋放,alter table同樣獲取不到metadata的獨(dú)占鎖。

處理方法:通過 select * from information_schema.innodb_trxG, 找到未提交事物的sid,然后kill掉,讓其回滾。

通過show processlist看不到表上有任何操作,在information_schema.innodb_trx中也沒有任何進(jìn)行中的事務(wù)。很可能是因?yàn)樵谝粋€(gè)顯式的事務(wù)中,對(duì)表進(jìn)行了一個(gè)失敗的操作(比如查詢了一個(gè)不存在的字段),這時(shí)事務(wù)沒有開始,但是失敗語句獲取到的鎖依然有效,沒有釋放。從performance_schema.events_statements_current表中可以查到失敗的語句。

處理方法:通過performance_schema.events_statements_current找到其sid,kill 掉該session,也可以kill掉DDL所在的session。

總之,alter table的語句是很危險(xiǎn)的(核心是未提交事務(wù)或者長(zhǎng)事務(wù)導(dǎo)致的),在操作之前要確認(rèn)對(duì)要操作的表沒有任何進(jìn)行中的操作、沒有未提交事務(wù)、也沒有顯式事務(wù)中的報(bào)錯(cuò)語句。

如果有alter table的維護(hù)任務(wù),在無人監(jiān)管的時(shí)候運(yùn)行,最好通過lock_wait_timeout設(shè)置好超時(shí)時(shí)間,避免長(zhǎng)時(shí)間的metedata鎖等待。

關(guān)于MySQL的鎖表其實(shí)還有很多其他場(chǎng)景,我們?cè)趯?shí)踐的過程中盡量避免鎖表情況的發(fā)生,當(dāng)然這需要一定經(jīng)驗(yàn)的支撐。但更重要的是,如果發(fā)現(xiàn)鎖表我們要能夠快速的響應(yīng),快速的解決問題,避免影響正常業(yè)務(wù),避免情況進(jìn)一步惡化。所以,本文中的解決思路大家一定要收藏或記憶一下,做到有備無患,避免突然狀況下抓瞎。

MySQL從入門到精通(九) MySQL鎖,各種鎖

鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問某一資源的機(jī)制,在數(shù)據(jù)庫中,除傳統(tǒng)的計(jì)算資源(CPU、RAM、I/O)爭(zhēng)用外,數(shù)據(jù)也是一種供許多用戶共享的資源,如何保證數(shù)據(jù)并發(fā)訪問的一致性,有效性是所有數(shù)據(jù)庫必須解決的一個(gè)問題,鎖沖突也是影響數(shù)據(jù)庫并發(fā)訪問性能的一個(gè)重要因素,從這個(gè)角度來說,鎖對(duì)數(shù)據(jù)庫而言是尤其重要,也更加復(fù)雜。MySQL中的鎖,按照鎖的粒度分為:1、全局鎖,就鎖定數(shù)據(jù)庫中的所有表。2、表級(jí)鎖,每次操作鎖住整張表。3、行級(jí)鎖,每次操作鎖住對(duì)應(yīng)的行數(shù)據(jù)。

全局鎖就是對(duì)整個(gè)數(shù)據(jù)庫實(shí)例加鎖,加鎖后整個(gè)實(shí)例就處于只讀狀態(tài),后續(xù)的DML的寫語句,DDL語句,已經(jīng)更新操作的事務(wù)提交語句都將阻塞。其典型的使用場(chǎng)景就是做全庫的邏輯備份,對(duì)所有的表進(jìn)行鎖定,從而獲取一致性視圖,保證數(shù)據(jù)的完整性。但是對(duì)數(shù)據(jù)庫加全局鎖是有弊端的,如在主庫上備份,那么在備份期間都不能執(zhí)行更新,業(yè)務(wù)會(huì)受影響,第二如果是在從庫上備份,那么在備份期間從庫不能執(zhí)行主庫同步過來的二進(jìn)制日志,會(huì)導(dǎo)致主從延遲。

解決辦法是在innodb引擎中,備份時(shí)加上--single-transaction參數(shù)來完成不加鎖的一致性數(shù)據(jù)備份。

添加全局鎖: flush tables with read lock; 解鎖 unlock tables。

表級(jí)鎖,每次操作會(huì)鎖住整張表.鎖定粒度大,發(fā)送鎖沖突的概率最高,并發(fā)讀最低,應(yīng)用在myisam、innodb、BOB等存儲(chǔ)引擎中。表級(jí)鎖分為: 表鎖、元數(shù)據(jù)鎖(meta data lock, MDL)和意向鎖。

表鎖又分為: 表共享讀鎖 read lock、表獨(dú)占寫鎖write lock

語法: 1、加鎖 lock tables 表名 ... read/write

2、釋放鎖 unlock tables 或者關(guān)閉客戶端連接

注意: 讀鎖不會(huì)阻塞其它客戶端的讀,但是會(huì)阻塞其它客戶端的寫,寫鎖既會(huì)阻塞其它客戶端的讀,又會(huì)阻塞其它客戶端的寫。大家可以拿一張表來測(cè)試看看。

元數(shù)據(jù)鎖,在加鎖過程中是系統(tǒng)自動(dòng)控制的,無需顯示使用,在訪問一張表的時(shí)候會(huì)自動(dòng)加上,MDL鎖主要作用是維護(hù)表元數(shù)據(jù)的數(shù)據(jù)一致性,在表上有活動(dòng)事務(wù)的時(shí)候,不可以對(duì)元數(shù)據(jù)進(jìn)行寫入操作。為了避免DML和DDL沖突,保證讀寫的正確性。

在MySQL5.5中引入了MDL,當(dāng)對(duì)一張表進(jìn)行增刪改查的時(shí)候,加MDL讀鎖(共享);當(dāng)對(duì)表結(jié)構(gòu)進(jìn)行變更操作時(shí),加MDL寫鎖(排他).

查看元數(shù)據(jù)鎖:

select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema_metadata_locks;

意向鎖,為了避免DML在執(zhí)行時(shí),加的行鎖與表鎖的沖突,在innodb中引入了意向鎖,使得表鎖不用檢查每行數(shù)據(jù)是否加鎖,使用意向鎖來減少表鎖的檢查。意向鎖分為,意向共享鎖is由語句select ... lock in share mode添加。意向排他鎖ix,由insert,update,delete,select。。。for update 添加。

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_lock;

行級(jí)鎖,每次操作鎖住對(duì)應(yīng)的行數(shù)據(jù),鎖定粒度最小,發(fā)生鎖沖突的概率最高,并發(fā)讀最高,應(yīng)用在innodb存儲(chǔ)引擎中。

innodb的數(shù)據(jù)是基于索引組織的,行鎖是通過對(duì)索引上的索引項(xiàng)加鎖來實(shí)現(xiàn)的,而不是對(duì)記錄加的鎖,對(duì)于行級(jí)鎖,主要分為以下三類:

1、行鎖或者叫record lock記錄鎖,鎖定單個(gè)行記錄的鎖,防止其他事物對(duì)次行進(jìn)行update和delete操作,在RC,RR隔離級(jí)別下都支持。

2、間隙鎖Gap lock,鎖定索引記錄間隙(不含該記錄),確保索引記錄間隙不變,防止其他事物在這個(gè)間隙進(jìn)行insert操作,產(chǎn)生幻讀,在RR隔離級(jí)別下都支持。

3、臨鍵鎖Next-key-lock,行鎖和間隙鎖組合,同時(shí)鎖住數(shù)據(jù),并鎖住數(shù)據(jù)前面的間隙Gap,在RR隔離級(jí)別下支持。

innodb實(shí)現(xiàn)了以下兩種類型的行鎖

1、共享鎖 S: 允許一個(gè)事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖。

2、排他鎖 X: 允許獲取排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)獲得相同數(shù)據(jù)集的共享鎖和排他鎖。

insert 語句 排他鎖 自動(dòng)添加的

update語句 排他鎖 自動(dòng)添加

delete 語句 排他鎖 自動(dòng)添加

select 正常查詢語句 不加鎖 。。。

select 。。。lock in share mode 共享鎖 需要手動(dòng)在select 之后加lock in share mode

select 。。。for update 排他鎖 需要手動(dòng)在select之后添加for update

默認(rèn)情況下,innodb在repeatable read事務(wù)隔離級(jí)別運(yùn)行,innodb使用next-key鎖進(jìn)行搜索和索引掃描,以防止幻讀。

間隙鎖唯一目的是防止其它事務(wù)插入間隙,間隙鎖可以共存,一個(gè)事務(wù)采用的間隙鎖不會(huì)阻止另一個(gè)事務(wù)在同一間隙上采用的間隙鎖。


當(dāng)前名稱:mysql元數(shù)據(jù)鎖怎么用 mysql元數(shù)據(jù)表
分享URL:http://weahome.cn/article/dohojdj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部