mysql涉及到的知識多且深,這裡主要撿兩個最基礎也是後端rd最常接觸到的點來展開:innodb的事務及索引原理,偏理論,面試中被問到的概率非常大。為了更好的說明原理,貼了很多圖,大多**於網路,侵刪。
2.1 mysql分層架構
這種分層架構,可以將各層的職責劃分得很清晰,方便擴充套件。
2.2 innodb儲存引擎
innodb屬儲存引擎層,是mysql的預設儲存引擎(5.1版本及以上)。innodb相較其它儲存引擎的主要特點有:支援事務、支援高併發、自動崩潰恢復、基於聚簇索引組織表資料等。我們主要關注如下問題:innodb是如何保證事務?如何支援高併發?資料如何儲存?
事務具有4個基本特徵,分別是:原子性(atomicity)、一致性(consistency)、隔離性(isolation)、永續性(duration),簡稱acid,這是標準sql規範,innodb通過自己的方式實現之。
3.1 acid特性
3.2 事務日誌
innodb 使用undo、 redo log來保證事務原子性、一致性及永續性,同時採用預寫日誌方式將隨機寫入變成順序追加寫入,提公升事務效能。
事務流程
上圖為事務寫操作執行的大致過程,整個過程中只有一次刷盤操作,即事務提交時的redo log的寫盤。其實寫盤並不一定會立馬持久化到磁碟,要看資料庫配置,預設情況下innodb_flush_log_at_trx_commit=1,即一次redo log寫盤操作會立即寫到磁碟中,是最保險的方案。
innodb中多個事務共享乙個redo log buffer, 寫盤時,會將當前buffer中的多個事務日誌持久化,而不管事務有沒有commit,而且並不是只有事務commit才會觸發redo log寫盤,其它操作如redo log buffer空間不足、觸發checkpoint、例項shutdown及binlog切換時都會觸發redo log寫盤操作。
3.3 mvcc
innodb使用mvcc機制來提公升rr隔離級別的併發性。mvcc (multi-version concurrency control)多版本併發控制協議,將讀操作分成兩類:快照讀與當前讀。讀取的是記錄的最新版本,會對返回的記錄加上鎖,確保其他事務不能併發修改。
1 select * from table where ?;
1 select * from table where ? lock in share mode;
2 select * from table where ? for update;
3 insert into table values (…);
4 update table set ? where ?;
5 delete from table where ?;
快照讀是通過undo log來實現多個版本的控制。如下圖,每個資料行:row_id 為行id,trx_id表示最近修改的事務id,db_roll_ptr為指向undo segment中undo log的指標。快照讀時,比較當前事務id與trx_id的關係,如果trx_id 小於事務id,則該條資料對當前事務可見,反之不可見,不可見時再通過db_roll_ptr查詢歷史版本記錄,取出可見的最近的歷史記錄。undo log 的鏈路不會很深,後台purge執行緒定期清除無用的歷史版本(在沒有活動事務依賴時,undo log即可被刪除)。
3.4 加鎖分析:總結於何登成的《 innodb加鎖處理分析》
當前讀都會加鎖,怎麼加?則要看具體情景——隔離級別及索引情況。
在innodb的rr隔離級別下,對於同一條sql語句:
gap鎖的意義:當前事務佔住間隙範圍,避免其它事務往這個範圍插入資料,引起幻讀,只發生在rr隔離級別。如果id列是唯一索引(或主鍵索引 ),且當前讀條件語句中的id不存在時,innodb也會給範圍加gap鎖。
使用索引的優點:減少需要掃瞄的資料量,避免檔案排序及臨時表,將隨機i/o變為順序i/o等,從而達到更快的讀寫資料。innodb採用b+樹的結構來組織索引。
4.1 b+樹
innodb之所以採用b+樹來組織索引,是由其扁平化的結構決定的。非葉子節點記錄索引列的key值,真實資料只存於葉子節點,這樣的好處是非葉子節點很適合做快取(乙個大節點約16k,能儲存1200多個key值)。真實資料庫中的b+樹是非常扁平的,高度為3時容量可達22gb;高度為4時則可儲存26tb;另外大節點之間用雙向鍊錶互連,方便順序掃瞄。
4.2 聚簇索引及二級索引
二級索引:innodb二級索引的葉節點儲存的是主鍵id,查詢資料時,先索引到主鍵id,再回聚簇表查詢資料詳情,需要走兩次索引查詢。主鍵的資料型別盡量要小,它直接影響索引樹的儲存空間。
4.3 高效能索引策略
正確地建立和使用索引是實現高效能查詢的基礎。
sql優化跟索引息息相關,需要具體場景具體分析。explain之後,關注有沒有走預期的索引,有沒有檔案排序,掃瞄多少資料量等等。
後端rd在日常工作中會經常遇到mysql死鎖及慢查詢問題,帶著這些問題,我們能更快的去了解innodb的事務及索引原理;反之,理解了原理,再回顧之前遇到的場景,也能豁然。通過本文希望大家能理解innodb是如何保證事務?如何支援高併發?資料如何儲存?
參考
InnoDB聚集索引,輔助索引,覆蓋索引,聯合索引
聚集索引就是按照每張表的主鍵id和指向葉子結點的偏移量作為b 樹的非葉子結點,行記錄資料作為葉子結點,葉子結點也稱之為資料頁,且葉子結點通過雙向鍊錶連線。由於一張資料表只有乙個主鍵,因此一張資料表也只能有乙個聚集索引。聚集索引結構是b 樹且葉子結點通過雙向鍊錶連線,所以對於主鍵的排序查詢和範圍查詢都...
update會鎖表嗎?
update會鎖表嗎?兩種情況 1.帶索引 2.不帶索引 前提介紹 方式 採用命令列的方式來模擬 1.mysq由於預設是開啟自動提交事務,所以首先得檢視自己當前的資料庫是否開啟了自動提交事務。命令 select autocommit 結果如下 autocommit 0 如果是1,那麼執行命令 set...
mysql null會導致索引失效嗎
網上很多部落格中都寫到 is null is not null 無法使用索引 首先說下,該結論經過驗證是錯誤的。現在通過例項來驗證下 我的myslq版本是 5.7.28 建表語句 create table t union index id bigint 20 not null auto increm...