MySQL* 執行原理

參考:

https://blog.csdn.net/dream_188810/article/details/78870520

https://blog.csdn.net/soonfly/article/details/70238902

MySQL執行流程

監聽到客戶端(php/java/py等)請求連接 MySQL 服務器時,客戶端會建立一個線程,而 MySQL 服務器有一個線程池(Connection Pool)接管這些連接。

mysql -u root -p -P 3306 -h 127.0.0.1

jiagou_png

 當有 sql 語句傳入時:

SELECT * FROM `user` WHERE `id` = 1;

  1. sql 語句先會交由處理器(Management Serveices & Utilities)等待處理;
  2. 當該請求從等待隊列進入到處理隊列,管理器會將該請求丟給 SQL 接口(SQL Interface)
  3. (查詢緩存): SQL 接口會進入【緩存器】進行命中,如果緩存命中成功,直接進入返回結果;
  4. 如果沒有命中,SQL接口丟給後面的解釋器(Parser),它判斷SQL語句正確與否,正確則將其解析爲數據結構,否則返回異常;
  5. 解釋器將解析的數據結構交給後面的優化器(Optimizer),它會產生多種執行計劃。
  6. 最終數據庫確定一種最優執行計劃後,此時便可以交由存儲引擎(Engine)處理。
  7. 存儲引擎將會到存儲設備中取得相應的數據,並原路返回給程序。

MySQL 各個組件工作原理

線程池(Connection Pool)

  1. 每個客戶端都會建立一個與服務器連接的線程,服務器會有一個線程池來管理這些連接。
  2. 如果客戶端需要連接到MYSQL數據庫還需要進行驗證,包括用戶名、密碼、主機信息等。

處理器(Management Serveices & Utilities)

系統管理和控制工具。

SQL接口(SQL Interface)

用於接受SQL命令,和返回查詢結果的對外處理接口。

解釋器(Parser)

  1. SQL命令傳遞到解析器的時候會被解析器驗證和解析,解析器是由Lex和YACC實現的,是一個很長的腳本。
  2. 將SQL語句分解成數據結構,並將這個結構傳遞到後續步驟,以後SQL語句的傳遞和處理就是基於這個結構的。
  3. 如果在分解構成中遇到錯誤,那麼就說明這個sql語句是不合理的。

優化器(Optimizer)

  1. SQL語句在查詢之前會使用查詢優化器對查詢進行優化。他使用的是“選取-投影-聯接”策略進行查詢。
  2. 用一個例子就可以理解: select uid,name from user where gender = 1;
  • 這個select 查詢先根據 where 語句進行選取,而不是先將表全部查詢出來以後再進行 gender 過濾。
  • 這個select查詢先根據 uid 和 name 進行屬性投影,而不是將屬性全部取出以後再進行過濾。
  • 將這兩個查詢條件聯接起來生成最終查詢結果。

緩存器(Cache & Buffer)

  1. 如果查詢緩存有命中的查詢結果,查詢語句就可以直接去查詢緩存中取數據。
  2. 這個緩存機制是由一系列小緩存組成的。比如表緩存,記錄緩存,key緩存,權限緩存等。

插入式存儲引擎(Pluggable Storage Engine)

數據庫存儲引擎負責創建、查詢、更新和刪除數據,不同的存儲引擎提供不同的存儲機制、索引技巧、鎖定水平等功能,使用不同的存儲引擎,還可以獲得特定的功能。

Innodb vs MyISAM

存儲引擎在MySQL的邏輯架構中位於第三層,負責MySQL中的數據的存儲和提取,MySQL存儲引擎有很多,不同的存儲引擎保存數據和索引的方式是不同。

Innodb 

  1. Innodb 存儲引擎表默認使用獨立表空間(vs 系統表空間)存儲數據,即由 .frm 和 .idb 兩個文件進行存儲。
  2. 作爲典型的事務型存儲引擎,完全支持事務的 ACID 特性。(由 Redo Log 和 Undo Log 實現) 
  3. 支持行級鎖,鎖的存在是爲了處理併發問題,分爲共享鎖(讀鎖)和排他鎖(寫鎖)。

適用:Innodb 始終是最優選擇項。

MyISAM

  1. MyISAM 存儲引擎表由 .frm(用於存儲表結構).MYD(用於存儲表數據) .MYI (存儲表索引)組成。
  2. 使用表級鎖而不是行級鎖,所以併發寫操作的處理效率差些(讀操作時不阻塞末尾的插入數據)。
  3. 表損壞時可檢查和修復:check table test; repair table test;
  4. 支持全文索引,是一種基於分詞創建的索引,可以支持複雜的查詢。
  5. 支持表壓縮(壓縮之後只讀):myisampack -b -f \mysql\data\test\test.MYI
  6. MyISAM 不支持事務,不支持外鍵,不支持集羣數據庫。

適用:非事務型應用、靜態類(即數據不經常更新/刪除)、空間類應用。

MyISAM 表鎖

表共享讀鎖(Table Read Lock):當一個線程獲得對一個表的寫鎖後,只有持有鎖的線程可以對錶進行更新操作,其他線程的讀、寫操作都會等待,直到鎖被釋放爲止。 

表獨佔寫鎖(Table Write Lock):當一個線程獲得對一個表的讀鎖後,這個線程可以查詢鎖定表中的記錄,但更新或訪問其他表都會提示錯誤,其他線程可以查詢表中的記錄,但更新就會出現鎖等待。 

InnoDB 行鎖

InnoDB的行鎖是基於索引實現的,如果不通過索引訪問數據,InnoDB會使用表鎖。行鎖帶來的問題有 髒讀(Dirty Reads)、不可重複讀(Non-Repeatable Reads)、幻讀(Phantom Reads)等問題。

爲此可選擇不同的事務隔離級別來保證數據的準確性:未提交讀(Read uncommitted)、提交讀(Read committed)、可重複讀(Repeatable read,默認)、序列化(Serializable)。

共享鎖(S):又稱讀鎖。允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖。若事務T對數據對象A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。
排他鎖(X):又稱寫鎖。允許獲取排他鎖的事務更新數據,阻止其他事務取得相同的數據集共享讀鎖和排他寫鎖。若事務T對數據對象A加上X鎖,事務T可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到T釋放A上的鎖。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章