更新時(shí)間:2021-01-08 17:34:27 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1928次
鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或純線程并發(fā)訪問某一資源的機(jī)制。而表鎖由MySQL Server 實(shí)現(xiàn),一般在執(zhí)行DDL語句時(shí)會對整個(gè)表進(jìn)行加鎖,比如說ALTER TABLE等操作。在執(zhí)行SQL語句時(shí),也可以明確指定對某個(gè)表進(jìn)行加鎖。本文我們就來重點(diǎn)講述一下MySQL表鎖。
表鎖使用的是一次性鎖技術(shù),也就是說,在會話開始的地方使用 lock 命令將后續(xù)需要用到的表都加上鎖,在表釋放前,只能訪問這些加鎖的表,不能訪問其他表,直到最后通過 unlock tables 釋放所有表鎖。除了使用 unlock tables 顯示釋放鎖之外,會話持有其他表鎖時(shí)執(zhí)行l(wèi)ock table 語句會釋放會話之前持有的鎖;會話持有其他表鎖時(shí)執(zhí)行 start transaction 或者 begin 開啟事務(wù)時(shí),也會釋放之前持有的鎖。
由于MyISAM存儲引擎使用的鎖定機(jī)制完全是由MySQL提供的表級鎖定實(shí)現(xiàn),所以下面我們將以MyISAM存儲引擎作為示例存儲引擎。
1.MySQL表級鎖的鎖模式
MySQL的表級鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨(dú)占寫鎖(Table Write Lock)。鎖模式的兼容性:
對MyISAM表的讀操作,不會阻塞其他用戶對同一表的讀請求,但會阻塞對同一表的寫請求;
對MyISAM表的寫操作,則會阻塞其他用戶對同一表的讀和寫操作;
MyISAM表的讀操作與寫操作之間,以及寫操作之間是串行的。當(dāng)一個(gè)線程獲得對一個(gè)表的寫鎖后,只有持有鎖的線程可以對表進(jìn)行更新操作。其他線程的讀、寫操作都會等待,直到鎖被釋放為止。
2.如何加表鎖
MyISAM在執(zhí)行查詢語句(SELECT)前,會自動(dòng)給涉及的所有表加讀鎖,在執(zhí)行更新操作(UPDATE、DELETE、INSERT等)前,會自動(dòng)給涉及的表加寫鎖,這個(gè)過程并不需要用戶干預(yù),因此用戶一般不需要直接用LOCK TABLE命令給MyISAM表顯式加鎖。顯式加鎖基本上都是為了方便而已,并非必須如此。給MyISAM表顯示加鎖,一般是為了一定程度模擬事務(wù)操作,實(shí)現(xiàn)對某一時(shí)間點(diǎn)多個(gè)表的一致性讀取。例如,有一個(gè)訂單表orders,其中記錄有訂單的總金額total,同時(shí)還有一個(gè)訂單明細(xì)表order_detail,其中記錄有訂單每一產(chǎn)品的金額小計(jì)subtotal,假設(shè)我們需要檢查這兩個(gè)表的金額合計(jì)是否相等,可能就需要執(zhí)行如下兩條SQL:SELECT SUM(total) FROM orders;
SELECT SUM(subtotal) FROM order_detail;
這時(shí),如果不先給這兩個(gè)表加鎖,就可能產(chǎn)生錯(cuò)誤的結(jié)果,因?yàn)榈谝粭l語句執(zhí)行過程中,order_detail表可能已經(jīng)發(fā)生了改變。因此,正確的方法應(yīng)該是:
LOCK tables orders read local,order_detail read local;
SELECT SUM(total) FROM orders;
SELECT SUM(subtotal) FROM order_detail;
Unlock tables;
3.MyISAM表鎖優(yōu)化建議
對于MyISAM存儲引擎,雖然使用表級鎖定在鎖定實(shí)現(xiàn)的過程中比實(shí)現(xiàn)行級鎖定或者頁級鎖所帶來的附加成本都要小,鎖定本身所消耗的資源也是最少。但是由于鎖定的顆粒度比較到,所以造成鎖定資源的爭用情況也會比其他的鎖定級別都要多,從而在較大程度上會降低并發(fā)處理能力。所以,在優(yōu)化MyISAM存儲引擎鎖定問題的時(shí)候,最關(guān)鍵的就是如何讓其提高并發(fā)度。由于鎖定級別是不可能改變的了,所以我們首先需要盡可能讓鎖定的時(shí)間變短,然后就是讓可能并發(fā)進(jìn)行的操作盡可能的并發(fā)。
從上面對MySQL表鎖的描述我們不難看出,表鎖具有開銷小,加鎖快的特性,而且不會出現(xiàn)死鎖,鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度低。當(dāng)然,表鎖只是MySQL里面的一種大的鎖的類別,還有行鎖。想要了解行鎖的小伙伴,鎖定本站的MySQL教程,里面有著詳細(xì)的講解。

初級 202925

初級 203221

初級 202629

初級 203743