InnoDB存儲引擎

InnoDB是如今使用的最多的儲存引擎了吧。來看看它的特色:node

ACID事務mysql

行鎖算法

MVCCsql

外鍵數據庫

一致性非鎖定讀緩存

不支持全文索引數據結構

 

InnoDB的體系架構架構

主要是由內存塊組成的內存池。oop

內存池的主要工做性能

1.維護內部數據結構

2.緩存重作日誌

3.緩存磁盤上的數據,數據進入內存以前就存儲在這裏

後臺線程負責刷新內存池,保證內存池中的緩存數據是最新的。

還有,將已經修改的數據存儲到磁盤中。

 

後臺線程

默認狀況下,InnoDB有7個線程:4個IO線程、1個master 線程、1個錯誤監控線程、一個鎖監控線程。

4個IO線程分別是:

insert buffer thread

log thread

read thread

write thread

在Linux系統中,IO線程的數量是不能調整的,可是在插件版的InnoDB中,read和write線程增長到了4個,

而且配置文件中沒有innodb_file_io_threads這個參數。

-------- 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 2 state: 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)

參數換成了innodb_read_io_threads和innodb_write_io_threads

mysql> show variables like 'innodb_version'\G; *************************** 1. row *************************** Variable_name: innodb_version Value: 5.6.36
1 row in set (0.00 sec) ERROR: No query specified mysql> show variables like 'innodb_%io_threads'\G; *************************** 1. row *************************** Variable_name: innodb_read_io_threads Value: 4
*************************** 2. row *************************** Variable_name: innodb_write_io_threads Value: 4
2 rows in set (0.00 sec)

 

內存

InnoDB引擎的內存由如下幾部分組成:

緩衝池

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)

 

重作日誌緩衝池

mysql> show variables like 'innodb_log_buffer_size'\G; *************************** 1. row *************************** Variable_name: innodb_log_buffer_size Value: 8388608
1 row in set (0.00 sec)

 

額外的內存池

mysql> show variables like 'innodb_additional_mem_pool_size'\G; *************************** 1. row *************************** Variable_name: innodb_additional_mem_pool_size Value: 8388608
1 row in set (0.00 sec)

 

緩衝池佔用的內存最大,用來緩存數據。

存儲引擎工做方式:

將數據庫文件按頁(16K)讀取到緩衝池中,而後按照最少使用(LRU)算法來保留緩衝池中的數據。

若是數據須要修改,優先修改緩衝池中的數據,修改後的頁叫作髒頁。

最後後臺線程將髒頁刷新到文件中。

 

mysql> show engine innodb status\G;

每一個幀爲16K,因此緩衝池大小爲8192*16/1024=128M。

Free buffers 當前空閒的緩衝幀數量。

Database pages 已經使用的緩衝幀

Modified db pages 髒頁的數量

從上面的數據能夠看出,緩衝池還剩下5.5%左右可使用。數據庫壓力比較大。

Per second averages calculated from the last 30 seconds

該命令顯示的是過去30秒的狀態,並不是最新的狀態。

 

數據頁的類型

索引頁

數據頁

undo頁

插入緩衝(insert buffer)

自適應哈希索引(adaptive hash index)

InnoDB存儲的鎖信息(lock info)

數據字典信息(data dictionary)

 

日誌緩衝將日誌文件先放入緩衝區,而後刷新到重作日誌。通常每秒就會將重作日誌緩衝刷新到日誌文件,日誌緩衝的值不須要設置很大,大於每秒的事務量便可。

 

InnoDB引擎管理內存的方式叫作內存堆(heap)

在對某些數據結構自己進行內存分配時,首先從額外內存池分配,不夠用就從緩衝池分配。

InnoDB實例的緩衝池中,緩衝幀對應的緩衝控制對象所需的內存也是從額外內存池分配的,

因此當緩衝池很大時,額外內存池的大小也要增長。

 

master thread

InnoDB引擎的主要工做都是在master thread由完成的。

master thread線程的優先級最高,經過分析其源代碼能夠知道,其內部由幾個循環構成:

主循環(loop)

後臺循環

暫停循環

刷新循環

master thread基本就是在這幾個循環之間來回切換。

 

主循環(loop)

大部分操做都在此循環中完成,分爲2大部分:每秒鐘的操做和每10秒的操做

 

 從代碼中能夠看出,是可能有延遲的。

每一秒的操做包括:

重作日誌緩衝刷新到磁盤,即便這個事務尚未提交(老是)。

合併插入緩衝(可能)。

最多刷新100個InnoDB緩衝池中的髒頁到磁盤(可能)。

若是當前沒有用戶活動,切換到後臺循環(可能)。

即便事務沒有提交,重作日誌緩衝每秒也會被刷新到磁盤中的重作日誌文件,這也是爲何再大的事務提交的時間也很快。

 

合併插入緩衝並非每秒都發生。InnoDB引擎會判斷一秒內發生的IO次數是夠小於5次,若是小於5次,InnoDB認爲IO壓力很小,

就會執行插入緩衝合併。

 

一樣,最多刷新100個髒頁也不是必定發生。InnoDB會判斷當前緩衝區髒頁的比例是否超過了配置文件中innodb_max_dirty_pages_pct

參數(默認90%),若是超過了該值,就會刷新100個髒頁到磁盤中。

 

接着來看每10秒的操做:

刷新100個髒頁到磁盤(可能)。

合併至多5個插入緩衝(老是)。

將日誌緩衝刷新到磁盤(老是)。

刪除無效的重作頁(老是)。

刷新100個或者10個髒頁到磁盤(老是)。

產生一個檢查點(老是)。

以上過程當中,InnoDB首先會判斷過去10秒內,IO操做是否超過200次,

若是沒有,將會把100個髒頁刷新到磁盤。

以後,會合並插入緩衝。

以後,會將日誌緩衝刷新到磁盤。

而後,刪除無用的Undo頁。

在執行update或者delete操做時,由於一致性讀的關係,這些行的版本信息會被保留,

在進行Undo時,會去判斷這些被刪除的行是否能夠刪除

若是能夠,當即刪除。經過源代碼能夠知道,最多一次刪除20個Undo頁

而後,InnoDB回去判斷緩衝池中髒頁的比例,若是大於70%,則刷新100個髒頁,不然,刷新10個髒頁

最後,InnoDB會產生一個檢查點,在此刻,InnoDB會將最老日誌序列號(oldest LSN)的頁寫入磁盤。

 

接着來看後臺循環

若是數據庫沒有活動,數據庫空閒或者數據庫關閉時,就會切換到這個模式。

這個循環會執行的操做:

刪除無用的Undo頁(老是)。

合併20個插入緩衝(老是)。

跳回到主循環  (老是)。

不斷刷新100個頁,知道符號條件(可能,跳轉到flush loop中完成)

若是刷新循環沒有什麼活動,會切換到暫停循環,將master thread掛起。

若是啓用了InnoDB引擎,卻沒有任何基於InnoDB的表,就是處於這個狀態。

 

master thread的潛在問題

從上面的知識能夠知道,源代碼對IO作了限制。每秒最大刷新100個髒頁或者刷新20個插入緩衝。

這個可能在某些程序中會致使master thread忙不過來

因此在InnoDB Plugin版本中加入了innodb_io_capacity參數,

用來表示磁盤IO吞吐量

mysql> show variables like 'innodb_io%'\G; *************************** 1. row *************************** Variable_name: innodb_io_capacity Value: 200

規則以下:

在合併插入緩衝時,數量爲該值的5%

在刷新髒頁時,數量爲該值

 

若是使用了SSD和進行了Raid操做,能夠將該值設置的高點。

 

另外一個問題是參數innodb_max_dirty_pages_pct,在mysql5.1(包括此版本),默認值爲90%,

意味着髒頁佔緩衝池的90%,這個太大了!在InnoDB Plugin版本,該值被調整爲了75%,

因此能夠兼顧髒頁刷新頻率和磁盤IO。

 

InnoDB Plugin的另外一個參數是innodb_adaptive_flushing(自適應的刷新),該值影響每秒髒頁的數量

mysql> show variables like 'innodb_adaptive_%'\G; *************************** 1. row *************************** Variable_name: innodb_adaptive_flushing Value: ON

這個參數會致使,當髒頁在緩衝池的比例小於innodb_max_dirty_pages_pct時,也會刷新必定數量的髒頁。

因此,最好使用InnoDB Plugin版本,對數據庫的性能會有提高。

 

關鍵特性

InnoDB的關鍵特性還包括插入緩衝,2次寫,自適應哈希索引。

插入緩衝

咱們知道,主鍵是行的惟一標識符,在表中,行的插入順序是按照主鍵遞增的

插入緩衝的使用要知足2個條件

索引是輔助索引

索引不是惟一的

 

2次寫

這個能夠保證數據的可靠性。

架構

 

 當髒頁刷新時,並非直接將其寫入磁盤,而是先將其寫入內存中的doublewrite buffer。

每次寫入1M到共享表空間的磁盤中。這樣若是數據庫崩潰了,能夠在共享表空間找到頁的副本,

在應用重作日誌來恢復。

 

自適應哈希索引

哈希是一種快速的查找方法。

經常使用語join操做

InnoDB引擎會監控表上的索引查找,若是觀察到創建哈希索引會帶來速度的提高,

就會創建哈希索引,這就是自適應哈希索引。

啓動自適應哈希索引,能夠帶來讀寫性能2倍的提升;

能夠帶來輔助索引性能5倍的提升;

------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations: insert 0, delete mark 0, delete 0 discarded operations: insert 0, delete mark 0, delete 0 Hash table size 276707, node heap has 402 buffer(s) 0.00 hash searches/s, 0.00 non-hash searches/s

默認開啓

*************************** 3. row *************************** Variable_name: innodb_adaptive_hash_index Value: ON

 

啓動、關閉和恢復

 innodb_fast_shutdown參數影響InnoDB引擎的行爲,默認爲1

mysql> show variables like 'innodb_fast_shutdown'\G;
*************************** 1. row ***************************
Variable_name: innodb_fast_shutdown
        Value: 1
1 row in set (0.00 sec)

0 表示關閉數據庫時,須要完成全部的full purge和merge insert buffer操做

若是在升級InnoDB Plugin,能夠將該值設置爲0

2 表示不完成full purge和merge insert buffer操做,也不將緩衝池中的數據髒頁寫會磁盤,而是寫在日誌。

 

innodb_force_recovery參數影響引擎的恢復狀況,默認值爲0
mysql> show variables like 'innodb_force_recovery'\G;
*************************** 1. row ***************************
Variable_name: innodb_force_recovery
        Value: 0
1 row in set (0.00 sec)

相關文章
相關標籤/搜索