MySQL架構與概念
一、MySQL的邏輯架構
數據庫
最上面不是MySQL特有的,全部基於網絡的C/S的網絡應用程序都應該包括鏈接處理、認證、安全管理等。
中間層是MySQL的核心,包括查詢解析、分析、優化和緩存等。同時它還提供跨存儲引擎的功能,包括存儲過程、觸發器和視圖等。
最下面是存儲引擎,它負責存取數據。服務器經過storage engine API能夠和各類存儲引擎進行交互。
1.一、查詢優化和執行(Optimization and Execution)緩存
MySQL 將用戶的查詢語句進行解析,並建立一個內部的數據結構——分析樹,而後進行各類優化,例如重寫查詢、選擇讀取表的順序,以及使用哪一個索引等。查詢優化器不 關心一個表所使用的存儲引擎,可是存儲引擎會影響服務器如何優化查詢。優化器經過存儲引擎獲取一些參數、某個操做的執行代價、以及統計信息等。在解析查詢 以前,服務器會先訪問查詢緩存(query cache)——它存儲SELECT語句以及相應的查詢結果集。若是某個查詢結果已經位於緩存中,服務器就不會再對查詢進行解析、優化、以及執行。它僅僅 將緩存中的結果返回給用戶便可,這將大大提升系統的性能。安全
1.二、併發控制
MySQL提供兩個級別的併發控制:服務器級(the server level)和存儲引擎級(the storage engine level)。加鎖是實現併發控制的基本方法,MySQL中鎖的粒度:
(1) 表級鎖:MySQL獨立於存儲引擎提供表鎖,例如,對於ALTER TABLE語句,服務器提供表鎖(table-level lock)。
(2) 行級鎖:InnoDB和Falcon存儲引擎提供行級鎖,此外,BDB支持頁級鎖。InnoDB的併發控制機制,下節詳細討論。
另外,值得一提的是,MySQL的一些存儲引擎(如InnoDB、BDB)除了使用封鎖機制外,還同時結合MVCC機制,即多版本兩階段封鎖協議(Multiversion two-phrase locking protocal),來實現事務的併發控制,從而使得只讀事務不用等待鎖,提升了事務的併發性。
注:併發控制是DBMS的核心技術之一(實際上,對於OS也同樣),它對系統性能有着相當重要的影響,之後再詳細討論。
服務器
1.三、事務處理
MySQL中,InnoDB和BDB都支持事務處理。這裏主要討論InnoDB的事務處理(關於BDB的事務處理,也十分複雜,之前曾較爲詳細看過其源碼,之後有機會再討論)。
1.3.一、事務的ACID特性
事務是由一組SQL語句組成的邏輯處理單元,事務具備如下4個屬性,一般簡稱爲事務的ACID屬性(Jim Gray在《事務處理:概念與技術》中對事務進行了詳盡的討論)。
(1)原子性(Atomicity):事務是一個原子操做單元,其對數據的修改,要麼全都執行,要麼全都不執行。
(2)一致性(Consistent):在事務開始和完成時,數據都必須保持一致狀態。這意味着全部相關的數據規則都必須應用於事務的修改,以保持數據的完整性;事務結束時,全部的內部數據結構(如B樹索引或雙向鏈表)也都必須是正確的。
(3)隔離性(Isolation):數據庫系統提供必定的隔離機制,保證事務在不受外部併發操做影響的「獨立」環境執行。這意味着事務處理過程當中的中間狀態對外部是不可見的,反之亦然。
(4)持久性(Durable):事務完成以後,它對於數據的修改是永久性的,即便出現系統故障也可以保持。
1.3.二、事務處理帶來的相關問題
因爲事務的併發執行,帶來如下一些著名的問題:
(1)更新丟失(Lost Update):當兩個或多個事務選擇同一行,而後基於最初選定的值更新該行時,因爲每一個事務都不知道其餘事務的存在,就會發生丟失更新問題--最後的更新覆蓋了由其餘事務所作的更新。
(2) 髒讀(Dirty Reads):一個事務正在對一條記錄作修改,在這個事務完成並提交前,這條記錄的數據就處於不一致狀態;這時,另外一個事務也來讀取同一條記錄,若是不加 控制,第二個事務讀取了這些「髒」數據,並據此作進一步的處理,就會產生未提交的數據依賴關係。這種現象被形象地叫作"髒讀"。
(3)不可重複讀(Non-Repeatable Reads):一個事務在讀取某些數據後的某個時間,再次讀取之前讀過的數據,卻發現其讀出的數據已經發生了改變、或某些記錄已經被刪除了!這種現象就叫作「不可重複讀」。
(4)幻讀(Phantom Reads):一個事務按相同的查詢條件從新讀取之前檢索過的數據,卻發現其餘事務插入了知足其查詢條件的新數據,這種現象就稱爲「幻讀」。
1.3.三、事務的隔離性
SQL2標準定義了四個隔離級別。定義語句以下:
SET TRANSACTION ISOLATION LEVEL
[READ UNCOMMITTED |
READ COMMITTED |
REPEATABLE READ |
SERIALIZABLE ]
這 與Jim Gray所提出的隔離級別有點差別。其中READ UNCOMMITTED即Jim的10(瀏覽);READ COMMITTED即20,遊標穩定性;REPEATABLE READ爲2.99990隔離(沒有幻像保護);SERIALIZABLE隔離級別爲30,徹底隔離。SQL2標準默認爲徹底隔離(30)。各個級別存在 問題以下:
網絡
隔離級數據結構 |
髒讀架構 |
不可重複讀併發 |
幻象讀性能 |
讀未提交優化 (Read uncommitted) |
可能 |
可能 |
可能 |
讀提交 (Read committed) |
不可能 |
可能 |
可能 |
可重複讀 (Repeatable read) |
不可能 |
不可能 |
可能 |
可串行化 (Serializable) |
不可能 |
不可能 |
不可能 |
各 個具體數據庫並不必定徹底實現了上述4個隔離級別,例如,Oracle只提供READ COMMITTED和Serializable兩個標準隔離級別,另外還提供本身定義的Read only隔離級別;SQL Server除支持上述ISO/ANSI SQL92定義的4個隔離級別外,還支持一個叫作「快照」的隔離級別,但嚴格來講它是一個用MVCC實現的Serializable隔離級別。MySQL 支持所有4個隔離級別,其默認級別爲Repeatable read,但在具體實現時,有一些特色,好比在一些隔離級別下是採用MVCC一致性讀。國產數據庫DM也支持全部級別,其默認級別爲READ COMMITTED。