一、InnoDB 體系架構

InnoDB 存盤引擎有多個記憶體塊,可以認為這些記憶體塊組成了一個大的記憶體池,負責如下作業:
- 維護所有行程/執行緒需要訪問的多個內部資料結構,
- 快取磁盤上的資料,方便快速的讀取,同時對磁盤檔案的資料修改之前在這里進行快取,
- 重做日志(redo log)緩沖,
后臺執行緒的主要作用是負責重繪記憶體池中的資料,保證緩沖池中的記憶體快取的是最近的資料,同時將已修改的資料檔案重繪到磁盤檔案,同時保證在資料庫發生例外的情況下 InnoDB 能恢復到正常運行狀態,
通過 SHOW ENGINE INNODB STATUS 可以觀察到 INNODB 存盤引擎的運行情況,
SHOW ENGINE INNODB STATUS
二、記憶體池

緩沖池簡單來說就是一塊記憶體區域,通過記憶體的速度來彌補磁盤速度較慢對資料庫性能的影響,緩沖池的大小直接影響著資料庫的整體性能,可以通過配置引數 innodb_buffer_pool_size 來設定,
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'
并且 InnoDB 允許有多個快取池實體,每個 PAGE 根據哈希值平均分配到不同緩沖池實體中,這樣做的好處是減少資料庫內部的資源競爭,增加資料庫的并發處理能力,可以通過配置引數 innodb_buffer_pool_instances 來設定,
SHOW VARIABLES LIKE 'innodb_buffer_pool_instances'
通常來說,資料庫中的快取池是通過 LRU(Lastest Recent Used,最近最少使用)演算法來進行管理的,快取池的默認單位是 "頁",一頁默認 16 KB,
從 InnoDB 1.2 版本開始,可以通過 INNODB_BUFFER_POOL_STATS 來觀察快取池的運行狀態,
SELECT
POOL_ID,
HIT_RATE '快取池的命中率',
PAGES_MADE_YOUNG AS '快取池 old 部分加入到 new 部分的次數',
PAGES_NOT_MADE_YOUNG '快取池 new 部分加入到 old 部分的次數'
FROM information_schema.INNODB_BUFFER_POOL_STATS
重做(REDO)日志快取是用來存放重做日志資訊的,一般不需要設定得過大,因為一般情況下每一秒鐘都會將重做日志快取重繪到日志檔案,一般設定 8MB 就足以滿足絕大部分得應用,可通過 INNODB_LOG_BUFFER_SIZE 引數控制,
SHOW VARIABLES LIKE 'INNODB_LOG_BUFFER_SIZE'
當前事務資料庫系統普遍都采用了 WriteAhead Log 策略,即當事務提交時,先寫重做日志,再修改頁,因此,重做日志的作用是對資料庫系統中的資料進行恢復(當資料庫系統例外宕機的時候),
額外記憶體池是用來分配一些資料結構本身的記憶體,例如緩沖池中的幀快取(frame buffer)、緩沖控制物件(innodb_buffer_pool),
三、后臺執行緒
Master Thread 是一個非常核心的后臺執行緒,主要負責將快取池中的資料異步重繪到磁盤,保證資料的一致性,包括臟頁的重繪、合并插入快取(INSERT BUFFER)、UNDO 頁的回收等,
IO Thread 的作業主要是負責 IO 請求的回呼處理(InnoDB 存盤引擎中大量的使用了 AIO 來處理寫 IO 請求),
SHOW VARIABLES LIKE 'INNODB_%io_threads'
PurgeThread 是在 InnoDB 1.1.x 版本中引入的,用來回收已經使用并分配的 undo 頁以減輕 Master Thread 的作業量 ,因為事務被提交后,其所使用的 undolog 可能不再需要,
SHOW VARIABLES LIKE 'INNODB_purge_threads'
Page Cleaner Thread 是在 InnoDB 1.2.x 版本中引入的,其作用是將之前版本的臟頁重繪操作放入到單獨的執行緒中來完成以減輕 Master Thread 的作業量,
四、其他
InnoDB 存盤引擎開創性地設計了 Insert Buffer(插入緩沖),對于非聚簇索引的插入或更新操作,不是每一次直接插入到索引頁中,而是先判斷插入的非聚簇索引頁是否在緩沖池中,若在,則直接插入;若不在,則先放入到一個 Insert Buffer 物件中,然后再以一定的頻率進行 Insert Buffer 和輔助索引頁子節點的 merge(合并)操作,這時通常能將多個插入合并到一個操作中(因為在一個索引頁中),這就大大提高了對于非聚簇索引插入的性能,
doublewrite(兩次寫)由兩部分組成,一部分是記憶體中的 doublewrite buffer,大小為 2MB,另一部分是物理磁盤上共享表空間(tablespace)中連續的 128個頁,即2個區,大小同樣是 2MB,在對緩沖池的臟頁進行重繪時,并不直接寫磁盤,而是會通過 memcpy 函式將臟頁先復制到記憶體中的 doublewrite buffer,之后通過 doublewrite buffer 再分兩次,每次 1MB 順序地寫入共享表空間(tablespace)的物理磁盤上,然后馬上呼叫 fsync 函式,同步磁盤,避免緩沖寫帶來的問題,如果作業系統在將頁寫入磁盤的程序中發生了崩潰,在恢復程序中,InnoDB 存盤引擎可以從共享表空間中的 doublewrite 中找到該頁的一個副本,將其復制到表空間檔案,再應用重做日志,
SHOW GLOBAL STATUS LIKE 'INNODB_dblwr%'

自適應哈希索引(Adaptive Hash Index,AHI)是指 InnoDB 存盤引擎會自動根據訪問的頻率和模式來自動地為某些熱點頁建立哈希索引,AHI 是通過緩沖池的 B+ 樹頁構造而來,因此建立的速度很快,而且不需要對整張表構建哈希索引,
在 InnoDB 存盤引擎中,采用異步IO(Asynchronous IO,AIO)的方式來處理磁盤操作,
SHOW VARIABLES LIKE 'innodb_use_native_aio'
InnoDB 存盤引擎還提供了 Flush Neighbor Page(重繪鄰接頁)的特性,其作業原理為:當重繪一個臟頁時,InnoDB 存盤引擎會檢測該頁所在區的所有頁,如果是臟頁,那么一起進行重繪,這樣做的操作顯而易見,通過 AIO 可以將多個 IO 寫入操作合并為一個 IO 操作,(固態硬碟具有超高的 IOPS)
SHOW VARIABLES LIKE 'innodb_flush_neighbors'
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/6040.html
標籤:MySQL
上一篇:mysql標識列和事務
下一篇:druid配置
