MYSQL學習(二) --MYSQL框架


MYSQL架構理解

通過對MYSQL重要的幾個屬性的理解,建立一個基本的MYSQL的知識框架。后續再補充完善。

一、MYSQL架構

  這里給的架構描述,是很宏觀的架構。有助於建立對MYSQL整體理解。

  1. 架構圖

  以下是在網上找的兩張MYSQL架構圖。能反映MYSQL的結構。

      

 

  結構基本一致,都是連接、服務和存儲引擎三部分。

    

  2.分層實現

  MYSQL大致分為3個層次。連接層服務層引擎層連接層功能是客戶端的鏈接服務服務層完成緩存查詢、SQL分析、SQL優化引擎層真正負責MYSQL數據的存儲和提取

  1.連接層

  核心功能是完成客戶端的鏈接安全服務。負責一些連接處理授權認證以及相關安全方案。該層提供了線程池功能。為通過安全認證的客戶端提供線程。

驗證主要是用戶名、密碼的驗證。

  2.服務層

  服務層提供的服務包括查詢的解析分析(語法、語義)、優化(SQL)、緩存查詢內置函數(日期、數學、時間、加密)、跨存儲引擎的功能(存儲過程、觸發器、視圖)等。

  3.引擎層

  存儲引擎層主要負責數據的存儲和提取。服務器通過API和引擎層進行通信。

  核心需要了解的引擎有InnoDBMyISAM兩種引擎。絕大多數情況下都選擇使用使用InnoDB引擎。

  1. InnoDB支持事務、支持行表鎖(高並發友好-行鎖更好的支持並發)、支持主外鍵、不支持全文檢索。
  2. MyISAM支持全文檢索不支持事務只支持表鎖(對並發不好--操作一條數據就需要鎖住整張表)

  3.查詢組件

  按照查詢過程,描述各組件的功能。

  1.連接器

    管理數據庫鏈接、權限驗證

  

  2.用戶權限是鏈接時刻的用戶權限

    一個用戶成功建立

    連接后,即使你用管理員賬號對這個用戶的權限做了修改,也不會影響已經存在連接的權限。修改完成后,只有再新建的連接才會使用新的權限設置。

  1. 鏈接

    鏈接過程比較麻煩,通常使用長鏈接。

   (1) 長鏈接

    如果客戶端和服務端鏈接上之后,客戶端有持續的請求,則一直使用同一個鏈接。

    長鏈接缺點:容易占用內存。在執行語句中使用的內存是管理在鏈接對象中的。這些資源只有在斷開鏈接的使用才能釋放。如果長鏈接時間較長,可能積累的內存很大,造成內存溢出。解決思路(定期斷開重連)

  (2)短鏈接

    連接后執行SQL之后,斷開鏈接,下次使用時,重新鏈接。

2.查詢緩存

  核心思想就是看,緩存中是否存在剛剛查詢過和當前一樣的SQL。如果存在,則直接使用緩存數據返回。如果不存在,才執行后續的查詢步驟。缺點是:適合於靜態表。如果是動態表,數據實時發生變化。查詢以前的緩存數據不准確。

  1. 查詢緩存

  建立鏈接后,首先是在內存中查詢,看之前是否執行過這條語句。之前執行過的語句可能以KEY-VALUE的形式保存在內存中。KEY為查詢的語句。VALUE是查詢的結果。

  (1)緩存存在

    直接將緩存的數據返回給客戶端。

  (2)緩存不存在

    執行后面的階段。

3.分析器

  將SQL的字符串轉成語法樹。過程包含詞法解析和語法解析。

  (1)詞法解析

  識別字符串中的SQL關鍵字和函數關鍵字。

  (2)語法解析

  在詞法分析基礎之上,生成語法樹。可以向后提交給優化器。

4.優化器

  優化器對語法樹進行進一步優化,給出更合理的執行計划。從而提高SQL的執行效率。

  比如:多個表JOIN的時候,決定表的關聯順序。多個索引時,選擇使用哪個索引。

5.執行器

  經過優化器優化后的語句,進入執行器階段。開始執行語句。

  (1)判斷權限

  判斷用戶有沒有對表操作的權限。如果沒有,則直接返回該用戶沒有權限錯誤。如果有,就繼續執行。

  (2)調用引擎API,繼續執行

  打開表,執行器會根據表的引擎定義,去執行這個引擎提供的接口。

二、並發控制

  當多個線程,同時修改同一張表的數據的時候,就需要並發控制。MYSQL在兩個級別實現並發控制。服務器級(the server level)和存儲引擎級(the storage engine level)。加鎖實現並發控制。對鎖從不同的角度分析,盡量減小鎖對並發的影響。從提升並發性能的角度來分析的

  (一)、盡小可能使用互斥,盡大可能使用共享

  互斥是實現同步的一種方式。也是代價比較大的一種。對並發性能影響較大。因此,對鎖分為共享鎖和互斥鎖。也是經常說的讀鎖和寫鎖。根據不同的情況,在保證正確性的前提下,盡可能使用共享鎖(讀鎖)

  1.讀鎖(共享鎖)

  讀鎖允許多個連接,並發的讀取統一資源,互不干涉。讀鎖之間是共享的。不互斥。

  2.寫鎖(互斥鎖、排它鎖)

  一個寫鎖阻塞其它寫鎖和讀鎖。保證同一時刻只有一個連接寫入數據。同時,防止其它用戶對這個數據進行讀寫。

  (二)、 粒(盡小范圍加鎖)

  在滿足邏輯正確的情況下。加鎖范圍越小,產生阻塞的可能性越小。並發的性能就越高。因此。從這個角度來分析MYSQL的鎖機制。MYSQL中分為表鎖行級鎖

  1.表鎖

  表鎖是用戶操作的過程中對整張表鎖定。只允許一個用戶對表進行操作(插入、刪除、更新)MYSQL獨立於存儲引擎提供表鎖,例如,對於ALTER TABLE語句,服務器提供表鎖(table-level lock)

表鎖是MYSQL基本的鎖策略。也是開銷最小的鎖策略(因為簡單可行)。

  2.行級鎖

  最大程度的支持並發處理。InnoDB支持行級鎖。指鎖定需要的幾行數據即可。也是開銷最大的所策略(需要精確的控制,代價很大)

  (三)、 多版本控制

  多版本控制的核心是 讀事務不用等待鎖。從而更加提升了性能。MYSQLMVCC的實現邏輯。

  通過在每行數據后添加兩個隱藏列來實現。一個是創建時間,一個死過期時間(刪除時間)。這兩個列存儲的是系統版本號(版本號的大小體現時間的先后順序)。每開始一個新的事務,版本號都會增加。事務開始時刻的版本號作為這個事務的版本號。

MVCC的具體操作,InnoDB引擎為例

  (1)INSERT

  插入每行數據,創建時間為當前的系統版本號

  (2)DELETE

  刪除每行數據,保存當前系統版本號為刪除時間。

  (3)UPDATE

  插入一行新數據。當前系統版本號為創建時間。另外,當前版本號為原來行的刪除時間

  (4)SELECT

   讀操作不需要等待其它鎖

   查詢的時候,需要滿足一下兩個條件的數據。

  1. 只需要找創建時間小於或等於當前版本號的數據。(這樣能確保事務讀取的行,要么在事務開始之前就已經存在,要么是事務自身插入或者修改的)
  2. 行的刪除時間,要么未定義,要么大於當前版本。

  符合以上兩個條件的記錄,才能作為查詢結果。

三、 事務

  數據庫的事務處理原則是ACID的正確性。

  (一)、事務的ACID屬性

  1.原子性

  一個事務被視為最小的工作單元,整個事務所有操作,要么都執行,要么全部回滾,都不執行。不能執行其中的一部分,任務不能分割。

  2.一致性

  符合邏輯,從一個一致性狀態轉換到另一個一致性狀態。

  3.隔離性

  提供一定的隔離機制,保證事務在運行過程中不受外部並發操作的影響。一個事務所做的修改,在提交之前,對其它事務不可見。

  4.持久性

  一旦事務提交,其所做的修改就會保存到數據庫中。即事務提交后,對數據的修改是永久性的。

 (二)、 隔離級別

  隔離規定了,一個事務所做的修改,那些在事務內部和事務間是可見的,那些是不可見的。較低級別的隔離通常可以執行較高的並發。系統的開銷更低。

  1.未提交讀 REDA UNCOMMITED

  事務中的修改,即使沒有提交,對其它事務也都是可見的

  這種情況下,容易造成臟讀。

  2.提交讀 READ COMMITED

  一個事務中的修改,只有在事務提交之后,對其它事務才可見。換句話說,一個事務的修改,在其提交之前,對其余事務是不可見的。

  這個級別滿足隔離性的定義,也稱為不可重復讀。因為,即使在一個事務中,重復兩次查詢,可能得到不一樣的結果。

  3.可重復讀 REPEATABLE READ

  同一個事務中,多次讀取,記錄結果是一致的(因為同一個事務,版本號是一樣的,有版本號控制,能夠保證,多次查詢結果是一致的)。重復讀能解決臟讀的問題。

  可重復讀是MYSQL默認的隔離級別

  4.可串行化 SERIALIZABLE

  是隔離的最高級別。強制要求事務串行執行。是加鎖讀。

   

 (三)、 死鎖

  兩個或多個事務,在同一資源上相互占用。並請求占用對方占用的資源。

 (四)、MYSQL中的事務

  MYSQL默認為自動提交(AUTOCOMMIT)

  1.自動提交

  如果不是顯示的提交一個事務(START TRANSACTION ---COMMIT),每個查詢都會作為一個事務提交。

  參數設置:set autocommit = 1

  2.手動提交

  所有的查詢都是在一個事務中,直至顯示的執行commit提交或者rollback回滾,該事務才結束。

  參數設置: set autocommit = 0

 (五)、 事務處理的幾個問題

  由於事務的並發執行,帶來以下一些著名的問題:

  1.更新丟失(Lost Update

  當兩個或多個事務選擇同一行,然后基於最初選定的值更新該行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題--最后的更新覆蓋了由其他事務所做的更新。

  2.臟讀(Dirty Reads

  一個事務正在對一條記錄做修改,在這個事務完成並提交前,這條記錄的數據就處於不一致狀態;這時,另一個事務也來讀取同一條記錄,如果不加控制,第二個事務讀取了這些""數據,並據此做進一步的處理,就會產生未提交的數據依賴關系。這種現象被形象地叫做"臟讀"

  3.不可重復讀(Non-Repeatable Reads

  一個事務在讀取某些數據后的某個時間,再次讀取以前讀過的數據,卻發現其讀出的數據已經發生了改變、或某些記錄已經被刪除了!這種現象就叫做"不可重復讀"

  4.幻讀(Phantom Reads

  一個事務按相同的查詢條件重新讀取以前檢索過的數據,卻發現其他事務插入了滿足其查詢條件的新數據,這種現象就稱為"幻讀"

四、引擎

  數據庫中的引擎是真正執行SQL的組件,被MYSQL集成在內部。MYSQL是一個多引擎的數據庫管理系統。核心的有InnoDB(默認引擎)MyISAM

 (一)、 InnoDB

  MYSQL默認的存儲引擎。最大的特點是支持事務支持行級鎖,因此能支持高並發的訪問。不支持全文索引。索引是基於聚簇索引建立的。對主鍵的查詢有很高的性能。

 (二)、MyISAM

  MYSQL5之前的默認存儲引擎。最大的特點是支持全文索引。但是,不支持事務,支持表鎖。並發支持性不好


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM