設計目標是面向在線事務(OLTP)處理的應用。php
支持事務、行級鎖、經過多版本併發控制(MVCC)支持高併發、提供一致性非鎖定讀、next-key locking避免幻讀、主鍵彙集索引前端
設計目標是面向OLAP應用。mysql
不支持事務、不支持行鎖、表鎖設計、支持全文索引算法
略sql
InnoDB存儲引擎是多線程模型,後臺有多個不一樣的線程,用於處理不一樣的任務。數據庫
內部由多個循環組成。包括主循環(loop),後臺循環(background loop)緩存
主循環每隔一秒的操做數據結構
主循環每隔10秒的操做多線程
InnoDB是基於磁盤的存儲系統,爲了彌補cpu和磁盤性能的差距,將從磁盤讀出的數據保存在內存中,下次讀取先從緩衝池中讀取。有數據更新也先更新緩衝池的數據,經過checkpoint機制寫回磁盤。緩衝池中包括索引頁、數據頁、undo頁、插入緩存、鎖信息等架構
最近作少使用算法,最頻繁使用的頁在List前端,最少使用的頁在List末尾。當緩衝池容量不足容納新數據時,先從尾部釋放數據頁。新數據插入在List的midpoint(List的5/8,對樸素LRU的優化,樸素LRU插入List頭部。避免大量一次性查詢把頻繁使用的頁刷出緩衝池)
當數據被更新,緩衝池中的數據首先被更新,修改以後的頁稱爲髒頁。髒頁會保存到Flush List中,經過checkpoint機制把髒頁數據寫回磁盤
首先把重作日誌信息存入緩衝區,而後按照必定頻率同步到重作日誌文件中。如下三種狀況都會觸發重作日誌緩存同步到重作日誌文件:
爲了防止宕機致使事務未提交信息丟失,在事務提交時,先把數據保存到重作日誌(redo log)中,再修改頁。保證了持久性(D)
發生宕機,重啓以後自動從重作日誌中恢復數據。
可是這裏有如下問題:
check point就是爲了解決這些問題:
check point觸發時機:
咱們知道索引分爲彙集索引和非彙集索引。
彙集索引通常是自增的惟一id,頁中的數據記錄按順序存放,寫入的時候不須要隨機讀取其餘頁中的數據,寫入速度很快(若是用UUID做爲主鍵,寫入速度會很慢,每次寫入都須要隨機讀)
實際應用中,一張表每每還有非彙集索引的存在。非彙集索引葉子節點的插入不是順序的,須要離散的訪問非彙集索引頁,隨機讀取致使了插入數據的性能降低。插入緩存就是爲了優化這種場景下的插入速度
對於非彙集索引的插入,會先判斷非彙集索引頁是否在緩衝池中,若是在緩衝池中,直接插入索引頁,若是沒在,先放入到insert buffer對象中,而後再以必定的頻率把insert buffer中的數據和非彙集索引的葉子節點進行數據合併
insert buffer 的數據結構也是B+樹,有記錄要插入的時候,會對記錄進行封裝,按照記錄的插入順序進行編號,是順序寫入
若是InnoDB正在寫入某個頁的數據到磁盤,正好寫了一部分的時候宕機了。這種狀況稱爲部分寫失效,會致使數據丟失
double write由兩部分組成。一部分是double write緩衝,一部分是物理磁盤連續共享空間。在刷新髒頁數據的時候,先複製一份髒頁數據到兩次寫緩存中,在順序寫入共享磁盤中(由於是順序寫性能影響不大)。最後寫入數據存儲磁盤中(離散寫)
hash是很是快的查詢方式,時間負責度爲O(1)。而B+樹的查找次數取決於樹的高度。
若是一個頁被頻繁的訪問,並且訪問模式也相同(聯合索引使用最左原則)。會自動針對這頁數據根據緩衝池中的索引創建Hash索引提升查詢速度
能夠在發出一個IO請求後,在發出另外的IO請求,不必等待上一次的IO請求處理完成。把所有IO請求都發出,等待全部IO操做的完成,這就是AIO(Aysnc IO)
MySQL據庫和InnoDB存儲引擎有不少類型的文件,每種文件用處不一樣。主要有參數文件、sokcet文件、pid文件、日誌文件、表結構文件、存儲引擎文件
InnoDB中,表數據都是按照主鍵順序組織存放的。每張表都有主鍵,若是沒有顯示的定義主鍵,會把惟一索引做爲主鍵。若是惟一索引也沒有,會自動建立6字節大小的指針做爲主鍵
全部數據都存放在表空間中,表空間又由段、區、頁組成
數據庫的索引結構是B+樹,高度通常在2-4層,一次查找只須要2-4次的io。索引分爲彙集索引和非彙集索引
按照每張表的主鍵構建的B+樹,葉子節點中存儲着整張表的行記錄數據,每一個葉子節點經過雙向鏈表進行鏈接。由於實際的數據頁只能按照一個彙集索引進行排列,每張表只能擁有一個彙集索引
彙集索引對於主鍵的範圍查找和排序查找速度很是快。
葉子節點不包含行記錄的所有數據,葉子節點只存儲了鍵值和指向彙集索引的書籤
在線架構改變,經過php腳本實現,在索引的建立或刪除過程當中,能夠有讀寫事務對錶進行操做。過程以下:
經過新的alter語法,能夠選擇索引的建立方式
Cardinality表示索引中惟一值的數據的估計值(不是實時更新,使用採樣法延遲更新),應儘量接近表中數據總行數。
聯合索引也是一棵B+樹,不一樣的是索引鍵值的數量大於等於2。聯合索引的第二個好處是已經對第二個鍵值作了排序處理,減小了一次額外的排序操做
MyISAM引擎的鎖是表鎖設計,併發狀況下讀沒有問題,可是寫的性能會比較低
實現原理是經過MVCC機制實現,若是讀取的行正處於update或delete中,讀操做不會去等待行上X鎖的釋放,而是去讀取行的快照數據。
一致性非鎖定讀能夠極大的提升併發性能
不一樣的事務隔離級別,讀取的快照版本是有差異的
默認配置下,採用可重複讀的隔離級別,讀取數據採起的是一致性非鎖定讀。
可是某些場景下須要對讀取操做加鎖來保證嚴格的數據一致性,這時候能夠顯式的對讀取的記錄進行加鎖:
默認隔離級別(可重複讀)下,默認加的是next-key lock(爲了解決幻讀問題),當索引中含有惟一屬性時,會降級爲record lock。
在讀已提交隔離級別下,加的是record lock
舉個例子:
如今表z,有a,b兩列,a是主鍵索引,b創建輔助索引。如今記錄以下:(1,1)(3,1)(5,3)(7,6)(10,8)
select * from z where b=3 for update
由於鎖是經過對索引加鎖實現的。因此這裏須要對主鍵索引和輔助索引加鎖,主鍵索引加的鎖是record lock,輔助索引加的鎖是next-key lock,鎖定範圍是(1,3)、三、(3,6)