MySQL系統架構


  已經很久沒有寫博客了,平時總感覺沒有時間寫,但是卻有大把的時間去走神,去做一些無用的事情。寫博客是挺鍛煉人的一個過程,不僅鍛煉寫作能力,堅持寫還能夠大幅提升技術水平,寫出來還能夠有廣大的網友幫助我們糾錯,一起探討問題。平時有很多的知識點似懂非懂,可能放個假期,僅有的知識點也就隨風飛向遠方了。技術層出不窮,很多時候會讓我們應接不暇,但是有很多知識點是萬變不離其宗,把握兩個原則,少即是多,快即是慢。對某一方面要有足夠的深度,然后再去擴展廣度。最近開始深入學習mysql,志同道合者一同走起嘞。

  以下內容是依據《MySQL性能調優與架構設計》來做的知識點總結,感興趣的朋友可以看一下這本書,畢竟按照書來學習比較系統。能夠整體的把握知識脈絡。

一、MySQL邏輯模塊組成

  mysql可以看成是二層架構,第一層叫SQL Layer,這一部分主要功能是完成mysql數據庫系統處理底層數據之前的所有的准備工作,包括權限判斷、sql解析、執行計划優化、query cache的處理等; 第二層是存儲引擎層(Storage Engine Layer),這一層才是數據庫系統數據存取操作的實現,是由多種存儲引擎共同完成。

  

看起來結構簡單,但是每一層又包含很多的小模塊。

 

SQL Layer層包含的模塊有:

1. 初始化模塊

  初始化模塊就是在mysql server啟動的時候,對整個系統做各種各樣的初始化操作,比如各種buffer,cache結構的初始化和內存空間的申請,各種系統變量的初始化設定,各種存儲引擎的初始化設置等

2. 核心API

  核心API模塊主要是為了提供一些需要非常高效的底層操作功能的優化實現,包括各種底層數據結構的實現,特殊算法的實現,字符竄處理,數字處理等,小文件I/O,格式化輸出,以及最重要的內存管理部分。核心API模塊的所有源代碼都集中在mysys和strings文件夾下面。

3. 網絡交互模塊

  底層網絡交互模塊抽象出底層網絡交互所使用的接口api,實現底層網絡數據的接收與發送,以方便其它各個模塊的調用。以及對這一程序的部分維護。所有源碼都在vio文件夾下面。

4. Client & Server 交互協議模塊

  任何的C/S結構的軟件系統,都肯定會有自己獨有的信息交互協議,MySQL也不例外,MySQL的Client & Server交互協議模塊部分,實現了客戶端與MySQL交互過程中的所有協議。當然這些協議都是建立在現有的OS和網絡協議之上的。如TCP/IP、Unix Socket.  

5. 用戶模塊

  用戶模塊所實現的功能,主要是包括用戶的登錄連接權限控制和用戶的授權管理。就像是MySQL的大門守衛一樣,決定是否給來訪者“開門”

6. 訪問控制模塊

   造訪客人進門了就可以想干嘛就干嘛么? 為了安全考慮,肯定是不能如此隨意。這時候就需要訪問控制模塊實時監控客人的每一個動作,給不同的客人以不同的權限。訪問控制模塊實現的功能就是根據用戶模塊中各用戶的授權信息,以及數據庫自身特有的各種約束,來控制用戶對數據的訪問。用戶模塊和訪問控制模塊兩者結合起來,組成了MySQL整個數據庫系統的權限安全管理的功能。

7. 連接管理、連接線程、線程管理模塊

  連接管理模塊負責監聽對MySQL Server的各種請求,接受連接請求,轉發所有連接請求到線程管理模塊,每一個連接上MySQL Server的客戶端請求都會被分配(或創建)一個連接線程為其單獨服務。而連接線程的主要工作就是負責MySQL Server 與客戶端的通信,接受客戶端的命令請求。傳遞Server端的結果信息。線程管理模塊則負責管理維護這些連接線程。還包括線程的創建,線程的cache等

8. Query解析和轉發模塊

   在MySQL中我們習慣將所有Client端發送給Server端的命令都稱為query,在MySQL Server里面,連接線程接受到客戶端的一個query后,會直接將該query傳遞給專門負責將各種Query進行分類然后轉發給相應的處理模塊,這個模塊就是Query解析和轉發模塊。主要工作就是將query語句進行語義和語法分析,然后按照不同的操作類型進行分類,然后做出針對性的轉發。

9. Query Cache模塊

  Query Cache模塊在MySQL中是一個非常重要的模塊,他的主要功能是將客戶端提交給MySQL的select類的query請求的返回結果集cache到內存中,與該query的一個hash值做一個對應。該Query所取數據的基表發生任何數據的變化之后,MySQL會自動使該query的Cache失效。在讀寫比例非常高的應用系統中,Query cache對性能的提高是非常顯著的。當然他對內存的消耗也是巨大的。

10. Query優化器模塊

  Query優化器,就是優化客戶端請求的query,根據客戶端請求的query語句,和數據庫中的一些統計信息,在一系列算法的基礎上進行分析,得出一個最優的策略,告訴后面的程序如何取得這個query語句的結果。

11. 表變更管理模塊

   表變更管理模塊主要負責完成一些DML和DDL的query,如:update、delete、insert、create table,alter table等語句的處理。

12. 表維護模塊

  表的狀態檢查,錯誤修復,以及優化和分析等工作都是表維護模塊所需要做的事情。

13. 系統狀態管理模塊

   系統狀態管理模塊負責在客戶端請求系統狀態的時候,將各種狀態數據返回給用戶,比如DBA常用的show status命令,show variables命令等,所得到的的結果都是由這個模塊來返回的。

14. 表管理器

   這個模塊從名字上看來和上面的表變更和表維護模塊相混淆,但是其功能與表變更及維護模塊卻完全不同。大家都知道,每一個MySQL的表都有一個表的定義文件,依舊是*.frm文件。表管理器的工作主要就是維護這些文件,以及一個cache,該cache中的主要內容是各個表的結構信息。此外他還維護table級別的鎖管理。

15. 日志記錄模塊

   主要負責整個系統級別的邏輯層的日志的記錄,包括error log, binary log, show query log等。

16. 復制模塊

   復制模塊又可分為Master模塊和Slave模塊兩部分,Master模塊主要負責在Replication環境中讀取Master端binary日志,以及與Slave端的I/O線程交互等工作。Slave模塊比Master模塊所要做的事情稍多一些。在系統中主要體現在兩個線程上面。一個是負責從Master請求和接受binary日志,並寫入本地relay log中的I/O線程。另一個負責從relay log中讀取相關日志文件,然后解析成可以在Slave端正確執行並得到和Master端完全相同的結果的米寧再交給Slave執行的SQL線程。

17. 存儲引擎接口模塊

   存儲引擎接口模塊是MySQL數據庫最有特色的一點了。目前各種數據庫產品中,基本上只有MySQL可以實現其底層數據存儲引擎的插件式管理。這個模塊實際上只是一個抽象類,但是正因為它成功的將各種數據庫處理高度抽象化,才成就了今天的MySQL可插拔存儲引擎的特色。

  ·可以看到僅第一層就擁有這么多的模塊,可見一個簡單易用的數據庫,其底層實現也超復雜的。

 

二、 各模塊的工作配合

  重點來了。 我們通過一個例子來闡述mysql系統的各個模苦是如何相親相愛的完成一個我們認為的很簡單的查詢工作的。

  我們對啟動mysql,客戶端建立連接,請求query,得到返回結果,最終退出。這樣一整個過程來進行分析。

  第一步:當我們執行啟動mysql系統的命令之后,mysql的初始化模塊就從系統配置文件中讀取系統參數和命令行參數,並按照參數來初始化整個系統,如申請並分配buffer,初始化全局變量,以及各種結構等。同時各個存儲引擎也被啟動,進行各自的初始化工作。當整個系統初始化結束后,由連接管理模塊接手,連接管理模塊會啟動處理客戶端連接請求的監聽程序,包括tcp/ip的網絡監聽,還有unix的socket,這時候,mysql serve就基本啟動完成,准備好接受客戶端的請求了。

  第二步:當連接管理模塊監聽到客戶端的連接請求(借助網絡交互模塊的相關功能),雙方通過Client & Server交互協議模塊所定義的協議“寒暄”幾句之后,連接管理模塊就會將連接請求轉發給線程管理模塊,去請求一個連接線程。

  第三步:線程管理模塊接着將控制權交給連接線程模塊,告訴連接線程模塊,現在我這邊連接請求過來了,需要建立連接,你趕快處理一下。連接線程模塊會在接收到連接請求后,首先檢查當前連接線程池中是否有被cache的空閑連接線程,如果有,就取出一個和客戶端請求連接上,如果沒有空閑的連接線程,則建立一個新的連接線程與客戶端請求連接。當然,連接線程模塊並不是在接收到連接請求后馬上就會取出一個連接線程和客戶端連接,而是首先通過調用用戶模塊進行授權檢查,只有客戶端請求通過了授權檢查后,他才會將客戶端請求和負責請求的連接線程連上。

  在MySQL中,將客戶端的請求分為了兩種類型,一種是query,需要調用Parser也就是Query解析和轉發模塊的解析才能夠執行的請求;一種是command,不需要調用Parser就可以執行執行的請求。如果我們的初始化配置打開了Full Query Logging的功能,那么Query解析與轉發模塊就會調用日志記錄模塊將請求計入日志。不管是一個Query類型的請求還是一個command類型的請求,都會被記錄進入日志,所以出於性能考慮一般很少打開Full Query Logging的功能。

  第四步:當客戶端請求和連接線程“互換暗號(互通協議)”接上頭之后,連接線程就開始處理客戶端請求發送過來的各種命令(或者query),接受相關請求。他將收到的query語句轉發給Query解析和轉發模塊,Query解析器先對Query進行基本的語義和語法解析,然后根據命令類型的不同,有些會直接處理,有些會分發給其他模塊來處理。

  如果是一個Query類型的請求,會將控制權交給Query解析器,Query解析器首先分析是不是一個select類型的query,如果是,則調用查詢緩存模塊,讓它檢查該query在query cache中是否已經存在。如果有,則直接將cache中的數據返回給連接線程模塊。然后通過與客戶端連接的線程將數據輸出給客戶端。如果不是一個可以被cache的query類型,或者cache中沒有改query的數據,那么query將被繼續傳回Query解析器,讓Query解析器進行相應處理,在通過Query分發器分發給相關處理模塊。

  第五步:如果解析器解析結果是一條未被cache的select語句,則將控制權交給Optimizer,也就是Query優化器模塊,如果是DML或者是DDL語句,則會交給表變更管理模塊,如果是一些更新統計信息、檢測、修復和整理類的query則會交給表維護模塊去處理,復制相關的query則轉交給復制模塊去進行相應的處理,請求狀態的query則交給狀態收集報告模塊。實際上表變更管理模塊根據所對應的處理請求的不同,是分別由insert處理器、delete處理器、update處理器、create處理器,以及alter處理器這些小模塊來負責不同的DML和DDL的。

  第六步:在各個模塊收到Query解析與分發模塊發過來的請求后,首先會通過訪問控制模塊檢查連接用戶是否有訪問控制目標表以及目標字段的權限,如果有,就會調用表管理模塊請求相應的表,並獲取對應的鎖。表管理模塊首先會看到該表是否已經存在於table cache中,如果已經打開則直接進行鎖相關的處理,如果沒有在cache中,則需要在打開表文件獲取鎖,然后將打開的表交給表變更管理模塊

  第七步:當表變更管理模塊“獲取”打開的表之后,就會根據該表的相關meta信息,判斷表的存儲引擎類型和其它相關信息。根據表的存儲引擎類型,提交請求給存儲引擎接口模塊,調用對應的存儲引擎實現模塊,進行相應處理。

  不過,對於表變更管理模塊來說,可見的僅是存儲引擎接口模塊提供的一系列“標准”接口,底層存儲引擎實現模塊的具體實現,對於表變更管理模塊來說是透明的。他只需要調用對應的接口,並指定表類型,接口模塊會根據表類型調用正確存儲引擎來進行相應的處理。

  第八步:當一條query或者是一個command處理完成(成功或者失敗)之后,控制權都會交還給連接線程模塊。如果處理成功,則將處理結果(可能是一個Result set,也可能是成功或者失敗的標識)通過連接線程反饋給客戶端。如果處理過程中發生錯誤,也會將相應的錯誤信息發送給客戶端,然后連接線程模塊會進行相應的清理工作,並繼續等待后面的請求,重復上面提到的過程,或者完成客戶端斷開連接的請求。

  第九步:如果在上面的過程中,相關模塊使數據庫中的數據發生了變化,而且MySQL打來了bin-log功能,則對應的處理模塊還會調用日志處理模塊將相應的變更語句以更新事件的形式記錄到相關參數指定的二進制日志文件中。

  在上面各個模塊的內容處理過程中,各自的核心運算處理功能部分都會高度依賴整個MySQL API模塊,比如內存管理,文件I/O,數字和字符串處理等。

  以上整個過程如下圖:

 


免責聲明!

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



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