學習筆記 | 01 MySQL 體系結構與存儲引擎

課程內容

  • MySQL 數據庫的體系結構
  • MySQL 支持的存儲引擎
  • InnoDB 能夠取代 MyISAM 的原因和 InnoDB 幾大核心特性
  • InnoDB 存儲的原理和特點
  • MySQL 5.6 版本爲例介紹 MySQL 體系的結構組成
  • MySQL 5.7 版本和 MySQL 8.0 版本做了哪些優化和改進
    在這裏插入圖片描述

01 MySQL 數據庫的體系結構

在這裏插入圖片描述
MySQL 體系結構由 Client Connectors 層、MySQL Server 層及存儲引擎層組成。

Client Connectors 層
  • 負責處理客戶端的連接請求,與客戶端創建連接。目前 MySQL 幾乎支持所有的連接類型,例如常見的 JDBC、Python、Go 等。
MySQL Server 層
  • MySQL Server 層主要包括 Connection Pool、Service & utilities、SQL interface、Parser解析器、Optimizer 查詢優化器、Caches 緩存等模塊。
  • Connection Pool,負責處理和存儲數據庫與客戶端創建的連接,一個線程負責管理一個連接。Connection Pool 包括了用戶認證模塊,就是用戶登錄身份的認證和鑑權及安全管理,也就是用戶執行操作權限校驗。
  • Service & utilities 是管理服務&工具集,包括備份恢復、安全管理、集羣管理服務和工具。
  • SQL interface,負責接收客戶端發送的各種 SQL 語句,比如 DML、DDL 和存儲過程等。
  • Parser 解析器會對 SQL 語句進行語法解析生成解析樹
  • Optimizer 查詢優化器會根據解析樹生成執行計劃,並選擇合適的索引,然後按照執行計劃執行 SQL 語言並與各個存儲引擎交互。
  • Caches 緩存包括各個存儲引擎的緩存部分,比如:InnoDB 存儲的 Buffer Pool、MyISAM 存儲引擎的 key buffer 等,Caches 中也會緩存一些權限,也包括一些 Session 級別的緩存。
存儲引擎層
  • 存儲引擎包括 MyISAM、InnoDB,以及支持歸檔的 Archive 和內存的 Memory 等。MySQL是插件式的存儲引擎,只要正確定義與 MySQL Server 交互的接口,任何引擎都可以訪問MySQL,這也是 MySQL 流行的原因之一。
  • 存儲引擎底部是物理存儲層,是文件的物理存儲層,包括二進制日誌、數據文件、錯誤日誌、慢查詢日誌、全日誌、redo/undo 日誌等。
一條 SQL SELECT 語句的執行軌跡來說明客戶端與 MySQL 的交互過程

在這裏插入圖片描述
① 通過客戶端/服務器通信協議與 MySQL 建立連接。
② 查詢緩存,這是 MySQL 的一個可優化查詢的地方,如果開啓了 Query Cache 且在查詢緩存過程中查詢到完全相同的 SQL 語句,則將查詢結果直接返回給客戶端;如果沒有開啓Query Cache 或者沒有查詢到完全相同的 SQL 語句則會由解析器進行語法語義解析,並生成解析樹。
③ 預處理器生成新的解析樹。
④ 查詢優化器生成執行計劃。
⑤ 查詢執行引擎執行 SQL 語句,此時查詢執行引擎會根據 SQL 語句中表的存儲引擎類型,以及對應的 API 接口與底層存儲引擎緩存或者物理文件的交互情況,得到查詢結果,由MySQL Server 過濾後將查詢結果緩存並返回給客戶端。若開啓了 Query Cache,這時也會將SQL 語句和結果完整地保存到 Query Cache 中,以後若有相同的 SQL 語句執行則直接返回結果。

02 存儲引擎概述

  • 存儲引擎是 MySQL 中具體與文件打交道的子系統,它是根據 MySQL AB 公司提供的文件訪問層抽象接口定製的一種文件訪問機制,這種機制就叫作存儲引擎,下面是一些常用的存儲引擎,有遠古時期的 MyISAM、支持事務的 InnoDB、內存類型的 Memory、歸檔類型的 Archive、列式存儲的 Infobright,以及一些新興的存儲引擎,以 RocksDB 爲底層基礎的 MyRocks 和 RocksDB,和以分形樹索引組織存儲的 TokuDB,當然現在還有極數雲舟出品的分佈式存儲引擎 ArkDB,如下圖所示。
    在這裏插入圖片描述
  • 在 MySQL 5.6 版本之前,默認的存儲引擎都是 MyISAM,但 5.6 版本以後默認的存儲引擎就是 InnoDB 了。
  • InnoDB 存儲引擎的具體架構如下圖所示。上半部分是實例層(計算層),位於內存中,下半部分是物理層,位於文件系統中。
    在這裏插入圖片描述
實例層
  • 實例層分爲線程和內存。InnoDB 重要的線程有 Master Thread,Master Thread 是 InnoDB 的主線程,負責調度其他各線程。
  • Master Thread 的優先級最高, 其內部包含幾個循環:主循環(loop)、後臺循環(background loop)、刷新循環(flush loop)、暫停循環(suspend loop)。
  • Master Thread 會根據其內部運行的相關狀態在各循環間進行切換。

大部分操作在主循環(loop)中完成,其包含 1s 和 10s 兩種操作。

1s 操作主要包括如下:
  • 日誌緩衝刷新到磁盤(這個操作總是被執行,即使事務還沒有提交)。
  • 最多可能刷 100 個新髒頁到磁盤。
  • 執行並改變緩衝的操作。
  • 若當前沒有用戶活動,可能切換到後臺循環(background loop)等。
10s 操作主要包括如下:
  • 最多可能刷新 100 個髒頁到磁盤。
  • 合併至多 5 個被改變的緩衝(總是)。
  • 日誌緩衝刷新到磁盤(總是)。
  • 刪除無用的 Undo 頁(總是)。
  • 刷新 100 個或者 10 個髒頁到磁盤(總是)產生一個檢查點(總是)等。
  • buf_dump_thread 負責將 buffer pool 中的內容 dump 到物理文件中,以便再次啓動 MySQL 時,可以快速加熱數據。
  • page_cleaner_thread 負責將 buffer pool 中的髒頁刷新到磁盤,在 5.6 版本之前沒有這個線程,刷新操作都是由主線程完成的,所以在刷新髒頁時會非常影響 MySQL 的處理能力,在5.7 版本之後可以通過參數設置開啓多個 page_cleaner_thread。
  • purge_thread 負責將不再使用的 Undo 日誌進行回收。
  • read_thread 處理用戶的讀請求,並負責將數據頁從磁盤上讀取出來,可以通過參數設置線程數量。
  • write_thread 負責將數據頁從緩衝區寫入磁盤,也可以通過參數設置線程數量,page_cleaner 線程發起刷髒頁操作後 write_thread 就開始工作了。
  • redo_log_thread 負責把日誌緩衝中的內容刷新到 Redo log 文件中。
  • insert_buffer_thread 負責把 Insert Buffer 中的內容刷新到磁盤。實例層的內存部分主要包含 InnoDB Buffer Pool,這裏包含 InnoDB 最重要的緩存內容。數據和索引頁、undo 頁、insert buffer 頁、自適應 Hash 索引頁、數據字典頁和鎖信息等。additional memory pool 後續已不再使用。Redo buffer 裏存儲數據修改所產生的 Redo log。double write buffer 是 double write 所需的 buffer,主要解決由於宕機引起的物理寫入操作中斷,數據頁不完整的問題。
物理層

物理層在邏輯上分爲系統表空間、用戶表空間和 Redo日誌

  • 系統表空間裏有 ibdata 文件和一些 Undo,ibdata 文件裏有 insert buffer 段、double write段、回滾段、索引段、數據字典段和 Undo 信息段
  • 用戶表空間是指以 .ibd 爲後綴的文件,文件中包含 insert buffer 的 bitmap 頁、葉子頁(這裏存儲真正的用戶數據)、非葉子頁。InnoDB 表是索引組織表,採用 B+ 樹組織存儲,數據都存儲在葉子節點中,分支節點(即非葉子頁)存儲索引分支查找的數據值。
  • Redo 日誌中包括多個 Redo 文件,這些文件循環使用,當達到一定存儲閾值時會觸發checkpoint 刷髒頁操作,同時也會在 MySQL 實例異常宕機後重啓,InnoDB 表數據自動還原恢復過程中使用。
內存和物理結構

在這裏插入圖片描述
用戶讀取或者寫入的最新數據都存儲在 Buffer Pool 中,如果 Buffer Pool 中沒有找到則會讀取物理文件進行查找,之後存儲到 Buffer Pool 中並返回給 MySQL Server。Buffer Pool 採用LRU 機制,具體的內存隊列和刷新機制建議你課後學習瞭解下,這裏不詳細講述。

Buffer Pool 決定了一個 SQL 執行的速度快慢,如果查詢結果頁都在內存中則返回結果速度很快,否則會產生物理讀(磁盤讀),返回結果時間變長,性能遠不如存儲在內存中。但我們又不能將所有數據頁都存儲到 Buffer Pool 中,比如物理 ibd 文件有 500GB,我們的機器不可能配置能容得下 500GB 數據頁的內存,因爲這樣做成本很高而且也沒必要。在單機單實例情況下,我們可以配置 Buffer Pool 爲物理內存的 60%~80%,剩餘內存用於 session 產生的 sort 和 join 等,以及運維管理使用。如果是單機多實例,所有實例的buffer pool總量也不要超過物理內存的80%。開始時我們可以根據經驗設置一個 Buffer Pool 的經驗值,比如 16GB,之後業務在 MySQL 運行一段時間後可以根據 show global status like ‘%buffer_pool_wait%’ 的值來看是否需要調整 Buffer Pool 的大小。

Redo log 是一個循環複用的文件集,負責記錄 InnoDB 中所有對 Buffer Pool的物理修改日誌,當 Redo log文件空間中,檢查點位置的 LSN 和最新寫入的 LSN 差值(checkpoint_age)達到 Redo log 文件總空間的 75% 後,InnoDB 會進行異步刷新操作,直到降至 75% 以下,並釋放 Redo log 的空間;當 checkpoint_age 達到文件總量大小的 90% 後,會觸發同步刷新,此時 InnoDB 處於掛起狀態無法操作。

這樣我們就看到 Redo log 的大小直接影響了數據庫的處理能力,如果設置太小會導致強行 checkpoint 操作頻繁刷新髒頁,那我們就需要將 Redo log 設置的大一些,5.6 版本之前 Redo log 總大小不能超過 3.8GB,5.7 版本之後放開了這個限制。那既然太小影響性能,是不是設置得越大越好呢,這個問題留給你課後自己思考。

事務提交時 log buffer 會刷新到 Redo log 文件中,具體刷新機制由參數控制,你可以課後學習並根據自身業務特點進行配置。

若參數 innodb_file_per_table=ON,則表示用戶建表時採用用戶獨立表空間,即一個表對應一組物理文件,.frm 表定義文件和 .ibd 表數據文件。

當然若這個參數設置爲 OFF,則表示用戶建表存儲在 ibdata 文件中,不建議採用共享表空間,這樣會導致 ibdata 文件過大,而且當表刪除後空間無法回收。獨立表空間可以在用戶刪除大量數據後回收物理空間,執行一個 DDL 就可以將表空間的高水位降下來了。

03 新版本特性

MySQL 5.7 版本新特性如下:

  • 將 Undo 從共享表空間 ibdata 文件中分離出來,可以在安裝 MySQL 時由用戶自行指定文件大小和數量。
  • 增加了 temporary 臨時表空間,裏面存儲着臨時表或臨時查詢結果集的數據。
  • Buffer Pool 大小可以動態修改,無需重啓數據庫實例,這是 DBA 的福音。

MySQL 8.0 版本新特性如下:

  • 將 InnoDB 表的數據字典和 Undo 都從共享表空間 ibdata 中徹底分離出來了,以前需要ibdata 文件中數據字典與獨立表空間 ibd 文件中數據字典一致纔行,8.0 版本就不需要了。
  • temporary 臨時表空間也可以配置多個物理文件,而且均爲 InnoDB 存儲引擎並能創建索引,這樣加快了處理的速度。
  • 用戶可以像 Oracle 數據庫那樣設置一些表空間,每個表空間對應多個物理文件,每個表空間可以給多個表使用,但一個表只能存儲在一個表空間中。

04 InnoDB 和 MyISAM對比

在這裏插入圖片描述
在這裏插入圖片描述

  • InnoDB 支持 ACID 的事務 4 個特性,而 MyISAM 不支持;
  • InnoDB 支持 4 種事務隔離級別,默認是可重複讀 Repeatable Read 的,MyISAM 不支持;
  • InnoDB 支持 crash 安全恢復,MyISAM 不支持;
  • InnoDB 支持外鍵,MyISAM 不支持;
  • InnoDB 支持行級別的鎖粒度,MyISAM 不支持,只支持表級別的鎖粒度;
  • InnoDB 支持 MVCC,MyISAM 不支持;
  • InnoDB 表最大還可以支持 64TB,支持聚簇索引、支持壓縮數據存儲,支持數據加密,支持查詢/索引/數據高速緩存,支持自適應hash索引、空間索引,支持熱備份和恢復等,如下圖所示。
    在這裏插入圖片描述

性能對比

在這裏插入圖片描述

  • 讀寫混合模式下,隨着 CPU 核數的增加,InnoDB 的讀寫能力呈線性增長,
  • 在測試用例裏,最高可達近 9000 的 TPS,但 MyISAM 因爲讀寫不能併發,它的處理能力跟核數沒關係,呈一條水平線,TPS 低於 500。
  • 只讀模式下,隨着 CPU 核數的增加,InnoDB 的讀寫能力呈線性增長,最高可達近 14000 的 TPS,但 MyISAM 的處理能力不到 3000 TPS。

以上測試僅爲說明 InnoDB 比 MyISAM 的處理能力強大,具體 TPS 測試數據跟硬件和測試條件不同而有很大差異。

05 InnoDB 存儲引擎——核心特性

  • InnoDB 存儲引擎的核心特性包括:MVCC、鎖、鎖算法和分類、事務、表空間和數據頁、內存線程以及狀態查詢
    在這裏插入圖片描述

show engine innodb status\G 的結果裏面有詳細的 InnoDB 運行態信息,分段記錄的,包括內存、線程、信號、鎖、事務等,請你多多使用,出現問題時從中能分析出具體原因和解決方案。

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