高性能MySQL04-鎖機制

一、簡介

MySQL中有着Lock和Latch的概念,在數據庫中,這兩者都可以被稱爲“鎖”,但是兩者有着截然不同的含義。

Latch一般稱爲閂鎖(輕量級的鎖),因爲其要求鎖定的時間必須非常短。若持續的時間長,則應用的性能會非常差,在InnoDB引擎中,Latch又可以分爲mutex(互斥量)和rwlock(讀寫鎖)。其目的是用來保證併發線程操作臨界資源的正確性,並且通常沒有死鎖檢測的機制。

Lock的對象是事務,用來鎖定的是數據庫中的對象,如表、頁、行。並且一般lock的對象僅在事務commit或rollback後進行釋放(不同事務隔離級別釋放的時間可能不同)。

二、鎖的類型

對數據的操作其實只有兩種,也就是讀和寫,而數據庫在實現鎖時,也會對這兩種操作使用不同的鎖。

這兩種類型的鎖通常被稱爲共享鎖(shared lock)和排它鎖(exclusive lock),也叫讀鎖(read lock)和寫鎖(write lock)。

讀鎖是共享的,或者說是相互不阻塞的。多個客戶在同一時刻可以同時讀取同一個資源,而互不干擾。

寫鎖則是排它的,也就是說一個寫鎖會阻塞其它的寫鎖和讀鎖,這樣可以只允許一個人進行寫入,防止其他用戶讀取正在寫入的資源。

三、鎖粒度

Lock鎖根據粒度主要分爲表鎖、頁鎖和行鎖。不同的存儲引擎擁有的鎖粒度都不同。每種MySQL存儲引擎都可以實現自己的鎖策略和鎖粒度。

1、表鎖(table lock)

表級別的鎖定是MySQL各存儲引擎中最大顆粒度的鎖定機制,並且是開銷最小的策略。表鎖會鎖定整張表。一人用戶對錶進行寫入(插入、刪除、更新等)前,需要先獲得寫鎖,這會阻塞其它用戶對該表的所有讀寫操作。只有沒有寫鎖時,其它讀取的用戶都能獲得讀鎖,讀鎖之間是相互不阻塞的。

儘管存儲引擎可以管理自己的鎖,MySQL本身還是會使用各種有效的表鎖來實現不同的目的。例如,服務器會爲諸如ALTER TABLE之類的語句使用表鎖,而忽略存儲引擎的鎖機制。

使用表級鎖定的主要是MyISAM,MEMORY,CSV等一些非事務性存儲引擎。

2、行鎖(row lock)

行級鎖定最大的特點就是鎖定對象的粒度很小,也是目前各大數據庫管理軟件所實現的鎖定顆粒度最小的。由於鎖定顆粒度很小,所以發生鎖定資源爭用的概率也最小,能夠給予應用程序儘可能大的併發處理能力而提高一些需要高併發應用系統的整體性能。

雖然能夠在併發處理能力上面有較大的優勢,但是行級鎖定也因此帶來了不少弊端。由於鎖定資源的顆粒度很小,所以每次獲取鎖和釋放鎖需要做的事情也更多,所以也帶來了最大的鎖開銷。此外,行級鎖定也最容易發生死鎖。

使用行級鎖定的主要是InnoDB存儲引擎。

四、死鎖

死鎖是指兩個或者多個事務在同一資源上相互佔用,並請求鎖定對方佔用的資源,從而導致惡性循環的現象。當多個事務試圖以不同的順序鎖定資源時,就可能會產生死鎖多個事務同時鎖定同一個資源時,也會產生死鎖。

如下:

事務1:
START TRANSACTION;
UPDATE test SET age = 45 WHERE id = 4;
UPDATE test SET age = 19 WHERE id = 3;
COMMIT;

事務2:
START TRANSACTION;
UPDATE test SET age = 20 WHERE id = 3;
UPDATE test SET age = 47 WHERE id = 4;
COMMIT;

如果湊巧,兩個事務都執行了第一條UPDATE語句,更新了一行數據,同時也鎖定了該行數據,接着每個事務都嘗試去執行第二條UPDATE語句,卻發現已經被對方鎖定,然後兩個事務都在等待對方釋放鎖,同時又持有對方需要的鎖,則陷入死循環。除非有外部因素介入纔可能解除死鎖。

InnoDB目前處理死鎖的方法是,將持有最少等級排它鎖的事務進行回滾(這是相對比較簡單的死鎖回滾算法)。

死鎖發生以後,只有部分或者完全回滾其中一個事務,都能打破死鎖,對於事務型的系統,這是無法避免的。

五、總結

表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。

從鎖的角度來說,表級鎖更適合於以查詢爲主,只有少量按索引條件更新數據的應用,如Web應用;而行級鎖則更適合於有大量按索引條件併發更新少量不同數據,同時又有併發查詢的應用,如一些在線事務處理(OLTP)系統。

參考

1、《高性能MySQL》 [美]Baron Scbwartz, Peter Zaitsev, Vadim Tkacbenko 著
2、 蹲廁所的熊談談MySQL的鎖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章