MySQL架構學習筆記

MySQL邏輯架構

了解MySQL的架構有助于深入理解MySQL服務器,下圖是MySQL的三層邏輯架構圖(圖片來自于網(wǎng)絡)。

第一層用于對客戶端的連接處理、安全認證、授權等。每個客戶端連接都會在服務端擁有一個線程,每個連接發(fā)起的查詢都會在對應的單獨線程中執(zhí)行。

第二層包含了MySQL的核心服務功能,包括查詢解析、分析、查詢緩存、內置函數(shù)、存儲過程、觸發(fā)器、視圖等。當客戶端發(fā)起請求時,如果是SELECT操作,MySQL會先檢查是否命中查詢緩存,命中則直接返回查詢緩存中的數(shù)據(jù);否則,MySQL會解析查詢并創(chuàng)建對應的內部數(shù)據(jù)結構(解析樹),執(zhí)行各種優(yōu)化,然后執(zhí)行。

第三層包含了存儲引擎,存儲引擎負責數(shù)據(jù)的存儲和提取。MySQL中有很多種不同類型的存儲引擎,每個存儲引擎各不相同,MySQL服務器通過API與存儲引擎通信,屏蔽了各種存儲引擎之間的差異。

MySQL中的鎖

MySQL在處理并發(fā)讀和寫的時候,分別使用共享鎖(讀鎖)和排它鎖(寫鎖)。

對共享資源高并發(fā)操作,在加鎖的時候,最好能只鎖定所需要的數(shù)據(jù),控制鎖的粒度、提高并發(fā)能力。MySQL提供了兩種最重要的鎖策略,表級鎖和行級鎖。

表級鎖,即鎖定整張表。在對表進行插入、更新、刪除操作時,需要先獲得寫鎖,鎖定整張表,其它讀寫操作將會被阻塞。讀鎖之間是不會阻塞的。需要注意的是alter table操作會使用表級鎖,所以對數(shù)據(jù)量很大的表進行alter table操作時,需要謹慎。

行級鎖,即只鎖定數(shù)據(jù)所在的行,行級鎖只在存儲引擎層實現(xiàn)。行級鎖可以很好的支持并發(fā)處理,但是也會導致大量的資源開銷。

事務特性

四大特性(ACID):原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。

原子性:一個事務中的所有操作,要么全部成功執(zhí)行,要么全部失敗回滾;
一致性:事務執(zhí)行結果使數(shù)據(jù)庫從一個一致性狀態(tài)變到另一個一致性狀態(tài);
隔離性:事務操作提交之前,操作結果對其它事務不可見;
持久性:事務提交后,所有的修改操作會永久保存到數(shù)據(jù)庫中。

事務隔離級別

SQL標準中定義了四種隔離級別,分別是Read Uncommitted、Read Committed、Repeatable Read、Serializable。

Read Uncommitted:該隔離級別下,事務中未提交的數(shù)據(jù)對其它事務是可見的,即其它事務可以讀取到未提交事務的數(shù)據(jù),出現(xiàn)臟讀。

Read Committed:該隔離級別下,事務只能讀取到已提交事務所改變的數(shù)據(jù),解決了臟讀的問題,但是會出現(xiàn)不可重復讀,即在一個事務前后兩次讀取某數(shù)據(jù)的中間時刻,有其它事務修改了該數(shù)據(jù),導致兩次讀取的數(shù)據(jù)不一致。

Repeatable Read:該隔離級別是MySQL數(shù)據(jù)庫的默認事務隔離級別,它解決了不可重復讀的問題,但是會出現(xiàn)幻讀,即事務在讀取某范圍內的數(shù)據(jù)時,其它事務在該范圍內插入了新紀錄,導致之前的事務再次讀取會不一致。

Serializable:最高的隔離級別,該隔離級別下,通過強制事務串行執(zhí)行、在讀取的每一行數(shù)據(jù)上加鎖,來避免出現(xiàn)幻讀的問題。因為讀取的數(shù)據(jù)每行上都會加鎖,可能會導致大量的超時和鎖競爭問題,所以一般不使用該級別,除非是數(shù)據(jù)一致性要求特別高的情況。

下面通過一張圖清晰的展示各隔離級別。

MySQL可以通過執(zhí)行SET TRANSACTION ISOLATION LEVEL命令來設置隔離級別,新設置的隔離級別將在下一個事務開始的時候生效。

MySQL中的死鎖

死鎖是指多個事務在同一資源上相互占用,并請求鎖定對方所占用的資源,從而導致的惡性循環(huán)現(xiàn)象。

數(shù)據(jù)庫系統(tǒng)為了解決這個問題,實現(xiàn)了死鎖檢測和死鎖超時機制。在MySQL的InnoDB存儲引擎中,解決死鎖的方法是將持有最少行級排它鎖的事務進行回滾。

MySQL事務日志

事務日志,即一種特殊的操作記錄日志。

存儲引擎在修改表數(shù)據(jù)的時候,只修改內存中的拷貝,然后將修改行為記錄保存到硬盤上的事務日志中,對事務日志的保存操作采用追加的方式,保存操作是順序IO,相對于存儲引擎直接將數(shù)據(jù)持久化到硬盤的隨機IO高效的多。事務日志保存后,內存中被修改的數(shù)據(jù)在后臺可以慢慢的持久化到硬盤。如果事務日志保存成功了,而內存中被修改的數(shù)據(jù)沒有成功的寫入硬盤,發(fā)生了系統(tǒng)崩潰,存儲引擎會在重啟時自動恢復這部分數(shù)據(jù)。

MySQL中的事務

MySQL中的事務是在存儲引擎中實現(xiàn)的,所以上層的服務是不會管理事務的。默認情況下,MySQL自身提供了兩種事務型的存儲引擎,分別是InnnoDB和NDB Cluster。

在默認情況下,MySQL事務采用自動提交模式,即如果沒有顯示的開啟一個事務,那么每一次的查詢都將被當做一個事務執(zhí)行自動提交。當然,也可以通過設置來改變這種自動提交的模式。如果想開啟自動提交,可以通過命令SET AUTOCOMMIT = 1或SET AUTOCOMMIT = ON來設置;關閉自動提交模式,可以通過命令SET AUTOCOMMIT = 0或SET AUTOCOMMIT = OFF來設置。

InnoDB存儲引擎采用的是兩階段鎖定協(xié)議,在事務執(zhí)行的過程中,InnoDB會根據(jù)隔離級別在需要加鎖的時候自定加鎖,鎖只有在事務提交或回滾的時候才會釋放。當然,也可以顯示的加鎖,如使用SELECT FOR UPDATE,也可以使用服務層實現(xiàn)的LOCK TABLES和UNLOCK TABLES。

多版本并發(fā)控制(MVCC)

基于對并發(fā)性能的考慮,MySQL的大多數(shù)事務型存儲引擎都實現(xiàn)了多版本并發(fā)控制,可以簡單的認為MVCC是行級鎖的一個變種,但是它在很多情況下避免了加鎖操作,降低了開銷。

InnoDB的MVCC是通過在每行記錄后添加兩個隱藏列來實現(xiàn)的,一個列用于保存行的創(chuàng)建時間,一個列用于保存行的過期時間,這兩個時間在實際存儲的時候,存儲的是系統(tǒng)版本號。每開始一個新事務,系統(tǒng)版本號都將遞增。需要注意的是MVCC只能在Read Committed和Repeatable Read隔離級別下正常工作。

MySQL存儲引擎

MySQL自身和第三方提供了多種存儲引擎,每種存儲引擎優(yōu)勢各不相同,可以根據(jù)實際業(yè)務需要來選擇對應的存儲引擎。

InnoDB是MySQL的默認事務型存儲引擎,主要用來處理大量的短期型事務。它采用MVCC來支持高并發(fā),默認的事務隔離級別是Repeatable Read,并通過間隙鎖策略防止幻讀的出現(xiàn)。InnoDB表是基于聚簇索引建立的,而聚簇索引可以提高對主鍵查詢的性能,但是它的二級索引(非主鍵索引)中必須包含主鍵,如果主鍵列很大,并且有很多個二級索引,那么這些索引將會占用很大的空間和資源,所以在創(chuàng)建主鍵的時候盡量的小。

在MySQL5.1及之前的版本中,MyISAM是默認的存儲引擎,它提供了全文索引、壓縮、空間函數(shù)等功能,但是它不支持事務和行級鎖,并且崩潰后無法安全恢復,而InnoDB引擎是可以自動崩潰恢復的。MyISAM在并發(fā)的情況下,對整張表加鎖,讀操作會對需要讀的所有表加共享鎖,寫入時對表加排它鎖。

原文地址:
https://wind7rui.github.io/2017/10/29/MySQL%E6%9E%B6%E6%9E%84%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容