1. MySQL邏輯架構
上圖就是MySQL的邏輯架構:
- 第一層服務並不是MySQL獨有的,大多數是基於網路的客戶端 / 伺服器的工具或者服務都有類似的架構,例如連線處理、授權認證、安全等等一些功能,每個客戶端連線都會在服務端擁有一個執行緒,每個連線發起的查詢都會在對應的單獨執行緒中執行。。
- 第二層是MySQL的核心服務,例如查詢解析、分析、優化、快取以及所有的內建函式(日期、時間、數字函式),以及所有跨引擎的一些功能實現:儲存過程、觸發器、檢視等
- 第三層主要是MySQL儲存引擎,主要負責MySQL中資料的儲存及提取。伺服器通過API與儲存引擎進行通訊。這些介面遮蔽了不同引擎之間的差異,使得這些差異對上層的查詢過程透明。儲存引擎API包含了幾十個底層函式,用於執行 ”開始一個事務“ 或者 ”根據主鍵提取一行記錄等操作“。 另外不同儲存引擎之間也不會相互通訊,只是簡單響應上層伺服器的請求。現在主要使用的儲存引擎有:InnoDB、MyISAM
1.1 優化與執行
MySQL 會解析查詢,並建立內部資料結構(解析樹),然後對其進行各種優化,包括重寫查詢,決定表的讀取順序,以及選擇合適的索引等。使用者可以通過特殊的關鍵字提示(hint)優化器,影響它的決策程式。也可以使用優化器解釋(explain)優化過程的各個因素,便於使用者重構查詢、修改相關配置,使應用盡可能高效執行。
對於SELECT語句,在解析查詢之前,伺服器會先檢查查詢快取(Query Cache),如果能夠找到對應查詢,直接返回查詢快取中的結果集
2. 併發控制
無論什麼時候,只要有多個查詢或多個修改在同時產生,都會產生併發控制的問題。
2.1 讀寫鎖
示例場景:假設有一張表,在同一時刻被多個使用者併發讀取,同時有另外一個使用者在進行刪除或修改某條記錄,這個時候多個使用者讀取資料會和實際資料庫的資料發生不一致的情況。那該類情況下該如何處理。該類經典問題的解決方法就是併發控制。
處理方式:在處理併發讀或寫的時候,可以通過實現一個由兩種型別的鎖組成的鎖系統來解決問題。這兩種型別的鎖通常被稱為共享鎖(shared lock) 和排它鎖(exclusiv lock) ,也就讀鎖(read lock) 和寫鎖(write lock)。
鎖的概念:讀鎖是共享的,或者說是相互不阻塞的。多個使用者在同一時刻可以同時讀取同一個資源,而相互不干擾。寫鎖是排他的,一個寫鎖會阻塞其他的寫鎖和讀鎖,只有這樣,才能確保在給定的時間內,只有一個使用者能執行寫入。
2.2 鎖粒度
問題:加鎖可解決併發讀或併發寫處理,但同時加鎖也需要消耗資源。鎖的各種操作,包括獲得鎖、檢查鎖是否已經解決、釋放鎖等,都會增加系統的開銷。所以一般資料庫會提供多種鎖策略供使用者選擇,在鎖的開銷和資料的安全性之間尋求平衡
2.2.1 表鎖 (table lock)
表鎖是MySQL中最基本的鎖策略,並且是開銷最小的策略,它會鎖定整張表。一個使用者在對標進行寫操作(insert、delete、update等)前,需要先獲取寫鎖,阻塞其他使用者對該表的讀寫操作。只有沒有寫鎖時,其他使用者才能獲取讀寫。另外讀鎖之間是不相互阻塞的。
ps:寫鎖筆讀鎖擁有更高的優先順序,因此一個寫鎖請求可能會被插入到讀鎖佇列的前面
2.2.2 行鎖 (row lock)
行級鎖可以最大程度地支援併發處理(同時也帶來了最大的鎖開銷),行級鎖只在儲存引擎層實現。
3. 事務
概念:事務就是一組原子性的SQL查詢,或者說一個獨立的工作單元。事務內的語句,要麼全部執行成功,要麼全部執行失敗。一個好的事務處理系統,必須具備ACID特徵
- 原子性(atomicity):一個事務必須是一個不可分割的最小工作單元,整個事務的操作要麼全部提交成功,要麼全部失敗回滾。不可能只執行其中一部分操作,這就是事務的原子性
- 一致性(consistency):資料庫總是從一個一致性的狀態轉換到另外一個一致性的狀態。不存在部分狀態調整。
- 隔離性(isolation):一個事務所做的修改在最終提交前,對其他事務是不可見的。
- 永續性(durbility):一旦事務提交,其所做的修改就會永久儲存到資料庫中。此時即使系統崩潰,修改的資料也不會丟失。不同的永續性策略有不同的永續性級別,後續待介紹
ps:就像鎖粒度的升級或增加系統開銷一樣,這種事務處理過程中額外的安全性,也會需要資料庫系統做更多額外的工作。一個實現ACID的資料庫,相比沒有實現的ACID資料庫,通常會需要更強的CPU處理能力,更大的記憶體和更多的磁碟空間。