1. 程式人生 > >mysql邏輯架構或者說執行邏輯瞭解下

mysql邏輯架構或者說執行邏輯瞭解下

說起這個mysql的架構啊,相信大家的腦海裡會浮現一張圖:

老生常談的話題,咱們先來分析下這張圖,主要有三個層次:

  1. 最上面的一層,連線層,主要是連線與執行緒處理,這一層並不是MySQL獨有,一般的基於C/S架構的都有類似元件,比如連線處理、授權認證、安全等。
  2. 第二次叫sql處理層,也叫MySQL伺服器層,這是MySQL的核心部分,還可以叫做 SQL Layer,包括快取查詢、解析器、優化器,在 MySQL據庫系統處理底層資料之前的所有工作都是在這一層完成的,這一層包含了MySQL核心功能,包括解析、優化SQL語句,查詢快取目錄,內建函式(日期、時間、加密等函式)的實現,還有各個儲存引擎提供的功能都集中在這一層,如儲存過程,觸發器,視 圖等。
  3. 最後就是資料儲存層,也叫儲存引擎層,負責資料儲存,儲存引擎的不同,儲存方式、資料格式、提取方式等都不相同,這一部分也是很大影響資料儲存與提取的效能的。但是,與分層的思想一致,SQL處理層是通過API與儲存引擎通訊的,API遮蔽了下層的差異,下層提供對外介面,上層負責呼叫即可,不必清楚下層是怎麼實現的。

我們來總結下從上圖中瞭解到的一些資訊:

  1. 1)mysql是一個C/S架構模型,客戶端通過與服務端建立連線來操作服務端資料;
  2. 2)服務端的連線模組,將每一個客戶端傳送來的請求作為一個執行緒處理;
  3. 3)分析器分析請求,並轉發給優化器;
  4. 4)通過快取的方式提高查詢效能;
  5. 5)優化器負責和底層的儲存引擎進行互動,儲存和查詢mysql的資料;

既然MySQL是基於C/S架構的,這裡的客戶端自然是專門的,能訪問到MySQL伺服器的,主要有這麼幾類,操作客戶端:單純的操作MySQL伺服器中的資料(這裡資料包括庫、表、索引、表中資料等),比如常用的native、phpMyAdmin、Sequal Pro等;應用客戶端:應用程式通過程式訪問資料庫,比如JDBC、ODBC、PHP程式、python程式等。不管是哪種,其實最後都轉換為SQL語句訪問MySQL。

好,到這裡嘞,咱們來具體看下上述的mysql架構的三個層次是咋工作的???

首先就是連線層,也就是當MySQL啟動(MySQL伺服器就是一個程序),完事就等待客戶端連線,每當一個客戶端傳送連線請求,伺服器都會新建一個執行緒處理(如果是執行緒池的話,則是分配一個空的執行緒),每個執行緒獨立,擁有各自的記憶體處理空間,但是,如果這個請求只是查詢,沒關係,但是若是修改資料,很顯然,當兩個執行緒修改同一塊記憶體是會引發資料同步問題的,來看下連線處理的流程圖:

之後,當我們連線到伺服器時,伺服器需要對其進行驗證,也就是使用者名稱、IP、密碼驗證,一旦連線成功,還要驗證是否具有執行某個特定查詢的許可權(例如,是否允許客戶端對某個資料庫某個表的某個操作) 來看下這個認證過程的流程圖:

到這裡,相信大家會有一點點明瞭了,再來最後總結下,如下:

在我們伺服器內部,每個client連線都有自己的執行緒,這個連線的查詢都在一個單獨的執行緒中執行,同時這些執行緒輪流執行在某一個CPU核心(多核CPU)或者CPU中。然而,我們的伺服器快取了執行緒,因此不需要為每個client連線單獨建立和銷燬執行緒 。當clients(也就是應用程式)連線到了MySQL伺服器。伺服器就需要對它進行認證(Authenticate),這個認證也就是基於使用者名稱,主機,以及密碼,但是,對於使用了SSL(安全套接字層)的連線,還使用了X.509證書。最後嘞,clients一連線上,伺服器就驗證它的許可權 (如是否允許客戶端可以查詢world資料庫下的Country表的資料)。

好啦,咱們再來看下第二層,也就是sql處理層。

這一層主要功能有:SQL語句的解析、優化,快取的查詢,MySQL內建函式的實現,跨儲存引擎功能(所謂跨儲存引擎就是說每個引擎都需提供的功能(引擎需對外提供介面)),例如:儲存過程、觸發器、檢視等。

咱們先來簡單看下執行sql的一個流程圖:

上圖呢,只是一個簡單的過程,不是特定的某個型別的sql,我們可以來代入下試試。

如果是查詢語句(select語句),首先會查詢快取是否已有相應結果,有則返回結果,無則進行下一步(如果不是查詢語句,同樣調到下一步)。

另外嘞,我們來看下這個MySQL在這一步,進行的操作。

首先,它在解析查詢之前,要查詢快取,這個快取只能儲存查詢資訊以及結果資料。如果請求一個查詢在快取中存在,就不需要解析,優化和執行查詢了,可以直接返回快取中所存放的這個查詢的結果,反之嘞,就會解析查詢,並建立了一個內部資料結構(解析樹),然後對其進行各種優化。這些優化包括了,查詢語句的重寫,讀表的順序,索引的選擇等等。使用者可以通過查詢語句的關鍵詞傳遞給優化器以便提示使用哪種優化方式,這樣就影響了優化器的優化方式,咱這裡先不說好壞啊。另外,使用者也可以請求伺服器給出優化過程的各種說明,以獲知伺服器的優化策略,為使用者提供了引數基準,以便使用者可以重寫查詢,架構和修改相關伺服器配置,便於mysql更高效的執行。

咱要注意的是,優化器並是不關心表使用了哪種儲存引擎,但是儲存引擎對伺服器優化查詢的方式是有影響的。優化器需要知道儲存引擎的一些特性:具體操作的效能和開銷方面的資訊,以及表內資料的統計資訊。例如,儲存引擎支援哪些索引型別,這對於查詢是非常有用的。

來看下最後一層,儲存資料的層面。我們只需要知道,不同的儲存引擎會採用不同的技術(儲存機制、索引機制、鎖定機制)儲存資料,這主要是為了滿足資料儲存要求,比如有的資料不需要大量的改動,只用來查詢,而有的資料則需要常常修改(資料插入、刪除、更新),針對各種業務情況,為了更好的資料處理效率採用不同的資料儲存技術(即不同儲存引擎)。還要注意的是,MySQL的儲存引擎是外掛式的,也就是說,使用者可以隨時切換MySQL的儲存引擎:針對表或針對庫都可(通過SQL語句命令)。這種靈活性也是為什麼MySQL受到歡迎的一個重要原因。MySQL集合了多種引擎:MyISAM、InnoDB、BDB、Merge、Memory等,預設的是InnoDB(MySQL5.5開始,以前是MyISAM)。

這個儲存引擎介面模組可以說是 MySQL 資料庫中最有特色的一點了,我們可以看到,目前各種資料庫產品中,基本上只有 MySQL 可以實現其底層資料儲存引擎的外掛式管理。實際上這個模組只是一個抽象類,但正是因為它成功地將各種資料處理高度抽象化,才成就了今天 MySQL 可插拔儲存引擎的特色。

咱們不廢話啊,再來看下MySQL的物理檔案組成,包含三個模組:

1)日誌檔案

  1-1)Error log 錯誤日誌:記錄遇到的所有嚴重的錯誤資訊、每次啟動關閉的詳細資訊;

  1-2)Binary log 二進位制日誌:也就是binlog,記錄所有修改資料庫的操作;

  1-3)Query log 查詢日誌:記錄所有查詢操作,體積較大,開啟後對效能有影響;

  1-4)Slow Query log 慢查詢日誌:記錄所有執行時間超過long_query_time的sql語句和達到min_examined_row_limit條距離的語句;

  1-5)InnoDB redo log:記錄InnoDB所做的物理變更和事務資訊;

2)資料檔案

  2-1).frm檔案:表結構定義資訊

  2-2).MYD檔案:MyISAM引擎的資料檔案;

  2-3).MYI檔案:MyISAM引擎的索引檔案;

  2-4).ibd檔案和.ibdata檔案:InnoDB的資料和索引;.ibdata配置為共享表空間時使用,.ibd配置為獨享表空間時使用;

3)其它檔案

  3-1)系統配置檔案:/etc/my.cnf

  3-2) pid檔案:儲存自己的程序ID

  3-3)socket檔案:連線客戶端使用

最後,就是今天最最重要的sql邏輯模組組成這一部分了。

mysql邏輯架構採用sql層和儲存引擎分離的方式,實現了資料儲存和邏輯業務的分離,我們在巨集觀層次上可以分為三個組成部分,如下:

  1. 連線處理層
  2. 分析、快取處理層
  3. 優化器層

我感覺有點籠統啊,咱們再來細細的化分下:

  1. 初始化模組:資料庫啟動時,對資料庫的初始化操作;
  2. 核心API模組:底層操作的優化功能;
  3. 網路互動模組:對外提供可接收發送資料的API介面;
  4. 伺服器客戶端互動協議模組:實現客戶端服務端的互動協議;
  5. 使用者模組:控制使用者連線登入和授權;
  6. 訪問控制模組:監控使用者的每一個操作,依賴於使用者模組;
  7. 連線管理、連線執行緒和執行緒管理模組:監聽和管理與客戶端連線的執行緒;
  8. 轉發模組:將請求轉發到對應的處理模組;
  9. 快取模組:將查詢請求的結果快取,提高效能;
  10. 優化器模組:根據查詢請求計算提高查詢訪問速度的優化策略,根據最優策略返回查詢語句;
  11. 表變更模組:DML和DDL的語句處理;
  12. 表維護模組:檢測表狀態、分析、優化表結構、修復表;
  13. 系統狀態管理模組:將各種狀態資料返回,如:show status;
  14. 表管理器:維護系統生成的表文件如:.frm檔案.ibd檔案...將表結構的資訊快取,另外該模組還管表級別的鎖;
  15. 日誌記錄模組:負責整個資料庫邏輯層的日誌檔案;
  16. 複製模組:分為Master模組和Slave模組;Master模組負責複製binary檔案,並與Slave端I/O執行緒互動;Slave模組主要負責從Master端接收binary日誌,並寫入本地I/O執行緒,以及從relay log檔案中讀取日誌,解析成Slave端執行的命令,交給Slave端的SQL執行緒處理;
  17. 儲存引擎介面模組:實現了底層儲存引擎外掛式管理,將資料處理高度抽象化;

再來看下sql邏輯模組是如何協調工作的哈,流程圖如下:

解析如下:

  1. mysql啟動以後,初始化模組就從系統配置檔案中讀取系統引數和命令引數,初始化整個系統,同時儲存引擎也會啟動;
  2. 初始化結束後,連線管理模組會監聽客戶端的連線請求,並將連線請求轉發給執行緒管理模組去請求一個連線執行緒;
  3. 執行緒模組接到請求後會呼叫使用者模組進行授權檢查,通過授權以後會檢查是否又空閒執行緒,如果有取出並與客戶端連線,如果沒有則新建立建立一個執行緒與客戶端連線;
  4. mysql請求分為兩種,一種是需要命令解析和分發才能執行,另一種可以直接執行;不管哪種,如果開啟了日誌,那麼日誌模組會記錄日誌;
  5. 如果是Query型別的請求,會將控制權交給Query解析器,Query解析器檢查是否Select型別,如果是則啟動查詢快取模組,如果快取命中則將快取資料返回給連線執行緒模組,連線執行緒將資料傳遞到客戶端;如果沒有快取或者不是一個可以快取的查詢,此時解析器會進行相應的處理,通過查詢分發器給相關的處理模組;
  6. 如果解析器結果是DML/DDL,則交給變更模組;如果是檢查、修復的查詢交給表維護模組,如果是一條沒有被快取的語句,則交給查詢優化器模組。實際上表變更模組又分為若干小模組,例如:insert處理器、delete處理器、update處理器、create處理器,以及alter處理器這些小模組來負責不同的DML和DDL。總之,查詢優化器、表變更模組、表維護模組、複製模組、狀態模組都是根據命令解析器的結果不同而分發給不同的型別模組,最後和儲存引擎進行互動。
  7. 當一條命令執行完畢後,控制權都會還給連線執行緒模組,在上面各個模組處理過程中都依賴於核心API模組,比如:記憶體管理、檔案I/O,字串處理等。

到這裡嘞,就差不多結束了。

希望通過這篇文章,能夠讓大家對於這個MySQL的所謂的架構有一些簡單的瞭解。

好啦,本次記錄就到這裡了。

如果感覺不錯的話,請多多點贊支援哦。。。