Mysql 邏輯架構圖及日志系統


  我們經常能看到如下的邏輯架構圖,但是往往不能進行很好的記憶,看過就忘記了,也不知道它的實現方式。今天通過簡單的畫圖來簡單了解一下mysql到底是如何執行一個select語句,如何update一條語句。

 

1、Mysql邏輯架構圖

場景一:一條SQL語句如何執行?

1.1 一條SQL語句的執行過程

如圖:

 

 

大體來說,MySQL可以分為Server層和存儲引擎層兩部分。

Server層包括連接器、查詢緩存、分析器、優化器、執行器等,涵蓋MySQL的大多數核心服務功能,以及所有的內置函數(如日期、時間、數學和加密函數等),所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖等。

而存儲引擎層負責數據的存儲和提取。其架構模式是插件式的,支持InnoDB、MyISAM、Memory等多個存儲引擎。現在最常用的存儲引擎是InnoDB,它從MySQL 5.5.5版本開始成為了默認存儲引擎。

也就是說,你執行create table建表的時候,如果不指定引擎類型,默認使用的就是InnoDB。不過,你也可以通過指定存儲引擎的類型來選擇別的引擎,比如在create table語句中使用engine=memory, 來指定使用內存引擎創建表。不同存儲引擎的表數據存取方式不同,支持的功能也不同。 不同的存儲引擎共用一個Server層,也就是從連接器到執行器的部分。

 A.連接器:show processlist; 查看連接狀態,Sleep表示空間連接,query表示操作狀態

B.分析器:如果沒有命中查詢緩存,就要開始真正執行語句了。首先,MySQL需要知道你要做什么,因此需要對SQL語句做解析。 分析器先會做“詞法分析”。你輸入的是由多個字符串和空格組成的一條SQL語句,MySQL需要識別出里面的字符串分別是什么,代表什么。 MySQL從你輸入的"select"這個關鍵字識別出來,這是一個查詢語句。它也要把字符串“T”識別成“表名T”,把字符串“ID”識別成“列ID”。 做完了這些識別以后,就要做“語法分析”。根據詞法分析的結果,語法分析器會根據語法規則,判斷你輸入的這個SQL語句是否滿足MySQL語法。
C.優化器:經過了分析器,MySQL就知道你要做什么了。在開始執行之前,還要先經過優化器的處理。

1.2 執行器的執行流程

 

D.執行器:MySQL通過分析器知道了你要做什么,通過優化器知道了該怎么做,於是就進入了執行器階段,開始執行語句。

比如我們這個例子中的表T中,ID字段沒有索引,那么執行器的執行流程是這樣的:

  1. 調用InnoDB引擎接口取這個表的第一行,判斷ID值是不是10,如果不是則跳過,如果是則將這行存在結果集中;

  2. 調用引擎接口取“下一行”,重復相同的判斷邏輯,直到取到這個表的最后一行。

  3. 執行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結果集返回給客戶端。 

總結,MySQL包含如下子系統和核心庫:

  1. 網絡連接和網絡通信協議子系統[NET協議建立在TCP/IP協議棧上,為上層其他子系統提供數據包的讀、寫、解析和發送]
  2. 線程、進程和內存分配子系統[自啟動准備過程]
  3. 查詢解析和查詢優化子系統
  4. 存儲引擎接口子系統
  5. 各類存儲接口子系統
  6. 安全管理子系統[驗證和訪問控制等手段來保護服務器]
  7. 日志子系統[Error日志、查詢日志、慢查詢日志、二進制日志]
  8. 其他子系統-如復制功能、錯誤處理
  9. mysys核心庫文件

2、Mysql日志系統

日志系統只要有2個模塊:存儲引擎里的redo log重做日志;服務器-執行器中的binlog歸檔日志。

說到日志系統,需要了解幾個概念:creash-safe、redo log、binlog、WAL技術。

Redo log:用於保證crash-safe能力。innodb_flush_log_at_trx_commit =1表示每次事務的redo log 都持久化到磁盤,保證mysql異常重啟之后數據不丟失。Sync_binlog=1參數設置為1,表示每次事務的binlog都持久化到磁盤,保證mysql異常重啟之后binlog不丟失。

Crash-safe:有了redo log,InnoDB就可以保證即使數據庫發生異常重啟,之前提交的記錄都不會丟失。

WAL技術:Write-Ahead Loggin,先記錄到歸檔日志redo log里面,更新完成。InnoDB引擎在適當的時候,將這個更新記錄更新到(服務器-執行器)磁盤。(閑時)

  PS:歸檔日志大小可以進行配置

2.1 redo log日志與change buffer的區別

redo log:主要節省的是隨機寫磁盤的IO消耗(轉成順序寫)。
change buffer:主要節省的則是隨機讀磁盤的IO消耗。

2.2 場景一:一條SQL更新語句是如何執行的?

前提:創建表 create table T(ID int primary key,c int),插入一條ID=2的語句。

 更新語句不在內存時的操作過程:並不會立馬從磁盤去讀入內存

1、更新數據頁,不在內存,InnoDB會將這些更新操作緩存在change buffer中,減少讀磁盤。
2、merge:將change buffer 中的操作應用到原數據頁,得到最新結果的過程。
3、merge觸發的時間點:關閉數據庫、查詢該數據頁、后台線程定期操作。
4、change buffer:可持久化的數據,可通過參數innodb_change_buffer_max_size 設置占用buffer pool里的內存。
PS:普通索引更新時使用change buffer,唯一索引直接進行更新。

 


免責聲明!

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



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