1. 程式人生 > >【筆記】高效能MySQL(第三版)——第1章:MySQL架構與歷史

【筆記】高效能MySQL(第三版)——第1章:MySQL架構與歷史

1.1MySQL伺服器邏輯架構

MySQL伺服器邏輯架構圖

  • 最上層的服務並不是MySQL所獨有的,大多數基於網路的客戶端/伺服器的工具或者服務都有類似的架構。比如連線處理、授權認證、安全等等。
  • 第二層架構是MySQL比較有意思的部分。大多數MySQL的核心服務功能都在這一層,包括查詢解析、分析、優化、快取以及所有的內建函式(例如,日期、時間、數學和加密函式),所有跨儲存引擎的功能都在這一層實現:儲存過程、觸發器、檢視等。
  • 第三層包含了儲存引擎。儲存引擎負責MySQL中資料的儲存和提取。每個儲存引擎都有它的優勢和劣勢。儲存引擎API包含了幾十個底層函式,但儲存引擎不會去解析SQL(註釋:InnoDB是一個例外,它會解析外來鍵定義,因為MySQL伺服器本身沒有實現該功能,這也是MyISAM和InnoDB不同處之一),不同儲存引擎之間也不會相互通訊,而只是簡單地響應上層伺服器的請求。
1.1.1連線管理與安全性
  • 每個客戶端連線都會在伺服器程序中擁有一個執行緒,這個連線的查詢只會在這個單獨的執行緒中執行
  • MySQL5.5之後提供執行緒池外掛
1.1.2優化與執行
  1. MySQL會解析查詢,並建立內部資料結構(解析樹),然後對其進行各種優化,包括重寫查詢、決定表的讀取順序,以及選擇合適的索引等。(第6章詳細討論)
  2. 對於SELECT語句,在解析查詢之前,伺服器會先檢查查詢快取(Query Cache),如果能夠在其中找到對應的查詢,伺服器就不必再執行查詢解析、優化和執行的整個過程,而是直接返回查詢快取中的結果集。(第7章詳細討論)
  3. 儲存引擎對於優化查詢是有影響的。

1.2併發控制

分為伺服器層和儲存引擎層的併發控制,讀寫鎖和併發鎖。
  1. 一種提高共享資源併發性的方式就是讓鎖定物件更有選擇性。最理想的方式是,只對會修改的資料片進行精確的鎖定。在不發生衝突的情況下,鎖定的資料量越小,則系統併發程度越高。
  2. 鎖策略:就是在鎖的開銷和資料的安全性之間尋求平衡,這種平衡當然也會影響到效能。
  3. 表鎖(table lock):表鎖是MySQL中最基本的鎖策略,並且是開銷最小的策略。
  4. 行級鎖(row lock):行級鎖最大程度地支援併發處理(同時也帶來了最大的鎖開銷)。行級鎖只在儲存引擎層實現,而MySQL伺服器層沒有實現。

1.3事務

  • 理論上,RR級別(MySQL預設隔離級別)是沒有解決幻讀問題的,但是InnoDB和XtraDB通過多版本併發控制(MVCC)解決了幻讀問題。
  • 資料庫系統實現了各種死鎖檢測和死鎖超時機制。InnoDB處理死鎖的方法是,將持有最少行級排他鎖的事務進行回滾(相對比較簡單的死鎖回滾演算法)。
事務日誌
  1. 事務日誌可以幫助提高事務的效率。使用事務日誌,儲存引擎在修改表的資料時只需要修改其記憶體拷貝,再把該修改行為記錄到持久在硬碟中的事務日誌中,而不用每次都將修改的資料本身持久到硬碟。事務日誌持久以後,記憶體中被修改的資料在後臺可以慢慢地刷回磁碟(非同步的)。目前大多數儲存引擎都是這樣實現的,通常稱之為預寫式日誌(Write-Ahead Logging),修改資料需要寫兩次磁碟。
  2. 如果資料的修改已經記錄到事務日誌並持久化,但資料本身還沒有寫回磁碟,此時系統崩潰,儲存引擎在重啟時能夠自動恢復這部分修改的資料(redo日誌)。具體的恢復方式則視儲存引擎而定。
AUTOCOMMIT        http://www.cnblogs.com/wingsless/p/6803542.html        autocommit預設是開啟的,所以當我們不顯示的開啟事務時,單個查詢語句(只是針對查詢麼?)結束後會自動執行commit。如果把該選項關閉,那麼所有的查詢都會在一個事務中,直到顯示提交或回滾,所以根據InnoDB裡的MVCC,可以做到可重複讀。可以用SHOW VARIABLES LIKE "AUTOCOMMIT"檢視自動提交模式的狀態。 InnoDB採用的是兩階段鎖定協議(two-phase locking protocol)。在事務執行過程中,隨時都可以執行鎖定,鎖只有在執行COMMIT或ROLLBACK時才會釋放,並且所有的鎖是在同一時刻釋放。InnoDB會根據隔離級別在需要時自動加鎖。 顯示加鎖就是指在SELECT語句中,加上for update 或 lock in share mode(之前說的鎖都是隱式鎖)

1.4 多版本併發控制

  1. MVCC可以認為是行級鎖的一個變種,但它在很多情況下避免了加鎖操作,因此開銷更低。
  2. MVCC的實現,是通過儲存資料在某個時間點的快照來實現的。避免了事務開始的時間不同,而看到不同的資料。
  3. InnoDB的MVCC是通過在每行記錄後面儲存兩個隱藏的列來實現的。這兩列,一列儲存了行的建立時間,一個儲存了行的過期時間(或刪除時間),其實使用的是系統版本號。
  4. 通過獲取適當的版本號的內容來操作資料,保證資料時間上的一致性。對於SELECT操作,選擇的資料,建立時間早於或等於當前事務版本的資料號,刪除版本要麼未定義,要麼大於當前事務版本號。
  5. MVCC只在REPEATABLE READ和READ COMMIT兩個隔離級別下工作。其它兩個都和MVCC不相容,因為READ UNCOMMIT總是讀取最新的資料行,而不是符合當前事務版本的資料行;而SERIALIZABLE則會對所有讀取的行都加鎖。

1.5 InnoDB儲存引擎

  1. InnoDB採用MVCC來支援高併發,並且實現了四個標準的隔離級別。其預設級別是可重複讀(REPEATABLE READ),並且通過間隙鎖(next-key locking)策略防止幻讀的出現。間隙鎖使得InnoDB不僅僅鎖定查詢涉及的行,還會對索引中的間隙進行鎖定,以防止幻行的插入。
  2. InnoDB表是基於聚簇索引簡歷的,InnoDB的索引結構和MySQL的其它儲存引擎有很大的不同,聚簇索引對主鍵查詢有很高的效能。不過它的二級索引(secondary index,非主鍵索引)中必須包含主鍵列,所以如果主鍵列很大的話,其它的所有索引都會很大。因此,若表上的索引較多的話,主鍵應當儘可能的小。
※可以這麼理解,MVCC實現了最基本的可重複讀(通過讀快照的方式),但是如果沒有間隙鎖,那麼事務B往這個範圍內插入資料了,因為MVCC的關係,事務A看不到這個資料,但這時想插入資料就會失敗,所以間隙鎖根本上防止了幻讀(部分割槽域的幻讀)。 具體一些場景可以看這裡。 http://blog.csdn.net/qqqqq1993qqqqq/article/details/75449094
http://blog.csdn.net/qqqqq1993qqqqq/article/details/75519303
http://www.cnblogs.com/digdeep/p/4947694.html