輔助索引會觸發鎖嗎 InnoDB事務及索引原理

2021-10-16 09:37:22 字數 3523 閱讀 3466

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...