InnoDB存儲引擎介紹-(1)InnoDB存儲引擎結構
首先以一張圖簡單展示 InnoDB 的存儲引擎的體系架構.
從圖中可見, InnoDB 存儲引擎有多個內存塊,這些內存塊組成了一個大的內存池,主要負責如下工作:
-
維護所有進程/線程需要訪問的多個內部數據結構
-
緩存磁盤上的數據, 方便快速讀取, 同時在對磁盤文件修改之前進行緩存
-
重做日誌(redo log)緩沖
後臺線程的主要作用是負責刷新內存池中的數據,保證緩沖池中的內存緩存的是最新數據;將已修改數據文件刷新到磁盤文件;保證數據庫發生異常時 InnoDB 能恢復到正常運行 的狀態
後臺線程
InnoDB 使用的是多線程模型, 其後臺有多個不同的線程負責處理不同的任務
1. Master Thread
這是最核心的一個線程,主要負責將緩沖池中的數據異步刷新到磁盤,保證數據的一致性,包括贓頁的刷新、合並插入緩沖、UNDO 頁的回收等.
2. IO Thread
在 InnoDB 存儲引擎中大量使用了異步 IO 來處理寫 IO 請求, IO Thread 的工作主要是負責這些 IO 請求的回調.
可以通過命令來觀察 InnoDB 中的 IO Thread:
mysql> show engine innodb status\G *************************** 1. row *************************** Type: InnoDB Name: Status:===================================== 2017-07-22 00:16:26 7f4a37451700 INNODB MONITOR OUTPUT ===================================== -------- FILE I/O -------- I/O thread 0 state: waiting for completed aio requests (insert buffer thread) I/O thread 1 state: waiting for completed aio requests (log thread) I/O thread 2state: waiting for completed aio requests (read thread) I/O thread 3 state: waiting for completed aio requests (read thread) I/O thread 4 state: waiting for completed aio requests (read thread) I/O thread 5 state: waiting for completed aio requests (read thread) I/O thread 6 state: waiting for completed aio requests (write thread) I/O thread 7 state: waiting for completed aio requests (write thread) I/O thread 8 state: waiting for completed aio requests (write thread) I/O thread 9 state: waiting for completed aio requests (write thread) Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] , ibuf aio reads: 0, log i/o‘s: 0, sync i/o‘s: 0 Pending flushes (fsync) log: 0; buffer pool: 0 188 OS file reads, 27180 OS file writes, 26031 OS fsyncs 0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
可以看到, InnoDB 共有10個 IO Thread, 分別是 4個 write、4個 read、1個 insert buffer和1個 log thread.
3. Perge Thread
事務被提交之後, undo log 可能不再需要,因此需要 Purge Thread 來回收已經使用比分配的 undo頁. InnoDB 支持多個 Purge Thread, 這樣做可以加快 undo 頁的回收InnoDB 引擎默認設置為1個 Purge Thread:
mysql> SHOW VARIABLES LIKE "innodb_purge_threads"; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | innodb_purge_threads | 1 | +----------------------+-------+ 1 row in set (0.00 sec)
4. Page Cleaner Thread
Page Cleaner Thread 是新引入的,其作用是將之前版本中臟頁的刷新操作都放入單獨的線程中來完成,這樣減輕了 Master Thread 的工作及對於用戶查詢線程的阻塞
內存
1. 緩沖池
InnoDB 存儲引擎是基於磁盤存儲的,其中的記錄按照頁的方式進行管理,由於 CPU 速度和磁盤速度之間的鴻溝, InnoDB 引擎使用緩沖池技術來提高數據庫的整體性能.
緩沖池簡單來說就是一塊內存區域.在數據庫中進行讀取頁的操作,首先將從磁盤讀到的頁存放在緩沖池中,下一次讀取相同的頁時,首先判斷該頁是不是在緩沖池中,若在,稱該頁在緩沖池中被命中,直接讀取該頁.否則,讀取磁盤上的頁.
對於數據庫中頁的修改操作,首先修改在緩沖池中頁,然後再以一定的頻率刷新到磁盤,並不是每次頁發生改變就刷新回磁盤.
緩沖池的大小直接影響數據庫的整體性能,對於 InnoDB 存儲引擎而言,緩沖池配置通過參數 innodb_buffer_pool_size
來設置. 下面顯示本機虛擬機上一臺 MySQL 數據庫配置:
mysql> SHOW VARIABLES LIKE ‘innodb_buffer_pool_size‘; +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | innodb_buffer_pool_size | 2147483648 | +-------------------------+------------+ 1 row in set (0.00 sec)
緩沖池中緩存的數據頁類型有:索引頁、數據頁、 undo 頁、插入緩沖、自適應哈希索引、 InnoDB 的鎖信息、數據字典信息等.索引頁和數據頁占緩沖池的很大一部分.下圖顯示 InnoDB 存儲引擎總內存的結構情況.
2. 重做日誌緩沖
InnoDB 存儲引擎先將重做日誌信息放入這個緩沖區,然後以一定頻率將其刷新到重做日誌文件.重做日誌文件一般不需要設置得很大,因為在下列三種情況下重做日誌緩沖中的內容會刷新到磁盤的重做日誌文件中.
-
Master Thread 每一秒將重做日誌緩沖刷新到重做日誌文件
-
每個事物提交時會將重做日誌緩沖刷新到重做日誌文件
-
當重做日誌緩沖剩余空間小於1/2時,重做日誌緩沖刷新到重做日誌文件
3. 額外的內存池
在 InnoDB 存儲引擎中, 對一些數據結構本身的內存進行分配時,需要從額外的內存池中進行申請.例如,分配了緩沖池,但是每個緩沖池中的幀緩沖還有對應的緩沖控制對象,這些對象記錄以一些諸如 LRU, 鎖,等待等信息,而這個對象的內存需要從額外的內存池中申請.
InnoDB存儲引擎介紹-(1)InnoDB存儲引擎結構