MYSQL(01)-模塊介紹

整體框架

MySQL 可以分為 Server 層和存儲引擎層(Storage Engines)兩部分

Server 層

Server 層包括連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等,涵蓋了Mysql的大多數核心服務功能,以及內置函數,存儲過程,觸發(fā)器,試圖等(所有的跨存儲以前寧的操作)

Storage Engines層

主要是負責數據的存儲和提取,其架構模式是插件式的,支持InnoDB,MyISAM,Memory等多個存儲引擎。InnoDB是最常用的,也是Mysql5.5.5版本開始成為默認的存儲引擎

連接器

  • 負責維護客戶端的鏈接,獲取權限,管理鏈接
  • 如果你沒有后續(xù)的動作,這個連接就處于空閑狀態(tài)(show processlist查看所有鏈接)
  • 客戶端如果太長時間沒動靜,連接器就會自動將它斷開。這個時間是wait_timeout來控制的,默認8小時
  • 短鏈接:每次完成執(zhí)行都斷開鏈接(建立鏈接的過程比較耗時,建議盡量使用長鏈接)
  • 長連接:客戶端維持請求一直使用一個鏈接(但是全部使用長鏈接會導致內存使用過快)
  • 解決長鏈接內存過大的問題:Mysql5.7之后,可以每次執(zhí)行一個較大的操作后,執(zhí)行mysql_reset_connection開重新初始化鏈接資源,此過程無需重連和權限校驗

查詢緩存

MYSQL查詢一個請求會先看查詢緩存是否存在,之前執(zhí)行過的緩存會已KV的形式存儲在內存中,如果有則直接返回,但是默認建議不開啟查詢緩存,因為查詢緩存失效頻率太高,只要對一個表進行更新,那么這個表上所有的查詢緩存都會被清空。mysql8.0已經將查詢緩存整個刪除了

分析器

分析器分析SQL語句進行語法分析,如果判斷語法不對則會返回"You have an error in your SQL syntax" 的錯誤提醒

優(yōu)化器

在經過分析器判斷語法正確后,需要通過優(yōu)化器進行優(yōu)化處理,優(yōu)化器是在表中存在多個索引的時候,決定使用哪個索引,或者在一個語句有多表關聯查詢(join)的時候決定表的鏈接順序

執(zhí)行器

用于語句執(zhí)行

  • 先判斷你有沒有這個表的執(zhí)行查詢的權限,沒有返回權限錯誤的信息
  • 根據引擎提供額執(zhí)行接口執(zhí)行語句查詢
常用引擎,區(qū)別對比
引擎 Innodb Myisam
存儲文件 .frm 表定義文件
.ibd 數據文件
.frm 表定義文件
.myd 數據文件
.myi索引文件
鎖表 表鎖、行鎖 表鎖
事物 ACID 不支持
CRUD 讀、寫 讀多
count 掃表 專門存儲的地方
索引結構 B+Tree(聚集索引) B+Tree(非聚集索引)
版本默認 5.7版本之后的默認引擎 5.7版本之前的默認引擎

一條查詢語句是如何執(zhí)行的

上述MYSQL各個模塊的順序就是一條查詢語句的執(zhí)行順序

  1. 連接器創(chuàng)建客戶端與服務器之間的鏈接
  2. 首先查詢是否有查詢緩存如果有則直接使用
  3. 如果沒有查詢緩存則到達分析器進行SQL語句的語法分析
  4. 確認語法無誤之后,通過優(yōu)化器進行查詢優(yōu)化
    5.最終通過執(zhí)行器調用引擎執(zhí)行查詢

一條更新語句是如何執(zhí)行的

1.將ID為2的一條數據+1

  1. 執(zhí)行器查詢ID = 2的之一行,ID是逐漸,引擎使用B樹搜索找到這一行,如果ID=2這一行數據在內存中(change buffer中),則直接返回給執(zhí)行器,否則需要從磁盤讀取到內存中。
  2. 執(zhí)行器拿到行數據進行+1操作。再調用引擎寫入新數據
  3. 引擎將這行數據更新到內存中,同時將這個數據記錄到redo log中,此時redo log 處于prepare狀態(tài)。然后告知執(zhí)行器完成,隨時可以提交數據
    5.執(zhí)行器生成操作的binlog,并把binlog寫入磁盤
    6.執(zhí)行器調用引擎的提交事務接口,引擎把剛剛寫入的redo log改成提交狀態(tài)更新完成

過程中涉及到的幾個角色,主要是涉及到redo log(重做日志)和 binlog(歸檔日志)這兩個模塊

redo log

如果每一次的更新操作都需要寫進磁盤,然后磁盤也要找到對應的那條記錄,然后更新,整個過程IO成本過高,為了解決上述問題,可以通過WAL技術來實現(Write-Ahead Logging),原理是,當有一條更新記錄的時候,innodb先將操作記錄到redo log中,并更新內存change buffer ,這個時候更新就完成了,然后Innodb會在是到的時候將操作記錄更新到磁盤中,往往是系統比較空閑,或者change buffer 寫滿,或者redo log寫滿的時候

  • redo log 是[固定大小的,一組四個文件,每個文件1G大小
  • 有了redo log,innodb可以保證數據庫異常數據也不丟失,保證了數據的原子性

binlog

上述說的redo log是innodb引擎特有的,而binlog則是Server層自己的日志,又稱歸檔日志。為什么有兩個日志,因為MYSQL之前沒有innodb引擎。而且binlog只用于歸檔。他們有一下不同

  • redo log是innodb特有的,而binlog是mysql的server層實現的,所有引擎都可以使用
  • redo log 是物理日志,記錄數據也上做了什么修改 ,binlog是邏輯日志,記錄這個語句的原始邏輯"比如給ID=2 這一行的c字段加一"
  • redo log 是循環(huán)寫的,空間固定用完會刷新到磁盤,而binlog是最追加寫入的
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容