快速掌握 Innodb:從解析 show engine innodb shatus 開始

在這裏插入圖片描述

一、前言

MySQL 最早由瑞典 MySQL AB 公司開發,該公司由 Monty 在 1995 年創立;MySQL 這個名字來源於 Monty 的大女兒 My。它的成功不僅僅是因爲免費,還有它的可靠性穩定性和一些其它閃亮的特性。而 MySQL 中最核心的組建就是存儲引擎,令人意外的是 Innodb 引擎的發展進程竟然比 MySQL 要早,甚至在時間上遠遠甩開了一些高級編程語言

值得一提的是,MySQL 和 linux 兩大開發源碼的陣營都出自芬蘭人之手,按照採訪 Monty 時他的說法,芬蘭人的本性就是固執和討厭放棄,截止現在 Linus 在 Linux 方面堅持了 30 年,而 Monty 也堅持了 20 年,他們的這種專注和堅持是值得我們學習的。

理解 Innodb 的第一步就是要熟悉 show engine innodb shatus 中輸出結果的含義,今天我們一起來學習它。

二、環境及輸出

  • 操作環境:MySQL 5.7.28
  • 輸出結果:show engine innodb status\G
    在這裏插入圖片描述
  • 上面就是輸出結果,主要包含一些 innodb 引擎中的一些狀態,共有 10 個部分
  1. BACKGROUND THREAD:後臺 Master 線程狀態
  2. SEMAPHORES:等待線程的列表及事件計數器,評估當前負載情況
  3. LATEST DETECTED DEADLOCK:最新的幾次死鎖信息數據(只有發送死鎖時顯示)
  4. latest foreign key error:最近幾次外鍵錯誤信息(只有發生錯誤時顯示)
  5. TRANSACTIONS:innodb 事務統計信息
  6. FILE I/O:顯示的是I/O輔助線程的狀態及性能計數器的狀態
  7. INSERT BUFFER AND ADAPTIVE HASH INDEX:insert buffer pool 和 AHI 狀態
  8. LOG:innodb 事務日誌 Redo 的統計信息
  9. BUFFER POOL AND MEMORY:innodb buffer pool 使用統計信息
  10. ROW OPERATIONS:ROW 操作和其它統計信息

三、內容解析

在這裏插入圖片描述
show engine innodb status 顯示的不是當前實時的狀態,而是過去某個時間範圍的狀態,上圖爲輸出的時間信息表示:查詢信息爲過去的 21 秒內,每兩秒內平均值

在這裏插入圖片描述
介紹:Master 線程三種狀態

  • Master 線程是 innodb 引擎中最重要的線程,主要負責異步刷新數據維護數據一致性處理,有三種工作狀態,每次循環都會根據數據庫狀態選擇其中一種工作狀態。
  • Active 是 Master 線程判斷系統處於忙碌狀態時選擇的工作模式,它的循環數量增加主要與數據變化有關,與查詢無關。
  • Idle是 Master 線程判斷系統處於空閒狀態選擇的工作模式,Idle 與 Active 兩種工作模式做的事情幾乎都一樣,只不過執行時間間隔不同。
  • shutdown 是在關閉實例時纔會選擇的工作模式。

解析:輸出解析

  • 上圖是一臺比較空閒實例運行的結果,可以看到 srv_active 爲 567 而 srv_idle 則爲 1756519 遠遠大於 active 循環次數,所以可以對比兩 active 和 idle 的值來判斷系統的負載情況。
  • 相對的如果實例輸出的結果 srv_idle 遠遠大與 active 則可以認爲系統處於忙碌狀態

在這裏插入圖片描述

  • FILE I/O 主要是關於 innodb 中 IO Thread 線程的相關信息。
  • IO Thread 線程分別爲:Read threadWrite threadInsert buffer threadLog thread 使用的是異步 I/O 模型,處理不同類型的 I/O 請求和回調。
  • 可以通過上圖信息清晰看到 IO Thread 的信息,其中 read threadwrite thread線程分別4 個,Log thread 和 insert buffer thread 線程分別各一個,其中 read 和 write 線程可以根據參數來調整。

在這裏插入圖片描述
BUFFER POOL AND MEMORY 主要是關於 Innodb 的緩存池管理相關數據

  • Total large memory allocated:innodb 分配的總內存 (byte)
  • Dictionary memory allocated:innodb數據字典分配的內存數(byte)
  • Buffer pool size:緩衝池分配的頁數
  • Free buffers:緩衝池空閒頁數
  • Database pages:LRU 列表中分配的數據頁(LRU 是 innodb 管理緩存的算法)
  • Old database pages:LRU 在 old sublist部分頁的數量
  • Modified db pages:buffer pool 中的數據髒頁
  • Pending reads:掛起讀的數量

LRU 算法介紹:數據庫緩存技術中都會使用的算法

  • 算法思想:LRU 的本質是讓數據頁在緩存中長時間保留,提高查詢訪問效率,但是緩存是有限的,LRU 的作用就是減少重複數據頁加載頻率
  • 算法解析:LRU 是 innodb 中的一種定製化算法,首先它會有一個列表,叫 LRU LIST 上面存放一些數據頁,這個列表就是 Database pages 上圖是 6885 個數據頁 大約 1MB innodb 在 LRU 列表中加入了參考點,叫midpoint 當訪問到的數據頁不在緩衝區會直接將磁盤中的數據頁調到緩衝區隊列;innodb 不是將數據頁直接插入到緩衝區隊列隊頭,而是插入 LRU 列表的 midpoint 位置。默認配置 midpoint 是在整個列表長度的5/8 處,和數學中的黃金分割 0.618 很接近,midpoint 是由innodb_old_blocks_pct控制。LRU LIST在 midpoint 之前的列表稱爲 young sublist 或者sublist of new block 裏面的數據是熱數據,而LRU LISTmidpoint之後的列表稱爲 old sublist或者sublist of old block
    在這裏插入圖片描述
  • 算法過程:當緩衝池不能存放新讀取到的頁時,將首先釋放 LRU 列表中尾端的頁。當一些全表掃描如果進入 sublist of new block 區域,整個 LRU 就會是性能瓶頸,這種情況叫緩存污染。爲了解決這種問題,innodb 加入了 innodb_old_blocks_time 來表示數據頁讀取到 mid 位置後需要等待多久纔會進入 LRU 列表的熱端,默認爲1000 毫秒,可以設置此參數保證熱點數據不會被輕易刷出。

在這裏插入圖片描述
Innodb 引擎日誌管理

  • 上圖主要展示的是關於 innodb 日誌相關,所以我們需要了解 innodb 引擎中日誌的作用,主要有兩種類型的日誌 redo log 重做日誌和 undo log 回滾日誌,分別存儲在 ib_logfile 和 ibdata 文件中
  • LSN 介紹:redo 日誌的作用是爲了維護事務的持久性故障自動恢復,都會基於 LSN 日誌序列號,LSN 是一個一直遞增的整型數字(8 個字節),表示事務寫入到日誌的字節總量,每個數據頁和重做日誌及 checkpoint 都有 LSN。
  • checkpoint:innodb 的刷盤機制,可以將 buffer pool 中的數據髒頁刷寫到磁盤
  • redo 日誌工作機制:上面已經提過 redo 日誌主要維護事務的持久化存儲,我們現在認識 LSNcheckpoint 後仔細討論,當執行一條 DML 語句時 innodb 會將硬盤中需要改動的數據頁加載到 buffer pool 正常邏輯是在內存中修改完成後再刷到磁盤中,但是這樣有風險如果此時宕機 buffer pool 中沒有刷寫到到數據就會失效,所以 innodb 會先將改動數據記錄加載到 redo buffer pool 中然後再由它快速刷寫到 redo 的物理存儲空間中,此時如果宕機那麼原數據+改動數據記錄就可以恢復宕機前的狀態,這個恢復過程就是故障自動恢復機制,MySQL 在啓動時會對比數據和 ib_logfile 中到 LSN 編號,如果不一樣則認爲數據不一致,啓動自動故障恢復機制恢復數據後纔會啓動成功。
  • undo 日誌工作機制:undo 日誌主要維護的事務的原子性,事務執行過程會將事務的反操作記錄到 undo物理空間中,默認在 ibdata 共享文件中,但是 ibdata 太過龐大 5.7 版本後可以通過 innodb_undo_tablespaces 指定需要匹配幾個 undo 文件。

LOG 數據解析:

  • Log sequence number:LSN1 當前系統 LSN 最大值,新的事務日誌將在原日誌基礎上生成(LSN1 + 新日誌的大小)
  • Log flushed up to:LSN2 當前已經寫入日誌文件的 LSN
  • Pages flushed up to:LSN3 當前最舊的數據髒頁對應的 LSN 執行 checkpoint 時可以直接將此 LSN 寫入到日誌文件。
  • Last checkpoint at:LSN4 當前已經被 checkpoint 寫入的 LSN

在這裏插入圖片描述

  • 主要是等待線程的列表及事件計數器和一些的情況,可以評估系統的負載情況
  • 目前這部分相對來說用的比較少,網絡上的資料比較模糊,詳細描述後補。

在這裏插入圖片描述

  • 死鎖一般是事務相互等待對方資源,最後形成環路造成的。出現死鎖 MySQL 也會檢測到,然後通過回滾事務解決。發生死鎖會增加系統負擔,MySQL 錯誤日誌也會記錄死鎖問題,查詢到根源然後解決和避免死鎖問題。當然也可以通過上圖發現和結果最近的幾次死鎖問題。除了死鎖系統還有外鍵錯誤記錄。

三、總結

  • 上面我們介紹 innodb 體系結構中比較重要的指標,從show engine innodb shatus 的結果就可以看出 innodb 引擎的一個大體結構,四個線程、buffer pool、redo 和 undo、鎖機制和相關特性,當然這只是冰山一角,要想真正理解 innodb 還需要多花點時間
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章