MySQL InnoDB儲存引擎體系結構

lhrbest發表於2020-12-15

MySQL InnoDB儲存引擎體系結構



1. 結構圖

從MySQL 5.5版本開始預設使用InnoDB作為引擎,它擅長處理事務,具有自動崩潰恢復的特性,在日常開發中使用非常廣泛。下面是官方的InnoDB引擎架構圖,主要分為記憶體結構和磁碟結構兩大部分。

在這裡插入圖片描述

2. InnoDB記憶體結構

記憶體結構主要包括Buffer Pool、Change Buffer、Adaptive Hash Index和Log Buffer四大元件。

2.1 Buffer Pool

緩衝池,簡稱BP。BP以Page頁為單位,預設大小16K,BP的底層採用連結串列數 據結構管理Page。在InnoDB訪問表記錄和索引時會在Page頁中快取,以後使用可以減少磁 盤IO操作,提升效率。

  1. Page管理機制 Page根據狀態可以分為三種型別:
  1. free page : 空閒page,未被使用
  2. clean page:被使用page,資料沒有被修改過
  3. dirty page:髒頁,被使用page,資料被修改過,頁中資料和磁碟的資料產生了不 一致

針對上述三種page型別,InnoDB通過三種連結串列結構來維護和管理

  1. free list :表示空閒緩衝區,管理free page
  2. flush list:表示需要重新整理到磁碟的緩衝區,管理dirty page,內部page按修改時間 排序。髒頁即存在於flush連結串列,也在LRU連結串列中,但是兩種互不影響,LRU連結串列負 責管理page的可用性和釋放,而flush連結串列負責管理髒頁的刷盤操作。
  3. lru list:表示正在使用的緩衝區,管理clean page和dirty page,緩衝區以 midpoint為基點,前面連結串列稱為new列表區,存放經常訪問的資料,佔63%;後 面的連結串列稱為old列表區,存放使用較少資料,佔37%。
  • 改進型LRU演算法維護

普通LRU:末尾淘汰法,新資料從連結串列頭部加入,釋放空間時從末尾淘汰
改性LRU:連結串列分為new和old兩個部分,加入元素時並不是從表頭插入,而是從中間 midpoint位置插入,如果資料很快被訪問,那麼page就會向new列表頭部移動,如果 資料沒有被訪問,會逐步向old尾部移動,等待淘汰。
每當有新的page資料讀取到buffer pool時,InnoDb引擎會判斷是否有空閒頁,是否足 夠,如果有就將free page從free list列表刪除,放入到LRU列表中。沒有空閒頁,就會 根據LRU演算法淘汰LRU連結串列預設的頁,將記憶體空間釋放分配給新的頁。

  • Buffer Pool配置引數

show variables like ‘%innodb_page_size%’; //檢視page頁大小
show variables like ‘%innodb_old%’; //檢視lru list中old列表引數
show variables like ‘%innodb_buffer%’; //檢視buffer pool引數

建議:將innodb_buffer_pool_size設定為總記憶體大小的60%-80%, innodb_buffer_pool_instances可以設定為多個,這樣可以避免快取爭奪。

2.2 Change Buffer:

寫緩衝區,簡稱CB。在進行DML操作時,如果BP沒有其相應的Page資料, 並不會立刻將磁碟頁載入到緩衝池,而是在CB記錄緩衝變更,等未來資料被讀取時,再將數 據合併恢復到BP中。

  • ChangeBuffer佔用BufferPool空間,預設佔25%,最大允許佔50%,可以根據讀寫業務量來進行調整。引數innodb_change_buffer_max_size;

  • 當更新一條記錄時,該記錄在BufferPool存在,直接在BufferPool修改,一次記憶體操作。如果該記錄在BufferPool不存在(沒有命中),會直接在ChangeBuffer進行一次記憶體操作,不用再去磁碟查詢資料,避免一次磁碟IO。當下次查詢記錄時,會先進性磁碟讀取,然後再從 ChangeBuffer中讀取資訊合併,最終載入BufferPool中。

  • 寫緩衝區,僅適用於非唯一普通索引頁,為什麼?
    如果在索引設定唯一性,在進行修改時,InnoDB必須要做唯一性校驗,因此必須查詢磁碟, 做一次IO操作。會直接將記錄查詢到BufferPool中,然後在緩衝池修改,不會在 ChangeBuffer操作。

2.3 Adaptive Hash Index

自適應雜湊索引用於優化對BP資料的查詢。InnoDB儲存引擎會監 控對錶索引的查詢,如果觀察到建立雜湊索引可以帶來速度的提升,則建立雜湊索引,所以 稱之為自適應。InnoDB儲存引擎會自動根據訪問的頻率和模式來為某些頁建立雜湊索引。

2.4 LogBuffer

日誌緩衝區,用來儲存要寫入磁碟上log檔案(Redo/Undo)的資料,日誌緩衝 區的內容定期重新整理到磁碟log檔案中。日誌緩衝區滿時會自動將其重新整理到磁碟,當遇到BLOB 或多行更新的大事務操作時,增加日誌緩衝區可以節省磁碟I/O。

  • LogBuffer主要是用於記錄InnoDB引擎日誌,在DML操作時會產生Redo和Undo日誌。 LogBuffer空間滿了,會自動寫入磁碟。可以通過將innodb_log_buffer_size引數調大,減少磁碟IO頻率
  • innodb_flush_log_at_trx_commit引數控制日誌重新整理行為,預設為1

0 : 每隔1秒寫日誌檔案和刷盤操作(寫日誌檔案LogBuffer–>OS cache,刷盤OS cache–>磁碟檔案),最多丟失1秒資料
1:事務提交,立刻寫日誌檔案和刷盤,資料不丟失,但是會頻繁IO操作
2:事務提交,立刻寫日誌檔案,每隔1秒鐘進行刷盤操作

3. InnoDB磁碟結構

InnoDB磁碟主要包含Tablespaces,InnoDB Data Dictionary,Doublewrite Buffer、Redo Log和Undo Logs。

3.1表空間(Tablespaces)

用於儲存表結構和資料。表空間又分為系統表空間、獨立表空間、通用表空間、臨時表空間、Undo表空間等多種型別;

  1. 系統表空間(The System Tablespace)
    包含InnoDB資料字典,Doublewrite Buffer,Change Buffer,Undo Logs的儲存區 域。系統表空間也預設包含任何使用者在系統表空間建立的表資料和索引資料。系統表空 間是一個共享的表空間因為它是被多個表共享的。該空間的資料檔案通過引數 innodb_data_file_path控制,預設值是ibdata1:12M:autoextend(檔名為ibdata1、 12MB、自動擴充套件)。

  2. 獨立表空間(File-Per-Table Tablespaces)
    預設開啟,獨立表空間是一個單表表空間,該表建立於自己的資料檔案中,而非建立於 系統表空間中。當innodb_file_per_table選項開啟時,表將被建立於表空間中。否則, innodb將被建立於系統表空間中。每個表檔案表空間由一個.ibd資料檔案代表,該檔案 預設被建立於資料庫目錄中。表空間的表檔案支援動態(dynamic)和壓縮 (commpressed)行格式。

  3. 通用表空間(General Tablespaces)
    通用表空間為通過create tablespace語法建立的共享表空間。通用表空間可以建立於mysql資料目錄外的其他表空間,其可以容納多張表,且其支援所有的行格式。
    CREATE TABLESPACE ts1 ADD DATAFILE ts1.ibd Engine=InnoDB; //建立表空 間ts1
    CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1; //將表新增到ts1 表空間

  4. 撤銷表空間(Undo Tablespaces)
    撤銷表空間由一個或多個包含Undo日誌檔案組成。在MySQL 5.7版本之前Undo佔用的 是System Tablespace共享區,從5.7開始將Undo從System Tablespace分離了出來。 InnoDB使用的undo表空間由innodb_undo_tablespaces配置選項控制,預設為0。參 數值為0表示使用系統表空間ibdata1;大於0表示使用undo表空間undo_001、 undo_002等。

  5. 臨時表空間(Temporary Tablespaces)
    分為session temporary tablespaces 和global temporary tablespace兩種。session temporary tablespaces 儲存的是使用者建立的臨時表和磁碟內部的臨時表。global temporary tablespace儲存使用者臨時表的回滾段(rollback segments )。mysql服務 器正常關閉或異常終止時,臨時表空間將被移除,每次啟動時會被重新建立。

3.2資料字典(InnoDB Data Dictionary)

InnoDB資料字典由內部系統表組成,這些表包含用於查詢表、索引和表欄位等物件的元數 據。後設資料物理上位於InnoDB系統表空間中。由於歷史原因,資料字典後設資料在一定程度上 與InnoDB表後設資料檔案(.frm檔案)中儲存的資訊重疊。

3.3 雙寫緩衝區(Doublewrite Buffer)

位於系統表空間,是一個儲存區域。在BufferPage的page頁重新整理到磁碟真正的位置前,會先 將資料存在Doublewrite 緩衝區。如果在page頁寫入過程中出現作業系統、儲存子系統或 mysqld程式崩潰,InnoDB可以在崩潰恢復期間從Doublewrite 緩衝區中找到頁面的一個好 備份。在大多數情況下,預設情況下啟用雙寫緩衝區,要禁用Doublewrite 緩衝區,可以將 innodb_doublewrite設定為0。使用Doublewrite 緩衝區時建議將innodb_flush_method設 置為O_DIRECT。
MySQL的innodb_flush_method這個引數控制著innodb資料檔案及redo log的開啟、 刷寫模式。有三個值:fdatasync(預設),O_DSYNC,O_DIRECT。設定O_DIRECT表示 資料檔案寫入操作會通知作業系統不要快取資料,也不要用預讀,直接從Innodb Buffer寫到磁碟檔案。
預設的fdatasync意思是先寫入作業系統快取,然後再呼叫fsync()函式去非同步刷資料文 件與redo log的快取資訊。

3.4. 重做日誌(Redo Log)

重做日誌是一種基於磁碟的資料結構,用於在崩潰恢復期間更正不完整事務寫入的資料。 MySQL以迴圈方式寫入重做日誌檔案,記錄InnoDB中所有對Buffer Pool修改的日誌。當出 現例項故障(像斷電),導致資料未能更新到資料檔案,則資料庫重啟時須redo,重新把數 據更新到資料檔案。讀寫事務在執行的過程中,都會不斷的產生redo log。預設情況下,重 做日誌在磁碟上由兩個名為ib_logfile0和ib_logfile1的檔案物理表示。

3.5 撤銷日誌(Undo Logs)

撤消日誌是在事務開始之前儲存的被修改資料的備份,用於例外情況時回滾事務。撤消日誌 屬於邏輯日誌,根據每行記錄進行記錄。撤消日誌存在於系統表空間、撤消表空間和臨時表 空間中。

4. 新版本結構演變

在這裡插入圖片描述

MySQL 5.7 版本

  • 將Undo日誌表空間從共享表空間ibdata檔案中分離出來,可以在安裝MySQL時由使用者自行指定檔案大小和數量。
  • 增加了 temporary 臨時表空間,裡面儲存著臨時表或臨時查詢結果集的資料。
  • Buffer Pool 大小可以動態修改,無需重啟資料庫例項。

MySQL 8.0 版本

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




About Me

........................................................................................................................

● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除

● 本文在個人微 信公眾號( DB寶)上有同步更新

● QQ群號: 230161599 、618766405,微信群私聊

● 個人QQ號(646634621),微 訊號(db_bao),註明新增緣由

● 於 2020年12月完成

● 最新修改時間:2020年12月

● 版權所有,歡迎分享本文,轉載請保留出處

........................................................................................................................

小麥苗的微店https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

● 小麥苗出版的資料庫類叢書: http://blog.itpub.net/26736162/viewspace-2142121/

小麥苗OCP、OCM、高可用、MySQL、DBA學習班http://blog.itpub.net/26736162/viewspace-2148098/

● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/

........................................................................................................................

請掃描下面的二維碼來關注小麥苗的微 信公眾號( DB寶)及QQ群(230161599、618766405)、新增小麥苗微 信(db_bao), 學習最實用的資料庫技術。

........................................................................................................................

 

 



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2742544/,如需轉載,請註明出處,否則將追究法律責任。

相關文章