mysql學習筆記-底層原理詳解


前言
我相信每一個程序員都避免不了和數據庫打交道,其中Mysql以其輕量、開源成為當下最流行的關系型數據庫。Mysql5.0以前以MyISAM作為默認存儲引擎,在5.5版本以后,以InnoDB作為默認存儲引擎,相比MyISAM,InnoDB完整的支持ACID事務特性,同時支持行級鎖,支持事務這一特性也決定了InnoDB代替MyISAM成為主流存儲引擎的一大決定性因素。

Mysql系統架構圖

mysql整體包含四大部分:

連接層:包含各種組件和連接交互接口(Connectors:各種語言可以操控SQL的基礎,支持各種語言)
核心層:也被稱作SQL Laye,包括安全、權限、sql解析、緩存、執行優化。我們常用的視圖、存儲過程、觸發器等功能的實現也集中在這一層
存儲引擎層:也被稱為Storage Engine Layer,由多種存儲引擎共同組成,負責存儲和獲取數據。服務器是通過存儲引擎API來與它們交互的。MySQL中的存儲引擎可以實現插件式管理,它提供了一系列標准的管理和服務支持。
系統層:實際存儲一些數據庫文件以及日志文件等

Sql執行流程圖

連接層

如上圖(Sql執行流程)所示,我們Sql執行首先是客戶端向MySQL服務器發送一條查詢請求,與connectors交互,連接池認證相關處理。
  • 半雙工通信:Mysql客戶端/服務端通信協議是一種半雙工的通信信道,什么叫半雙工呢?半雙工指的是允許客戶端和服務端雙方相互通信,但是同一時刻只允許存在單向通信。對於查詢sql來講,大多數都是客戶端發送的查詢數據包較小且為單個數據包,服務端返回的數據包較大且較大時大多拆分為多個數據包,多個數據包都需要被客戶端完整接收才算是查詢結束,這也是為什么在實際開發中要求我們避免使用select *以及增加limlt查詢條件的原因之一。
  • Connectors(連接器)的職責就是維護上述過程中的連接通到,包括建立連接、權限表驗證、維持連接和關閉連接。新建和關閉應該不用過多描述;權限表驗證是從user、host、db等表查出權限,放置在連接的上下文中(也就是說已經打開的鏈接不受權限變更影響)。維持連接則指的是Connectors需要保障完全接收服務器響應的數據包,不能出現丟包的情況。
  • Connection Pool(連接池) :作為一個單進程多線程的應用,mysql連接也參照實現一種池化

對於mysql連接,任何時刻都有一個狀態,該狀態表示了mysql當前正在做什么。使用show full processlist命令查看當前狀態。下面是這些狀態的解釋:

  • sleep:線程正在等待客戶端發送新的請求;
  • query:線程正在執行查詢或者正在將結果發送給客戶端;
  • locked:在mysql服務器層,該線程正在等待表鎖。在存儲引擎級別實現的鎖,例如InnoDB的行鎖,並不會體現在線程狀態中。對於MyISAM來說這是一個比較典型的狀態。
  • analyzing and statistics:線程正在收集存儲引擎的統計信息,並生成查詢的執行計划;
  • copying to tmp table:線程在執行查詢,並且將其結果集復制到一個臨時表中,這種狀態一般要么是做group by操作,要么是文件排序操作,或者union操作。如果這個狀態后面還有on disk標記,那表示mysql正在將一個內存臨時表放到磁盤上。
  • sorting Result:線程正在對結果集進行排序。
  • sending data:線程可能在多個狀態間傳送數據,或者在生成結果集,或者在想客戶端返回數據。

核心層

我們之前說過,核心層包括安全權限(Management Services & Utilities 、)、sql解析(Parser)、緩存(cache)、執行優化(Optimizer)四塊,不過還應該再加上SQL Interface(Sql接口),這一塊主要是承擔和連接層的交互的作用。所以歸納而言
名稱 說明
Management Services & Utilities MySQL 的系統管理和控制工具,包括備份恢復、MySQL 復制、集群等。
SQL Interface(SQL 接口) 用來接收用戶的 SQL 命令,返回用戶需要查詢的結果。
Parser(查詢解析器) 包含驗證和解析兩部分,以便可以轉換為MySQL優化器可以識別的數據結構或返回 SQL 語句的錯誤。
Optimizer(查詢優化器) 驗證權限和優化查詢。舉個例子 SELECT id, name FROM student WHERE sex = "女";,SELECT 查詢先根據 WHERE 語句進行選取,而不是將表全部查詢出來以后再進行sex過濾。這就屬於一種優化。
SELECT 查詢先根據 id 和 name 進行屬性投影,而不是將屬性全部取出以后再進行過濾,將這兩個查詢條件連接起來生成最終查詢結果。所以說Mysql是使用“選取-投影-連接”策略進行查詢。
Caches & Buffers(查詢緩存) 查詢的時候如果發現緩存中有(hash實現),就直接返回緩存中的結果。這個緩存機制是由一系列小緩存組成的,比如表緩存、記錄緩存、key 緩存、權限緩存等。

Caches & Buffers(查詢緩存)

對select查詢結果做緩存,這個緩存可能包含多個小緩存,緩存的key值是通過查詢本身、當前要查詢的數據庫、客戶端協議版本號等一些可能影響結果的信息計算得來。所以兩個查詢在任何字符上的不同 (例如 : 空格、注釋),都會導致緩存不會命中。

MySQL 8.0版本中查詢緩存的功能已經被刪除

Management Services & Utilities

主要為Mysql的管理服務和一些工具組件,主要作用是對數據的恢復、回滾,以及數據遷移、復制、元數據的管理。主要為以下功能
  • 數據庫備份和恢復
  • 數據庫安全管理,如用戶及權限管理
  • 數據庫復制管理
  • 數據庫集群管理
  • 數據庫分區,分庫,分表管理
  • 數據庫元數據管理

SQL Interface(SQL 接口)

主要是用來接收Sql信息和返回執行結果.大體可以分以下幾類:
  • Data Manipulation Language (DML).
  • Data Definition Language (DDL).
  • 存儲過程
  • 視圖
  • 觸發器

Parser(查詢解析器)

  主要是對傳遞過來sql的分解,先對語法進行驗證檢查。語法檢查通過后,解析器會查詢緩存,如果緩存中有對應的語句,就直接返回結果不進行接下來的優化執行操作。

ps: 緩存中數據被修改,會被清出緩存。

Optimizer(查詢優化器)

  Optimizer階段主要就是對sql的優化了,通過系統規則選定最優的執行方案。這個過程包括選擇語法、常量轉換與計算、無效代碼排除、AND/OR等等,必要時還可能查詢存儲引擎,獲得最優策略。

Pluggable Storage Engine(存儲引擎層)

作為Mysql最具有特色的一塊地方,Mysql將存儲引擎作為一個抽象類,InnoDB、MyISAM、BDB、Memory等等都是其子類。5.5版本以后以InnoDB作為其默認實現。目前除mysql以外其他大多都是單一存儲引擎。

ps:存儲引擎是基於表的,而不是數據庫

InnoDB(默認存儲引擎)

  • 完整的支持ACID事務
  • 支持行級鎖
  • 支持外鍵
  • 使用聚集索引,索引和數據綁在一起在一個邏輯空間上,b+樹葉子節點對於主鍵索引存儲的是數據,對於輔助索引(二級索引)對應的則是主鍵的值
  • count掃全表
  • 必須存在唯一索引(主鍵)

MyISAM

  • 不支持事務,但是插入和更新更快
  • 支持表級鎖
  • 不支持外鍵
  • 使用非聚集索引,索引和數據分離的,b+樹葉子結點均存儲的是實體數據文件地址的指針
  • count走變量不走全表
  • 唯一索引非必要

對於存儲引擎的分析在下一篇博客會着重介紹,這里先介紹整個Mysql的架構,通過架構可以反應出一個sql的執行流程

文件系統層

    磁盤最小單位是512字節,操作系統是4KB,mysql里最小的是page(頁面)有16K

因為基於存儲引擎的不同,底層文件結構也會有些不同,比如InnoDB:frm是表定義文件,ibd是數據文件,而MyISAM:myd是數據文件,myi是索引文件。InnoDB還有redo Log、undo Log

結尾

本篇博客作為一個Mysql全局概覽的介紹,由連接層自上而下的說明了整個Mysql的結構組成,但是Mysql核心還是在存儲引擎上,所以后面會專門拿出一篇博文來介紹InnoDB默認引擎,鞏固自己的知識點。

掃一掃,關注我的公眾號


免責聲明!

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



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