mysql表鎖怎么產(chǎn)生 mysql 鎖表

mysql的鎖表機(jī)制不太理解,請(qǐng)?jiān)敿?xì)解釋

表級(jí)鎖、頁級(jí)鎖和行級(jí)鎖是不同粒度上的鎖,區(qū)別就是鎖定的范圍大小,顧名思義,表級(jí)鎖就是在整個(gè)表上請(qǐng)求一個(gè)鎖,頁級(jí)鎖就是在某個(gè)數(shù)據(jù)頁上請(qǐng)求一個(gè)鎖,行級(jí)鎖就是在某行上請(qǐng)求一個(gè)鎖。

創(chuàng)新互聯(lián)建站主要企業(yè)基礎(chǔ)官網(wǎng)建設(shè),電商平臺(tái)建設(shè),移動(dòng)手機(jī)平臺(tái),微信平臺(tái)小程序開發(fā)等一系列專為中小企業(yè)按需策劃產(chǎn)品體系;應(yīng)對(duì)中小企業(yè)在互聯(lián)網(wǎng)運(yùn)營的各種問題,為中小企業(yè)在互聯(lián)網(wǎng)的運(yùn)營中保駕護(hù)航。

更新操作一般優(yōu)先級(jí)比讀取要高,前提是讀取操作在隊(duì)列中尚未執(zhí)行,如果讀取已經(jīng)開始從數(shù)據(jù)中獲取數(shù)據(jù)了,這時(shí)候更新請(qǐng)求的鎖資源已經(jīng)被讀取操作鎖定了,那它只能等讀取操作結(jié)束以后才能執(zhí)行。

輕松掌握MySQL數(shù)據(jù)庫鎖機(jī)制的相關(guān)原理[1]

在一個(gè)update和insert操作頻繁的表中 少量數(shù)據(jù)測試的時(shí)候運(yùn)行良好 在實(shí)際運(yùn)營中 因數(shù)據(jù)量比較大( 萬條記錄) 會(huì)出現(xiàn)死鎖現(xiàn)象 用show processlist查看 可以看到一個(gè)update語句狀態(tài)是Locked 一個(gè)delete語句狀態(tài)是Sending data 查看了一下參考手冊(cè) 把鎖定相關(guān)的資料整理下來 以便自己記錄和追蹤該問題的解決情況

MySQL 支持對(duì)MyISAM和MEMORY表進(jìn)行表級(jí)鎖定 對(duì)BDB表進(jìn)行頁級(jí)鎖定 對(duì)InnoDB 表進(jìn)行行級(jí)鎖定 在許多情況下 可以根據(jù)培訓(xùn)猜測應(yīng)用程序使用哪類鎖定類型最好 但一般很難說出某個(gè)給出的鎖類型就比另一個(gè)好 一切取決于應(yīng)用程序 應(yīng)用程序的不同部分可能需要不同的鎖類型 為了確定是否想要使用行級(jí)鎖定的存儲(chǔ)引擎 應(yīng)看看應(yīng)用程序做什么并且混合使用什么樣的選擇和更新語句 例如 大多數(shù)Web應(yīng)用程序執(zhí)行許多選擇 而很少進(jìn)行刪除 只對(duì)關(guān)鍵字的值進(jìn)行更新 并且只插入少量具體的表 基本MySQL MyISAM設(shè)置已經(jīng)調(diào)節(jié)得很好

在MySQL中對(duì)于使用表級(jí)鎖定的存儲(chǔ)引擎 表鎖定時(shí)不會(huì)死鎖的 這通過總是在一個(gè)查詢開始時(shí)立即請(qǐng)求所有必要的鎖定并且總是以同樣的順序鎖定表來管理

對(duì)WRITE MySQL使用的表鎖定方法原理如下

◆ 如果在表上沒有鎖 在它上面放一個(gè)寫鎖

◆否則 把鎖定請(qǐng)求放在寫鎖定隊(duì)列中

對(duì)READ MySQL使用的鎖定方法原理如下

◆如果在表上沒有寫鎖定 把一個(gè)讀鎖定放在它上面

◆否則 把鎖請(qǐng)求放在讀鎖定隊(duì)列中

當(dāng)一個(gè)鎖定被釋放時(shí) 鎖定可被寫鎖定隊(duì)列中的線程得到 然后是讀鎖定隊(duì)列中的線程

這意味著 如果你在一個(gè)表上有許多更新 SELECT語句將等待直到?jīng)]有更多的更新

如果INSERT 語句不沖突 可以自由為MyISAM 表混合并行的INSERT 和SELECT 語句而不需要鎖定

InnoDB 使用行鎖定 BDB 使用頁鎖定 對(duì)于這兩種存儲(chǔ)引擎 都可能存在死鎖 這是因?yàn)?在SQL語句處理期間 InnoDB 自動(dòng)獲得行鎖定 BDB 獲得頁鎖定 而不是在事務(wù)啟動(dòng)時(shí)獲得

行級(jí)鎖定的優(yōu)點(diǎn)

· 當(dāng)在許多線程中訪問不同的行時(shí)只存在少量鎖定沖突

· 回滾時(shí)只有少量的更改

· 可以長時(shí)間鎖定單一的行

行級(jí)鎖定的缺點(diǎn)

· 比頁級(jí)或表級(jí)鎖定占用更多的內(nèi)存

· 當(dāng)在表的大部分中使用時(shí) 比頁級(jí)或表級(jí)鎖定速度慢 因?yàn)槟惚仨毇@取更多的鎖

· 如果你在大部分?jǐn)?shù)據(jù)上經(jīng)常進(jìn)行 GROUP BY 操作或者必須經(jīng)常掃描整個(gè)表 比其它鎖定明顯慢很多

· 用高級(jí)別鎖定 通過支持不同的類型鎖定 你也可以很容易地調(diào)節(jié)應(yīng)用程序 因?yàn)槠滏i成本小于行級(jí)鎖定

在以下情況下 表鎖定優(yōu)先于頁級(jí)或行級(jí)鎖定

· 表的大部分語句用于讀取

· 對(duì)嚴(yán)格的關(guān)鍵字進(jìn)行讀取和更新 你可以更新或刪除可以用單一的讀取的關(guān)鍵字來提取的一行

# ; UPDATE tbl_name SET column = value WHERE unique_key_col = key_value ;

# ; DELETE FROM tbl_name WHERE unique_key_col = key_value ;

· SELECT 結(jié)合并行的INSERT 語句 并且只有很少的UPDATE或 DELETE 語句

· 在整個(gè)表上有許多掃描或 GROUP BY 操作 沒有任何寫操作

lishixinzhi/Article/program/MySQL/201311/29594

關(guān)于MySQL中的表鎖和行鎖

mysql行鎖和表鎖

鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或純線程并發(fā)訪問某一資源的機(jī)制。在數(shù)據(jù)庫中,除傳統(tǒng)的計(jì)算資源(CPU、RAM、I/O)的爭用以外,數(shù)據(jù)也是一種供許多用戶共享的資源。如何保證數(shù)據(jù)并發(fā)訪問的一致性、有效性是所在有數(shù)據(jù)庫必須解決的一個(gè)問題,鎖沖突也是影響數(shù)據(jù)庫并發(fā)訪問性能的一個(gè)重要因素。從這個(gè)角度來說,鎖對(duì)數(shù)據(jù)庫而言顯得尤其重要,也更加復(fù)雜。

概述

相對(duì)其他數(shù)據(jù)庫而言,MySQL的鎖機(jī)制比較簡單,其最顯著的特點(diǎn)是不同的存儲(chǔ)引擎支持不同的鎖機(jī)制。

MySQL大致可歸納為以下3種鎖:

表級(jí)鎖:開銷小,加鎖快;不會(huì)出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。

行級(jí)鎖:開銷大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。

頁面鎖:開銷和加鎖時(shí)間界于表鎖和行鎖之間;會(huì)出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般

MySQL表級(jí)鎖的鎖模式(MyISAM)

MySQL表級(jí)鎖有兩種模式:表共享鎖(Table Read Lock)和表獨(dú)占寫鎖(Table Write Lock)。

對(duì)MyISAM的讀操作,不會(huì)阻塞其他用戶對(duì)同一表請(qǐng)求,但會(huì)阻塞對(duì)同一表的寫請(qǐng)求;

對(duì)MyISAM的寫操作,則會(huì)阻塞其他用戶對(duì)同一表的讀和寫操作;

MyISAM表的讀操作和寫操作之間,以及寫操作之間是串行的。

當(dāng)一個(gè)線程獲得對(duì)一個(gè)表的寫鎖后,只有持有鎖線程可以對(duì)表進(jìn)行更新操作。其他線程的讀、寫操作都會(huì)等待,直到鎖被釋放為止。

MySQL表級(jí)鎖的鎖模式

MySQL的表鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨(dú)占寫鎖(Table Write Lock)。鎖模式的兼容如下表

MySQL中的表鎖兼容性

當(dāng)前鎖模式/是否兼容/請(qǐng)求鎖模式

讀鎖 ? ?是 ? ?是 ? ?否 ?

寫鎖 ? ?是 ? ?否 ? ?否 ?

可見,對(duì)MyISAM表的讀操作,不會(huì)阻塞其他用戶對(duì)同一表的讀請(qǐng)求,但會(huì)阻塞對(duì)同一表的寫請(qǐng)求;對(duì)MyISAM表的寫操作,則會(huì)阻塞其他用戶對(duì)同一表的讀和寫請(qǐng)求;MyISAM表的讀和寫操作之間,以及寫和寫操作之間是串行的!(當(dāng)一線程獲得對(duì)一個(gè)表的寫鎖后,只有持有鎖的線程可以對(duì)表進(jìn)行更新操作。其他線程的讀、寫操作都會(huì)等待,直到鎖被釋放為止。)

如何加表鎖

MyISAM在執(zhí)行查詢語句(SELECT)前,會(huì)自動(dòng)給涉及的所有表加讀鎖,在執(zhí)行更新操作(UPDATE、DELETE、INSERT等)前,會(huì)自動(dòng)給涉及的表加寫鎖,這個(gè)過程并不需要用戶干預(yù),因此用戶一般不需要直接用LOCK TABLE命令給MyISAM表顯式加鎖。在本書的示例中,顯式加鎖基本上都是為了方便而已,并非必須如此。

給MyISAM表顯示加鎖,一般是為了一定程度模擬事務(wù)操作,實(shí)現(xiàn)對(duì)某一時(shí)間點(diǎn)多個(gè)表的一致性讀取。

要特別說明以下兩點(diǎn)內(nèi)容。

上面的例子在LOCK TABLES時(shí)加了‘local’選項(xiàng),其作用就是在滿足MyISAM表并發(fā)插入條件的情況下,允許其他用戶在表尾插入記錄

在用LOCKTABLES給表顯式加表鎖是時(shí),必須同時(shí)取得所有涉及表的鎖,并且MySQL支持鎖升級(jí)。也就是說,在執(zhí)行LOCK TABLES后,只能訪問顯式加鎖的這些表,不能訪問未加鎖的表;同時(shí),如果加的是讀鎖,那么只能執(zhí)行查詢操作,而不能執(zhí)行更新操作。其實(shí),在自動(dòng)加鎖的情況下也基本如此,MySQL問題一次獲得SQL語句所需要的全部鎖。這也正是MyISAM表不會(huì)出現(xiàn)死鎖(Deadlock Free)的原因

一個(gè)session使用LOCK TABLE 命令給表film_text加了讀鎖,這個(gè)session可以查詢鎖定表中的記錄,但更新或訪問其他表都會(huì)提示錯(cuò)誤;同時(shí),另外一個(gè)session可以查詢表中的記錄,但更新就會(huì)出現(xiàn)鎖等待。

當(dāng)使用LOCK TABLE時(shí),不僅需要一次鎖定用到的所有表,而且,同一個(gè)表在SQL語句中出現(xiàn)多少次,就要通過與SQL語句中相同的別名鎖多少次,否則也會(huì)出錯(cuò)!

并發(fā)鎖

在一定條件下,MyISAM也支持查詢和操作的并發(fā)進(jìn)行。

MyISAM存儲(chǔ)引擎有一個(gè)系統(tǒng)變量concurrent_insert,專門用以控制其并發(fā)插入的行為,其值分別可以為0、1或2。

當(dāng)concurrent_insert設(shè)置為0時(shí),不允許并發(fā)插入。

當(dāng)concurrent_insert設(shè)置為1時(shí),如果MyISAM允許在一個(gè)讀表的同時(shí),另一個(gè)進(jìn)程從表尾插入記錄。這也是MySQL的默認(rèn)設(shè)置。

當(dāng)concurrent_insert設(shè)置為2時(shí),無論MyISAM表中有沒有空洞,都允許在表尾插入記錄,都允許在表尾并發(fā)插入記錄。

可以利用MyISAM存儲(chǔ)引擎的并發(fā)插入特性,來解決應(yīng)用中對(duì)同一表查詢和插入鎖爭用。例如,將concurrent_insert系統(tǒng)變量為2,總是允許并發(fā)插入;同時(shí),通過定期在系統(tǒng)空閑時(shí)段執(zhí)行OPTIONMIZE TABLE語句來整理空間碎片,收到因刪除記錄而產(chǎn)生的中間空洞。

MyISAM的鎖調(diào)度

前面講過,MyISAM存儲(chǔ)引擎的讀和寫鎖是互斥,讀操作是串行的。那么,一個(gè)進(jìn)程請(qǐng)求某個(gè)MyISAM表的讀鎖,同時(shí)另一個(gè)進(jìn)程也請(qǐng)求同一表的寫鎖,MySQL如何處理呢?答案是寫進(jìn)程先獲得鎖。不僅如此,即使讀進(jìn)程先請(qǐng)求先到鎖等待隊(duì)列,寫請(qǐng)求后到,寫鎖也會(huì)插到讀請(qǐng)求之前!這是因?yàn)镸ySQL認(rèn)為寫請(qǐng)求一般比讀請(qǐng)求重要。這也正是MyISAM表不太適合于有大量更新操作和查詢操作應(yīng)用的原因,因?yàn)?,大量的更新操作?huì)造成查詢操作很難獲得讀鎖,從而可能永遠(yuǎn)阻塞。這種情況有時(shí)可能會(huì)變得非常糟糕!幸好我們可以通過一些設(shè)置來調(diào)節(jié)MyISAM的調(diào)度行為。

通過指定啟動(dòng)參數(shù)low-priority-updates,使MyISAM引擎默認(rèn)給予讀請(qǐng)求以優(yōu)先的權(quán)利。

通過執(zhí)行命令SET LOW_PRIORITY_UPDATES=1,使該連接發(fā)出的更新請(qǐng)求優(yōu)先級(jí)降低。

通過指定INSERT、UPDATE、DELETE語句的LOW_PRIORITY屬性,降低該語句的優(yōu)先級(jí)。

雖然上面3種方法都是要么更新優(yōu)先,要么查詢優(yōu)先的方法,但還是可以用其來解決查詢相對(duì)重要的應(yīng)用(如用戶登錄系統(tǒng))中,讀鎖等待嚴(yán)重的問題。

另外,MySQL也提供了一種折中的辦法來調(diào)節(jié)讀寫沖突,即給系統(tǒng)參數(shù)max_write_lock_count設(shè)置一個(gè)合適的值,當(dāng)一個(gè)表的讀鎖達(dá)到這個(gè)值后,MySQL變暫時(shí)將寫請(qǐng)求的優(yōu)先級(jí)降低,給讀進(jìn)程一定獲得鎖的機(jī)會(huì)。

上面已經(jīng)討論了寫優(yōu)先調(diào)度機(jī)制和解決辦法。這里還要強(qiáng)調(diào)一點(diǎn):一些需要長時(shí)間運(yùn)行的查詢操作,也會(huì)使寫進(jìn)程“餓死”!因此,應(yīng)用中應(yīng)盡量避免出現(xiàn)長時(shí)間運(yùn)行的查詢操作,不要總想用一條SELECT語句來解決問題。因?yàn)檫@種看似巧妙的SQL語句,往往比較復(fù)雜,執(zhí)行時(shí)間較長,在可能的情況下可以通過使用中間表等措施對(duì)SQL語句做一定的“分解”,使每一步查詢都能在較短時(shí)間完成,從而減少鎖沖突。如果復(fù)雜查詢不可避免,應(yīng)盡量安排在數(shù)據(jù)庫空閑時(shí)段執(zhí)行,比如一些定期統(tǒng)計(jì)可以安排在夜間執(zhí)行。

InnoDB鎖問題

InnoDB與MyISAM的最大不同有兩點(diǎn):一是支持事務(wù)(TRANSACTION);二是采用了行級(jí)鎖。

行級(jí)鎖和表級(jí)鎖本來就有許多不同之處,另外,事務(wù)的引入也帶來了一些新問題。

1.事務(wù)(Transaction)及其ACID屬性

事務(wù)是由一組SQL語句組成的邏輯處理單元,事務(wù)具有4屬性,通常稱為事務(wù)的ACID屬性。

原性性(Actomicity):事務(wù)是一個(gè)原子操作單元,其對(duì)數(shù)據(jù)的修改,要么全都執(zhí)行,要么全都不執(zhí)行。

一致性(Consistent):在事務(wù)開始和完成時(shí),數(shù)據(jù)都必須保持一致狀態(tài)。這意味著所有相關(guān)的數(shù)據(jù)規(guī)則都必須應(yīng)用于事務(wù)的修改,以操持完整性;事務(wù)結(jié)束時(shí),所有的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(如B樹索引或雙向鏈表)也都必須是正確的。

隔離性(Isolation):數(shù)據(jù)庫系統(tǒng)提供一定的隔離機(jī)制,保證事務(wù)在不受外部并發(fā)操作影響的“獨(dú)立”環(huán)境執(zhí)行。這意味著事務(wù)處理過程中的中間狀態(tài)對(duì)外部是不可見的,反之亦然。

持久性(Durable):事務(wù)完成之后,它對(duì)于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)系統(tǒng)故障也能夠保持。

2.并發(fā)事務(wù)帶來的問題

相對(duì)于串行處理來說,并發(fā)事務(wù)處理能大大增加數(shù)據(jù)庫資源的利用率,提高數(shù)據(jù)庫系統(tǒng)的事務(wù)吞吐量,從而可以支持可以支持更多的用戶。但并發(fā)事務(wù)處理也會(huì)帶來一些問題,主要包括以下幾種情況。

更新丟失(Lost Update):當(dāng)兩個(gè)或多個(gè)事務(wù)選擇同一行,然后基于最初選定的值更新該行時(shí),由于每個(gè)事務(wù)都不知道其他事務(wù)的存在,就會(huì)發(fā)生丟失更新問題——最后的更新覆蓋了其他事務(wù)所做的更新。例如,兩個(gè)編輯人員制作了同一文檔的電子副本。每個(gè)編輯人員獨(dú)立地更改其副本,然后保存更改后的副本,這樣就覆蓋了原始文檔。最后保存其更改保存其更改副本的編輯人員覆蓋另一個(gè)編輯人員所做的修改。如果在一個(gè)編輯人員完成并提交事務(wù)之前,另一個(gè)編輯人員不能訪問同一文件,則可避免此問題

臟讀(Dirty Reads):一個(gè)事務(wù)正在對(duì)一條記錄做修改,在這個(gè)事務(wù)并提交前,這條記錄的數(shù)據(jù)就處于不一致狀態(tài);這時(shí),另一個(gè)事務(wù)也來讀取同一條記錄,如果不加控制,第二個(gè)事務(wù)讀取了這些“臟”的數(shù)據(jù),并據(jù)此做進(jìn)一步的處理,就會(huì)產(chǎn)生未提交的數(shù)據(jù)依賴關(guān)系。這種現(xiàn)象被形象地叫做“臟讀”。

不可重復(fù)讀(Non-Repeatable Reads):一個(gè)事務(wù)在讀取某些數(shù)據(jù)已經(jīng)發(fā)生了改變、或某些記錄已經(jīng)被刪除了!這種現(xiàn)象叫做“不可重復(fù)讀”。

幻讀(Phantom Reads):一個(gè)事務(wù)按相同的查詢條件重新讀取以前檢索過的數(shù)據(jù),卻發(fā)現(xiàn)其他事務(wù)插入了滿足其查詢條件的新數(shù)據(jù),這種現(xiàn)象就稱為“幻讀”。

3.事務(wù)隔離級(jí)別

在并發(fā)事務(wù)處理帶來的問題中,“更新丟失”通常應(yīng)該是完全避免的。但防止更新丟失,并不能單靠數(shù)據(jù)庫事務(wù)控制器來解決,需要應(yīng)用程序?qū)σ碌臄?shù)據(jù)加必要的鎖來解決,因此,防止更新丟失應(yīng)該是應(yīng)用的責(zé)任。

“臟讀”、“不可重復(fù)讀”和“幻讀”,其實(shí)都是數(shù)據(jù)庫讀一致性問題,必須由數(shù)據(jù)庫提供一定的事務(wù)隔離機(jī)制來解決。數(shù)據(jù)庫實(shí)現(xiàn)事務(wù)隔離的方式,基本可以分為以下兩種。

一種是在讀取數(shù)據(jù)前,對(duì)其加鎖,阻止其他事務(wù)對(duì)數(shù)據(jù)進(jìn)行修改。

另一種是不用加任何鎖,通過一定機(jī)制生成一個(gè)數(shù)據(jù)請(qǐng)求時(shí)間點(diǎn)的一致性數(shù)據(jù)快照(Snapshot),并用這個(gè)快照來提供一定級(jí)別(語句級(jí)或事務(wù)級(jí))的一致性讀取。從用戶的角度,好像是數(shù)據(jù)庫可以提供同一數(shù)據(jù)的多個(gè)版本,因此,這種技術(shù)叫做數(shù)據(jù)多版本并發(fā)控制(MultiVersion Concurrency Control,簡稱MVCC或MCC),也經(jīng)常稱為多版本數(shù)據(jù)庫。

數(shù)據(jù)庫的事務(wù)隔離級(jí)別越嚴(yán)格,并發(fā)副作用越小,但付出的代價(jià)也就越大,因?yàn)槭聞?wù)隔離實(shí)質(zhì)上就是使事務(wù)在一定程度上“串行化”進(jìn)行,這顯然與“并發(fā)”是矛盾的,同時(shí),不同的應(yīng)用對(duì)讀一致性和事務(wù)隔離程度的要求也是不同的,比如許多應(yīng)用對(duì)“不可重復(fù)讀”和“幻讀”并不敏感,可能更關(guān)心數(shù)據(jù)并發(fā)訪問的能力。

為了解決“隔離”與“并發(fā)”的矛盾,ISO/ANSI SQL92定義了4個(gè)事務(wù)隔離級(jí)別,每個(gè)級(jí)別的隔離程度不同,允許出現(xiàn)的副作用也不同,應(yīng)用可以根據(jù)自己業(yè)務(wù)邏輯要求,通過選擇不同的隔離級(jí)別來平衡"隔離"與"并發(fā)"的矛盾

事務(wù)4種隔離級(jí)別比較

隔離級(jí)別/讀數(shù)據(jù)一致性及允許的并發(fā)副作用 ? ?讀數(shù)據(jù)一致性 ? ?臟讀 ? ?不可重復(fù)讀 ? ?幻讀 ?

未提交讀(Read uncommitted)

最低級(jí)別,只能保證不讀取物理上損壞的數(shù)據(jù) ? ?是 ? ?是 ? ?是 ?

已提交度(Read committed) ? ?語句級(jí) ? ?否 ? ?是 ? ?是 ?

可重復(fù)讀(Repeatable read) ? ?事務(wù)級(jí) ? ?否 ? ?否 ? ?是 ?

可序列化(Serializable) ? ?最高級(jí)別,事務(wù)級(jí) ? ?否 ? ?否 ? ?否 ?

最后要說明的是:各具體數(shù)據(jù)庫并不一定完全實(shí)現(xiàn)了上述4個(gè)隔離級(jí)別,例如,Oracle只提供Read committed和Serializable兩個(gè)標(biāo)準(zhǔn)級(jí)別,另外還自己定義的Read only隔離級(jí)別:SQL Server除支持上述ISO/ANSI SQL92定義的4個(gè)級(jí)別外,還支持一個(gè)叫做"快照"的隔離級(jí)別,但嚴(yán)格來說它是一個(gè)用MVCC實(shí)現(xiàn)的Serializable隔離級(jí)別。MySQL支持全部4個(gè)隔離級(jí)別,但在具體實(shí)現(xiàn)時(shí),有一些特點(diǎn),比如在一些隔離級(jí)下是采用MVCC一致性讀,但某些情況又不是。

獲取InonoD行鎖爭用情況

可以通過檢查InnoDB_row_lock狀態(tài)變量來分析系統(tǒng)上的行鎖的爭奪情況:

如果發(fā)現(xiàn)爭用比較嚴(yán)重,如Innodb_row_lock_waits和Innodb_row_lock_time_avg的值比較高,還可以通過設(shè)置InnoDB Monitors來進(jìn)一步觀察發(fā)生鎖沖突的表、數(shù)據(jù)行等,并分析鎖爭用的原因。?

InnoDB的行鎖模式及加鎖方法

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

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

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

另外,為了允許行鎖和表鎖共存,實(shí)現(xiàn)多粒度鎖機(jī)制,InnoDB還有兩種內(nèi)部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖。

意向共享鎖(IS):事務(wù)打算給數(shù)據(jù)行共享鎖,事務(wù)在給一個(gè)數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖。

意向排他鎖(IX):事務(wù)打算給數(shù)據(jù)行加排他鎖,事務(wù)在給一個(gè)數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。

InnoDB行鎖模式兼容性列表

如果一個(gè)事務(wù)請(qǐng)求的鎖模式與當(dāng)前的鎖兼容,InnoDB就請(qǐng)求的鎖授予該事務(wù);反之,如果兩者兩者不兼容,該事務(wù)就要等待鎖釋放。

意向鎖是InnoDB自動(dòng)加的,不需用戶干預(yù)。對(duì)于UPDATE、DELETE和INSERT語句,InnoDB會(huì)自動(dòng)給涉及及數(shù)據(jù)集加排他鎖(X);對(duì)于普通SELECT語句,InnoDB會(huì)自動(dòng)給涉及數(shù)據(jù)集加排他鎖(X);對(duì)于普通SELECT語句,InnoDB不會(huì)任何鎖;事務(wù)可以通過以下語句顯示給記錄集加共享鎖或排鎖。

共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

排他鎖(X):SELECT * FROM table_name WHERE ...?FOR UPDATE

用SELECT .. IN SHARE MODE獲得共享鎖,主要用在需要數(shù)據(jù)依存關(guān)系時(shí)確認(rèn)某行記錄是否存在,并確保沒有人對(duì)這個(gè)記錄進(jìn)行UPDATE或者DELETE操作。但是如果當(dāng)前事務(wù)也需要對(duì)該記錄進(jìn)行更新操作,則很有可能造成死鎖,對(duì)于鎖定行記錄后需要進(jìn)行更新操作的應(yīng)用,應(yīng)該使用SELECT ... FOR UPDATE方式獲取排他鎖。

InnoDB行鎖實(shí)現(xiàn)方式

InnoDB行鎖是通過索引上的索引項(xiàng)來實(shí)現(xiàn)的,這一點(diǎn)MySQL與Oracle不同,后者是通過在數(shù)據(jù)中對(duì)相應(yīng)數(shù)據(jù)行加鎖來實(shí)現(xiàn)的。InnoDB這種行鎖實(shí)現(xiàn)特點(diǎn)意味者:只有通過索引條件檢索數(shù)據(jù),InnoDB才會(huì)使用行級(jí)鎖,否則,InnoDB將使用表鎖!

在實(shí)際應(yīng)用中,要特別注意InnoDB行鎖的這一特性,不然的話,可能導(dǎo)致大量的鎖沖突,從而影響并發(fā)性能。

什么時(shí)候使用表鎖

對(duì)于InnoDB表,在絕大部分情況下都應(yīng)該使用行級(jí)鎖,因?yàn)槭聞?wù)和行鎖往往是我們之所以選擇InnoDB表的理由。但在個(gè)另特殊事務(wù)中,也可以考慮使用表級(jí)鎖。

第一種情況是:事務(wù)需要更新大部分或全部數(shù)據(jù),表又比較大,如果使用默認(rèn)的行鎖,不僅這個(gè)事務(wù)執(zhí)行效率低,而且可能造成其他事務(wù)長時(shí)間鎖等待和鎖沖突,這種情況下可以考慮使用表鎖來提高該事務(wù)的執(zhí)行速度。

第二種情況是:事務(wù)涉及多個(gè)表,比較復(fù)雜,很可能引起死鎖,造成大量事務(wù)回滾。這種情況也可以考慮一次性鎖定事務(wù)涉及的表,從而避免死鎖、減少數(shù)據(jù)庫因事務(wù)回滾帶來的開銷。

當(dāng)然,應(yīng)用中這兩種事務(wù)不能太多,否則,就應(yīng)該考慮使用MyISAM表。

在InnoDB下 ,使用表鎖要注意以下兩點(diǎn)。

(1)使用LOCK TALBES雖然可以給InnoDB加表級(jí)鎖,但必須說明的是,表鎖不是由InnoDB存儲(chǔ)引擎層管理的,而是由其上一層MySQL Server負(fù)責(zé)的,僅當(dāng)autocommit=0、innodb_table_lock=1(默認(rèn)設(shè)置)時(shí),InnoDB層才能知道MySQL加的表鎖,MySQL Server才能感知InnoDB加的行鎖,這種情況下,InnoDB才能自動(dòng)識(shí)別涉及表級(jí)鎖的死鎖;否則,InnoDB將無法自動(dòng)檢測并處理這種死鎖。

(2)在用LOCAK TABLES對(duì)InnoDB鎖時(shí)要注意,要將AUTOCOMMIT設(shè)為0,否則MySQL不會(huì)給表加鎖;事務(wù)結(jié)束前,不要用UNLOCAK TABLES釋放表鎖,因?yàn)閁NLOCK TABLES會(huì)隱含地提交事務(wù);COMMIT或ROLLBACK產(chǎn)不能釋放用LOCAK TABLES加的表級(jí)鎖,必須用UNLOCK TABLES釋放表鎖,正確的方式見如下語句。

關(guān)于死鎖

MyISAM表鎖是deadlock free的,這是因?yàn)镸yISAM總是一次性獲得所需的全部鎖,要么全部滿足,要么等待,因此不會(huì)出現(xiàn)死鎖。但是在InnoDB中,除單個(gè)SQL組成的事務(wù)外,鎖是逐步獲得的,這就決定了InnoDB發(fā)生死鎖是可能的。

發(fā)生死鎖后,InnoDB一般都能自動(dòng)檢測到,并使一個(gè)事務(wù)釋放鎖并退回,另一個(gè)事務(wù)獲得鎖,繼續(xù)完成事務(wù)。但在涉及外部鎖,或涉及鎖的情況下,InnoDB并不能完全自動(dòng)檢測到死鎖,這需要通過設(shè)置鎖等待超時(shí)參數(shù)innodb_lock_wait_timeout來解決。需要說明的是,這個(gè)參數(shù)并不是只用來解決死鎖問題,在并發(fā)訪問比較高的情況下,如果大量事務(wù)因無法立即獲取所需的鎖而掛起,會(huì)占用大量計(jì)算機(jī)資源,造成嚴(yán)重性能問題,甚至拖垮數(shù)據(jù)庫。我們通過設(shè)置合適的鎖等待超時(shí)閾值,可以避免這種情況發(fā)生。

通常來說,死鎖都是應(yīng)用設(shè)計(jì)的問題,通過調(diào)整業(yè)務(wù)流程、數(shù)據(jù)庫對(duì)象設(shè)計(jì)、事務(wù)大小、以及訪問數(shù)據(jù)庫的SQL語句,絕大部分都可以避免。下面就通過實(shí)例來介紹幾種死鎖的常用方法。

(1)在應(yīng)用中,如果不同的程序會(huì)并發(fā)存取多個(gè)表,應(yīng)盡量約定以相同的順序?yàn)樵L問表,這樣可以大大降低產(chǎn)生死鎖的機(jī)會(huì)。如果兩個(gè)session訪問兩個(gè)表的順序不同,發(fā)生死鎖的機(jī)會(huì)就非常高!但如果以相同的順序來訪問,死鎖就可能避免。

(2)在程序以批量方式處理數(shù)據(jù)的時(shí)候,如果事先對(duì)數(shù)據(jù)排序,保證每個(gè)線程按固定的順序來處理記錄,也可以大大降低死鎖的可能。

(3)在事務(wù)中,如果要更新記錄,應(yīng)該直接申請(qǐng)足夠級(jí)別的鎖,即排他鎖,而不應(yīng)該先申請(qǐng)共享鎖,更新時(shí)再申請(qǐng)排他鎖,甚至死鎖。

(4)在REPEATEABLE-READ隔離級(jí)別下,如果兩個(gè)線程同時(shí)對(duì)相同條件記錄用SELECT...ROR UPDATE加排他鎖,在沒有符合該記錄情況下,兩個(gè)線程都會(huì)加鎖成功。程序發(fā)現(xiàn)記錄尚不存在,就試圖插入一條新記錄,如果兩個(gè)線程都這么做,就會(huì)出現(xiàn)死鎖。這種情況下,將隔離級(jí)別改成READ COMMITTED,就可以避免問題。

(5)當(dāng)隔離級(jí)別為READ COMMITED時(shí),如果兩個(gè)線程都先執(zhí)行SELECT...FOR UPDATE,判斷是否存在符合條件的記錄,如果沒有,就插入記錄。此時(shí),只有一個(gè)線程能插入成功,另一個(gè)線程會(huì)出現(xiàn)鎖等待,當(dāng)?shù)?個(gè)線程提交后,第2個(gè)線程會(huì)因主鍵重出錯(cuò),但雖然這個(gè)線程出錯(cuò)了,卻會(huì)獲得一個(gè)排他鎖!這時(shí)如果有第3個(gè)線程又來申請(qǐng)排他鎖,也會(huì)出現(xiàn)死鎖。對(duì)于這種情況,可以直接做插入操作,然后再捕獲主鍵重異常,或者在遇到主鍵重錯(cuò)誤時(shí),總是執(zhí)行ROLLBACK釋放獲得的排他鎖。

盡管通過上面的設(shè)計(jì)和優(yōu)化等措施,可以大減少死鎖,但死鎖很難完全避免。因此,在程序設(shè)計(jì)中總是捕獲并處理死鎖異常是一個(gè)很好的編程習(xí)慣。

如果出現(xiàn)死鎖,可以用SHOW INNODB STATUS命令來確定最后一個(gè)死鎖產(chǎn)生的原因和改進(jìn)措施。

總結(jié)

對(duì)于MyISAM的表鎖,主要有以下幾點(diǎn)

(1)共享讀鎖(S)之間是兼容的,但共享讀鎖(S)和排他寫鎖(X)之間,以及排他寫鎖之間(X)是互斥的,也就是說讀和寫是串行的。

(2)在一定條件下,MyISAM允許查詢和插入并發(fā)執(zhí)行,我們可以利用這一點(diǎn)來解決應(yīng)用中對(duì)同一表和插入的鎖爭用問題。

(3)MyISAM默認(rèn)的鎖調(diào)度機(jī)制是寫優(yōu)先,這并不一定適合所有應(yīng)用,用戶可以通過設(shè)置LOW_PRIPORITY_UPDATES參數(shù),或在INSERT、UPDATE、DELETE語句中指定LOW_PRIORITY選項(xiàng)來調(diào)節(jié)讀寫鎖的爭用。

(4)由于表鎖的鎖定粒度大,讀寫之間又是串行的,因此,如果更新操作較多,MyISAM表可能會(huì)出現(xiàn)嚴(yán)重的鎖等待,可以考慮采用InnoDB表來減少鎖沖突。

對(duì)于InnoDB表,主要有以下幾點(diǎn)

(1)InnoDB的行銷是基于索引實(shí)現(xiàn)的,如果不通過索引訪問數(shù)據(jù),InnoDB會(huì)使用表鎖。

(2)InnoDB間隙鎖機(jī)制,以及InnoDB使用間隙鎖的原因。

(3)在不同的隔離級(jí)別下,InnoDB的鎖機(jī)制和一致性讀策略不同。

(4)MySQL的恢復(fù)和復(fù)制對(duì)InnoDB鎖機(jī)制和一致性讀策略也有較大影響。

(5)鎖沖突甚至死鎖很難完全避免。

在了解InnoDB的鎖特性后,用戶可以通過設(shè)計(jì)和SQL調(diào)整等措施減少鎖沖突和死鎖,包括:

盡量使用較低的隔離級(jí)別

精心設(shè)計(jì)索引,并盡量使用索引訪問數(shù)據(jù),使加鎖更精確,從而減少鎖沖突的機(jī)會(huì)。

選擇合理的事務(wù)大小,小事務(wù)發(fā)生鎖沖突的幾率也更小。

給記錄集顯示加鎖時(shí),最好一次性請(qǐng)求足夠級(jí)別的鎖。比如要修改數(shù)據(jù)的話,最好直接申請(qǐng)排他鎖,而不是先申請(qǐng)共享鎖,修改時(shí)再請(qǐng)求排他鎖,這樣容易產(chǎn)生死鎖。

不同的程序訪問一組表時(shí),應(yīng)盡量約定以相同的順序訪問各表,對(duì)一個(gè)表而言,盡可能以固定的順序存取表中的行。這樣可以大減少死鎖的機(jī)會(huì)。

盡量用相等條件訪問數(shù)據(jù),這樣可以避免間隙鎖對(duì)并發(fā)插入的影響。

不要申請(qǐng)超過實(shí)際需要的鎖級(jí)別;除非必須,查詢時(shí)不要顯示加鎖。

對(duì)于一些特定的事務(wù),可以使用表鎖來提高處理速度或減少死鎖的可能

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

鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問某一資源的機(jī)制,在數(shù)據(jù)庫中,除傳統(tǒng)的計(jì)算資源(CPU、RAM、I/O)爭用外,數(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ù)提交語句都將阻塞。其典型的使用場景就是做全庫的邏輯備份,對(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ì)阻塞其它客戶端的寫。大家可以拿一張表來測試看看。

元數(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ù)在同一間隙上采用的間隙鎖。

MySQL數(shù)據(jù)庫表鎖定的幾種方法實(shí)現(xiàn)

如果兩個(gè)程序都向表中寫數(shù)據(jù)顯然會(huì)造成很大的麻煩,甚至?xí)幸馔馇闆r發(fā)生。如果表正由一個(gè)程序?qū)懭?,同時(shí)進(jìn)行讀取的另一個(gè)程序也會(huì)產(chǎn)生混亂的結(jié)果。 鎖定表的方法 防止客戶機(jī)的請(qǐng)求互相干擾或者服務(wù)器與維護(hù)程序相互干擾的方法主要有多種。如果你關(guān)閉數(shù)據(jù)庫,就可以保證服務(wù)器 和myisamchk和isamchk之間沒有交互作用。但是停止服務(wù)器的運(yùn)行并不是一個(gè)好注意,因?yàn)檫@樣做會(huì)使得沒有故障的數(shù)據(jù)庫和表也不可用。本節(jié)主 要討論的過程,是避免服務(wù)器和myisamchk或isamchk之間的交互作用。實(shí)現(xiàn)這種功能的方法是對(duì)表進(jìn)行鎖定。 服務(wù)器由兩種表的鎖定方法: 1.內(nèi)部鎖定 內(nèi)部鎖定可以避免客戶機(jī)的請(qǐng)求相互干擾——例如,避免客戶機(jī)的SELECT查詢被另一個(gè)客戶機(jī)的UPDATE查詢所干擾。也可以利用內(nèi)部鎖定機(jī)制防止服務(wù)器在利用myisamchk或isamchk檢查或修復(fù)表時(shí)對(duì)表的訪問。 語法:鎖定表:LOCK TABLES tbl_name {READ | WRITE},[ tbl_name {READ | WRITE},…] 解鎖表:UNLOCKTABLESLOCKTABLES為當(dāng)前線程鎖定表。UNLOCK TABLES釋放被當(dāng)前線程持有的任何鎖。當(dāng)線程發(fā)出另外一個(gè)LOCK TABLES時(shí),或當(dāng)服務(wù)器的連接被關(guān)閉時(shí),當(dāng)前線程鎖定的所有表自動(dòng)被解鎖。 如果一個(gè)線程獲得在一個(gè)表上的一個(gè)READ鎖,該線程(和所有其他線程)只能從表中讀。如果一個(gè)線程獲得一個(gè)表上的一個(gè)WRITE鎖,那么只有持鎖的線程READ或WRITE表,其他線程被阻止。 每個(gè)線程等待(沒有超時(shí))直到它獲得它請(qǐng)求的所有鎖。 WRITE鎖通常比READ鎖有更高的優(yōu)先級(jí),以確保更改盡快被處理。這意味著,如果一個(gè)線程獲得READ鎖,并且然后另外一個(gè)線程請(qǐng)求一個(gè)WRITE鎖, 隨后的READ鎖請(qǐng)求將等待直到WRITE線程得到了鎖并且釋放了它。 顯然對(duì)于檢查,你只需要獲得讀鎖。再者鐘情跨下,只能讀取表,但不能修改它,因此他也允許其它客戶機(jī)讀取表。對(duì)于修復(fù),你必須獲得些所以防止任何客戶機(jī)在你對(duì)表進(jìn)行操作時(shí)修改它。 2.外部鎖定 服務(wù)器還可以使用外部鎖定(文件級(jí)鎖)來防止其它程序在服務(wù)器使用表時(shí)修改文件。通常,在表的檢查操作中服務(wù)器 將外部鎖定與myisamchk或isamchk作合使用。但是,外部鎖定在某些系統(tǒng)中是禁用的,因?yàn)樗荒芸煽康倪M(jìn)行工作。對(duì)運(yùn)行myisamchk或 isamchk所選擇的過程取決于服務(wù)器是否能使用外部鎖定。如果不使用,則必修使用內(nèi)部鎖定協(xié)議。 如果服務(wù)器用--skip-locking選項(xiàng)運(yùn)行,則外部鎖定禁用。該選項(xiàng)在某些系統(tǒng)中是缺省的,如Linux??梢酝ㄟ^運(yùn)行mysqladmin variables命令確定服務(wù)器是否能夠使用外部鎖定。檢查skip_locking變量的值并按以下方法進(jìn)行: ◆ 如果skip_locking為off,則外部鎖定有效您可以繼續(xù)并運(yùn)行人和一個(gè)實(shí)用程序來檢查表。服務(wù)器和實(shí)用程序?qū)⒑献鲗?duì)表進(jìn)行訪問。但是,運(yùn)行任何 一個(gè)實(shí)用程序之前,應(yīng)該使用mysqladmin flush-tables。為了修復(fù)表,應(yīng)該使用表的修復(fù)鎖定協(xié)議。 ◆ 如果skip_locaking為on,則禁用外部鎖定,所以在myisamchk或isamchk檢查修復(fù)表示服務(wù)器并不知道,最好關(guān)閉服務(wù)器。如果堅(jiān) 持是服務(wù)器保持開啟狀態(tài),月確保在您使用此表示沒有客戶機(jī)來訪問它。

linux下mysql為什么會(huì)鎖表

為什么要鎖數(shù)據(jù)?就是告訴大家,我現(xiàn)在在用它,其它人不要?jiǎng)印o權(quán)動(dòng),在后面乖乖排隊(duì)。等我操作完就把權(quán)限放出來。

表鎖這個(gè)情況,大部分是使用myisam的存儲(chǔ)引擎。myisam的特點(diǎn),讀的速度快,就是當(dāng)有人在寫操作某個(gè)表時(shí),就會(huì)把這個(gè)表都鎖起來,不讓其它人操作,沒辦法有得有失。

比表鎖更細(xì)一級(jí),就是行鎖,這個(gè)一般是用innodb存儲(chǔ)引擎,它可以做到只鎖定一行數(shù)據(jù),不會(huì)影響其它行的讀寫,更不會(huì)影響整個(gè)表。in操作或者大于小于操作另外討論。

當(dāng)然啦,關(guān)于數(shù)據(jù)庫的鎖,還有讀鎖和寫鎖之分。

網(wǎng)頁標(biāo)題:mysql表鎖怎么產(chǎn)生 mysql 鎖表
當(dāng)前網(wǎng)址:http://muchs.cn/article10/dosdddo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)品牌網(wǎng)站設(shè)計(jì)、電子商務(wù)網(wǎng)站排名、企業(yè)網(wǎng)站制作、搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

猜你還喜歡下面的內(nèi)容