一 插入緩沖
1.1 解決的問題
插入多條數(shù)據(jù)時有咨,除了需要插入聚集索引外,還需要插入到非聚集索引中,然而非聚集索引的插入走的是隨機寫,這個操作會影響性能锄列。
1.2 基本原理
插入非聚集索引時,不會直接寫到真正的非聚集索引里面去惯悠,而是先寫到一個叫插入緩沖
的臨時文件中(注意插入緩沖雖然名字叫緩沖邻邮,實際上是臨時文件)
然后依賴后臺線程將插入緩沖中的內(nèi)容更新到真正的非聚集索引上去。
由于對插入緩沖的寫是連續(xù)的克婶,所以這種操作就解決了隨機寫的問題筒严。
1.3 使用條件
并不是所有對非聚集索引的更新都會使用插入緩沖,需要滿足以下兩個條件:
- 非聚集索引不是唯一的
- 要插入的非聚集索引頁不在內(nèi)存中
為什么不能是唯一索引的情萤?
因為如果是唯一索引鸭蛙,則插入的時候就需要判斷是否有重復(fù),而這個判斷的過程本身就包含一次隨機讀筋岛,所以即使使用了插入緩沖也無法解決磁盤隨機讀寫的問題
為什么非聚集索引頁不能在內(nèi)存中娶视?
其實并不是非聚集索引頁不能在內(nèi)存中,而是在內(nèi)存中的非聚集索引頁就不需要走插入緩沖了泉蝌。因為如果在內(nèi)存中的話歇万,那直接寫內(nèi)存中的緩存頁即可揩晴。
這里可能還會有疑問,寫了內(nèi)存中的緩存頁后贪磺,把緩存頁刷新到磁盤時不是也會隨機寫磁盤嗎硫兰?
其實不是的,內(nèi)存中的緩存頁被更新后不會立即刷新到磁盤中寒锚,而是等待后臺線程刷新劫映。所以這里也不會隨機讀寫磁盤。
可能還會有疑問刹前,如果內(nèi)存中的緩存頁被更新后不直接刷新到磁盤泳赋,那么宕機時豈不是會丟失數(shù)據(jù)嗎?
其實這里也不會喇喉,因為在寫內(nèi)存中的緩存頁時會先寫重做日志祖今,記錄更新的內(nèi)容,而這個重做日志是會在事務(wù)提交前就刷新到磁盤中的拣技,所以即使宕機千诬,也可以用重做日志恢復(fù)數(shù)據(jù)。另外重做日志也是磁盤上連續(xù)的空間膏斤,所以也不會有隨機讀寫
二 兩次寫
2.1 解決的問題
當(dāng)數(shù)據(jù)庫寫物理頁時徐绑,如果宕機了,那么可能會導(dǎo)致物理頁的一致性被破壞莫辨。
可能有人會說傲茄,重做日志不是可以恢復(fù)物理頁嗎?實際上是的沮榜,但是要求是在物理頁一致的情況下盘榨。
也就是說,如果物理頁完全是未寫之前的狀態(tài)敞映,則可以用重做日志恢復(fù)较曼。如果物理頁已經(jīng)完全寫完了,那么也可以用重做日志恢復(fù)振愿。但是如果物理頁前面2K寫了新的數(shù)據(jù),但是后面2K還是舊的數(shù)據(jù)弛饭,則種情況下就無法使用重做日志恢復(fù)了冕末。
這里的兩次寫就是保證了物理頁的一致性,使得即使宕機侣颂,也可以用重做日志恢復(fù)档桃。
2.2 基本原理
在寫物理頁時,并不是直接寫到真正的物理寫上去憔晒,而是先寫到一個臨時頁上去藻肄,臨時頁寫完后蔑舞,再寫物理頁。
這樣一來:
- 如果寫臨時頁時宕機了嘹屯,物理頁還是完全未寫之前的狀態(tài)攻询,可以用重做日志恢復(fù)
- 如果寫物理頁時宕機了,則可以使用臨時頁來恢復(fù)物理頁
2.3 具體實現(xiàn)
- InnoDB中共享表空間中劃了2M的空間州弟,叫做double write钧栖,專門存放臨時頁。
- InnoDB還從內(nèi)存中劃出了2M的緩存空間婆翔,叫做double write buffer拯杠,專門緩存臨時頁
- 每次寫物理頁時,先寫到double write buffer中啃奴,然后從double write buffer寫到double write上去潭陪。最后再從double write buffer寫到物理頁上去
你問我為什么要有 double write buffer
這個東西?其實吧InnoDB里面物理頁都 會有內(nèi)存緩存最蕾。只是這里單把這2M的緩存取了個名字而已依溯。
三 自適應(yīng)哈希索引
InnoDB自動監(jiān)控對索引的查找,如果發(fā)現(xiàn)建立哈希索引可以提高效率揖膜,則會自動建立
可以使用innodb_adaptive_hash_index來啟用或者關(guān)閉誓沸,默認是開啟的