[TOC]

## 插入緩存
### 1.Insert Buffer
innodb使用insert buffer"欺騙"數據庫:對于為非唯一索引,輔助索引的修改操作并非實時更新索引的葉子頁,而是把若干對同一頁面的更新緩存起來做合并為一次性更新操作,轉化隨機IO 為順序IO,這樣可以避免隨機IO帶來性能損耗,提高數據庫的寫性能。


IBUF_POOL_SIZE_PER_MAX_SIZE參數修改默認為2 即為最大緩存為1/2 如果將其改為3 這最大能夠使用1/3的緩存池內存。
### 2.Change Buffer
innodb 1.0.x才開始引用 是Insert Buffer的升級版,
InnoDB存儲引擎可以對DML操作————INSERT、DEKETE、UPDATE進行緩沖,他們分別是:Insert Buffer、Delete Buffer、Purge buffer。
Change Buffer對象也是非唯一的輔助索引。
對一條記錄進行UPDATE操作可能分為兩個過程:
(1)Delete Buffer對應 UPDATE操作將記錄標記為已刪除;
(2)Purge Buffer對應UPDATE操作真正將記錄刪除。
innodb 2.0.x 開始通過參數 innodb_change_buffer_max_size來控制 查詢:`show variables like 'innodb_change_buffer_max_size'\G`
默認為25 即為1/4的緩沖池內存空間。最大為50值即為1/2的緩沖池內存空間。
### Insert Buffer內部實現
Insert Buffer 是一棵B+樹,因此其也由葉節點和非葉節點組成。非葉節點存放的是查詢的 search key(鍵值)
如圖:


### Merge Insert Buffer
(1)輔助索引頁被讀取到緩沖池時,
(2)Insert Buffer Bitmap 頁追蹤到該輔助索引頁已無可用空間時;
(3)Master Thread。


*****
## 兩次寫
doublewrite由兩部分組成,一部分是內存的doublewrite buffer,大小為2MB,另一部分是物理磁盤上共享表空間中聯系的128個頁,即2個區(extent),大小同樣為2MB。
臟讀刷新先復制到內存中的doublewrite buffer,之后doublewrite buffer再分兩次,每次1MB寫入共享表空間的物理磁盤,然后馬上調用fsync函數,同步磁盤,避免緩沖寫帶來的問題。如圖:

通過命令`SHOW GLOBAL STATUS LIKE 'innodb dblwr%'\G`觀察doublewrite運行的情況。
*****
## 自適應哈希索引
InnoDB存儲引擎會監控各索引頁的查詢。如果觀察到簡歷哈希所以可以帶來的速度提升,則建立哈希索引,稱為自適應哈希索引(Adaptive Hash Index,AHI)。AHI是通過緩沖池的B+樹頁構造而來,因此建立的速度很快,而且不需要對整張表構建哈希索引。InnoDB存儲引擎會自動根據訪問的頻率和墨水來自動地為某些熱點頁建立哈希索引。
AHI有個要求,連續訪問模式必須一樣的例如:

啟用之后讀取寫入可以提高2倍。輔助索引可以提高5倍。
通過`SHOW ENGINE INNODB STATUS\G;`查看狀態:

通過結果可以考慮是禁用還是啟動此特性,默認AHI啟用;
*****
## 異步IO
為了提高磁盤操作性能,當前的數據庫系統都采用異步IO(Asynchronous IO,AIO)的方式來處理磁盤操作。
與AIO對應的是 Sync IO,Sync IO每次進行IO操作 需要等到改操作結束才能繼續接下來的操作。但是如果用戶是一條索引掃描的查詢,那么需要掃描索引頁,也就是需要進行多次的IO操作。如果是這樣的話就沒有必要了。
用戶發送一個IO請求就可以發送另一個IO請求,當全部發送完畢,等待所有的IO操作的完成,這就是AIO。
AIO的另一個優勢 可以進行IO Merge操作,也就是將多個IO何必為一個IO。
若通過Linux操作系統下的iostat 命令 可以觀察 rrqm/s和wrqm/s。
InnoDB 1.1.x 開始(InnoDB Plugin 不支持)提供了內核級別AIO的支持,稱為 NatIve AIO。因此編譯或者運行該版本MySQL時需要libaio的支持。若沒有則會出現如下的提示:

Native AIO只有windows 和linux系統支持。Mac OSX不支持。
參數innodb_use_native_aio 控制師傅啟動 liunx默認不啟動。
`SHOW VARIABLES LIKE 'innodb_use_native_aio'\G`

官方顯示,啟用NatIve AIO,恢復速度可以提高75%。
read ahead方式讀取都是通過AIO完成,臟頁的刷新和磁盤寫入操作則全部由AIO完成。
*****
## 刷新鄰接頁
InnoDB存儲引擎還提供了Flush Neighbor Page(刷新鄰接頁)的特性。工作原理:當刷新臟頁時,InnoDB存儲引擎會檢測所在區的所有頁,如果是臟頁,那么一起進行刷新。
參數innodb_flush_neighbors 控制是否啟用改特性.如果是機械硬盤建議啟用,如果是固態硬盤就不建議使用 IOPS性能的磁盤 則建議設置為0,關閉此特性。
*****
## 啟動、關閉和恢復
關閉時參數innodb_fast_shutdown影響著表存儲引擎InnoDB的行為。該參數可取值為0、1、2,默認為1

當正常關閉MySQL數據庫時,下次的啟動應該會非常“正常”。但是沒有正常關閉 如用kill命令關閉數據庫,在MySQL 數據庫運行中重啟服務器,或者關閉數據庫時,將參數innodb_fast_shuidown設為了2時,下次MySQL數據庫啟動時都會對InnoDB存儲引擎的表進行恢復操作。
參數innodb_force_recovery影響了正規InnoDB存儲引擎恢復的狀況。默認為0,代表當發生需要恢復時,進行所有恢復的操作,當不能進行有效恢復時,如數據頁發送了corruption,MySQL數據庫可能發送宕機(crash),并把錯誤寫入錯誤日志中去。
如果用戶知道怎么進行恢復 比如進行alter table操作是發生意外了,數據庫重啟會對InnoDB進行回滾操作,對于大表淶水需要很長時間,所以可以把表刪除,從備份中導入數據到表。速度就會比回滾操作快。


如果innodb_force_recovery 設置為3 則不需要回滾,因此數據庫很快就啟動完成了。 但是需要仔細確認是否需要回滾事務操作。