首先以一張圖簡單展現 InnoDB 的存儲引擎的體系架構.從圖中可見, InnoDB 存儲引擎有多個內存塊,這些內存塊組成了一個大的內存池,主要負責以下工做:mysql
維護全部進程/線程須要訪問的多個內部數據結構git
緩存磁盤上的數據, 方便快速讀取, 同時在對磁盤文件修改以前進行緩存github
重作日誌(redo log)緩衝sql
後臺線程的主要做用是負責刷新內存池中的數據,保證緩衝池中的內存緩存的是最新數據;將已修改數據文件刷新到磁盤文件;保證數據庫發生異常時 InnoDB 能恢復到正常運行 的狀態數據庫
InnoDB 使用的是多線程模型, 其後臺有多個不一樣的線程負責處理不一樣的任務緩存
這是最核心的一個線程,主要負責將緩衝池中的數據異步刷新到磁盤,保證數據的一致性,包括贓頁的刷新、合併插入緩衝、UNDO 頁的回收等.數據結構
在 InnoDB 存儲引擎中大量使用了異步 IO 來處理寫 IO 請求, IO Thread 的工做主要是負責這些 IO 請求的回調.多線程
能夠經過命令來觀察 InnoDB 中的 IO Thread:架構
mysql> SHOW ENGINE INNODB STATUS\G *************************** 1. row *************************** Type: InnoDB Name: Status: ===================================== 2016-03-23 20:19:53 0x700000d51000 INNODB MONITOR OUTPUT .... ... -------- FILE I/O -------- I/O thread 0 state: waiting for i/o request (insert buffer thread) I/O thread 1 state: waiting for i/o request (log thread) I/O thread 2 state: waiting for i/o request (read thread) I/O thread 3 state: waiting for i/o request (read thread) I/O thread 4 state: waiting for i/o request (read thread) I/O thread 5 state: waiting for i/o request (read thread) I/O thread 6 state: waiting for i/o request (write thread) I/O thread 7 state: waiting for i/o request (write thread) I/O thread 8 state: waiting for i/o request (write thread) I/O thread 9 state: waiting for i/o request (write thread) ...... ---------------------------- END OF INNODB MONITOR OUTPUT
能夠看到, InnoDB 共有10個 IO Thread, 分別是 4個 write、4個 read、1個 insert buffer和1個 log thread.異步
事物被提交以後, undo log 可能再也不須要,所以須要 Purge Thread 來回收已經使用比分配的 undo頁. InnoDB 支持多個 Purge Thread, 這樣作能夠加快 undo 頁的回收
InnoDB 引擎默認設置爲4個 Purge Thread:
mysql> SHOW VARIABLES LIKE "innodb_purge_threads"\G *************************** 1. row *************************** Variable_name: innodb_purge_threads Value: 4 1 row in set (0.00 sec)
Page Cleaner Thread 是新引入的,其做用是將以前版本中髒頁的刷新操做都放入單獨的線程中來完成,這樣減輕了 Master Thread 的工做及對於用戶查詢線程的阻塞
InnoDB 存儲引擎是基於磁盤存儲的,其中的記錄按照頁的方式進行管理,因爲 CPU 速度和磁盤速度之間的鴻溝, InnoDB 引擎使用緩衝池技術來提升數據庫的總體性能.
緩衝池簡單來講就是一塊內存區域.在數據庫中進行讀取頁的操做,首先將從磁盤讀到的頁存放在緩衝池中,下一次讀取相同的頁時,首先判斷該頁是否是在緩衝池中,若在,稱該頁在緩衝池中被命中,直接讀取該頁.不然,讀取磁盤上的頁.
對於數據庫中頁的修改操做,首先修改在緩衝池中頁,而後再以必定的頻率刷新到磁盤,並非每次頁發生改變就刷新回磁盤.
緩衝池的大小直接影響數據庫的總體性能,對於 InnoDB 存儲引擎而言,緩衝池配置經過參數 innodb_buffer_pool_size
來設置. 下面顯示本機虛擬機上一臺 MySQL 數據庫配置:
mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_size'\G *************************** 1. row *************************** Variable_name: innodb_buffer_pool_size Value: 134217728 1 row in set (0.00 sec)
緩衝池中緩存的數據頁類型有:索引頁、數據頁、 undo 頁、插入緩衝、自適應哈希索引、 InnoDB 的鎖信息、數據字典信息等.索引頁和數據頁佔緩衝池的很大一部分.
下圖顯示 InnoDB 存儲引擎總內存的結構狀況.
InnoDB 存儲引擎先將重作日誌信息放入這個緩衝區,而後以必定頻率將其刷新到重作日誌文件.重作日誌文件通常不須要設置得很大,由於在下列三種狀況下重作日誌緩衝中的內容會刷新到磁盤的重作日誌文件中.
Master Thread 每一秒將重作日誌緩衝刷新到重作日誌文件
每一個事物提交時會將重作日誌緩衝刷新到重作日誌文件
當重作日誌緩衝剩餘空間小於1/2時,重作日誌緩衝刷新到重作日誌文件
在 InnoDB 存儲引擎中, 對一些數據結構自己的內存進行分配時,須要從額外的內存池中進行申請.例如,分配了緩衝池,可是每一個緩衝池中的幀緩衝還有對應的緩衝控制對象,這些對象記錄以一些諸如 LRU, 鎖,等待等信息,而這個對象的內存須要從額外的內存池中申請.
個人博客: http://ygmyth.github.io