這篇文章帶給大家的內容是關於MySQL中InnoDB儲存引擎的詳細介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
在MySQL中InnoDB屬於儲存引擎層,並以外掛程式的形式整合在資料庫中。從MySQL5.5.8開始,InnoDB成為其預設的儲存引擎。 InnoDB儲存引擎支援事務、其設計目標主要為面向OLTP的應用,主要特點有:支援事務、行鎖設計支援高並發、外鍵支援、自動崩潰復原、叢集索引的方式組織表結構等。 (相關推薦:MySQL教學)
#體系架構
#InnoDB儲存引擎是由記憶體池、後台執行緒、磁碟儲存三大部分組成。
執行緒
InnoDB 使用的是多執行緒模型, 其後台有多個不同的執行緒負責處理不同的任務
Master Thread
Master Thread是最核心的一個後台線程,主要負責將緩衝池中的資料非同步刷新到磁碟,保證資料的一致性。包括髒頁刷新、合併插入緩衝、UNDO頁的回收等。
IO Thread
在 InnoDB 儲存引擎中大量使用了非同步IO(Async IO)來處理寫入IO請求, IO Thread的工作主要是負責這些 IO 請求的回呼。
Purge Thread
交易提交後,其所使用的undo log可能不再需要,因此需要Purge Thread來回收已經指派並使用的UNDO頁。 InnoDB支援多個Purge Thread, 這樣做可以加快UNDO頁的回收,提高CPU的使用率以及提升儲存引擎的效能。
Page Cleaner Thread
Page Cleaner Thread的作用是取代Master Thread中髒頁刷新的操作,其目的是減輕原Master Thread的工作及對於用戶查詢線程的阻塞,進一步提高InnoDB儲存引擎的效能。
記憶體
InnoDB 儲存引擎記憶體的結構
#緩衝池
InnoDB存儲引擎是基於磁碟儲存的,並將其中的記錄按照頁的方式進行管理。但是由於CPU速度和磁碟速度之間的鴻溝,基於磁碟的資料庫系統通常使用緩衝池記錄來提高資料庫的整體效能。
緩衝池其實就是透過記憶體的速度來彌補磁碟速度較慢對資料庫效能的影響。在資料庫進行讀取操作時,首先將磁碟中的頁放入緩衝池中,下次再讀取相同頁時,首先從緩衝池中獲取該頁數據,起到高速緩存的作用。
資料的修改操作,則首先修改在緩衝池中的頁數據,然後使用稱為Checkpoint的機制刷新到磁碟上。
緩衝池的大小直接影響資料庫的整體效能,對於InnoDB儲存引擎而言,緩衝池配置透過參數 innodb_buffer_pool_size 來設定。使用SHOW VARIABLES LIKE 'innodb_buffer_pool_size'
指令可查看緩衝池配置:
mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_size' \G *************************** 1. row *************************** Variable_name: innodb_buffer_pool_size Value: 134217728 1 row in set (0.01 sec)
緩衝池中快取的資料頁類型有: 索引頁、undo頁、插入緩衝、自適應雜湊索引、InnoDB鎖定資訊、資料字典資訊等,索引頁和資料頁佔緩衝池很大的一部分。
重做日誌緩衝
緩衝池中的頁資料比磁碟要新時,需要將新資料刷新到磁碟中。 InnoDB採用Write Ahead Log策略來刷新數據,即當交易提交時,先寫入重做日誌緩衝,重做日誌緩衝會按一定頻率刷新到重置日誌文件中,然後臟頁會根據checkpoint機制刷新到磁碟。
重做日誌緩衝不需要設定很大,通常8M能滿足大部分的應用場景。重做日誌支援一下三種情況觸發刷新:
Master Thread每一秒將重做日誌緩衝刷新到重做日誌檔案
每次交易提交時將重做日誌緩衝刷新到重做日誌檔案
當重做日誌緩衝池剩餘空間小於1/2時,重做日誌緩衝刷新到重做日誌檔案
額外記憶體池
在InnoDB儲存引擎中,對記憶體的管理是透過一種稱為內存堆的方式進行的。在對一些資料結構本身的記憶體進行分配時,需要從額外的記憶體池中進行申請,當該區域的記憶體不夠時,會從緩衝池中進行申請。
鎖定
InnoDB支援的鎖定有:
共用鎖定與排它鎖定
意向鎖定
-
記錄鎖定
# 間隙鎖定
自增鎖
共享鎖定與排他鎖定
InnoDB引擎實現了兩種標準的行級鎖,共享鎖(shared (S) locks) 和排他鎖(exclusive (X) locks)。共享鎖允許一個佔有鎖的事務去讀取一行數據,排它鎖則允許事務對某一行記錄進行寫入操作。
如果一個交易持有了一個共享鎖,其他交易仍然可以取得這行記錄的共享鎖,但不能取得到這行記錄的排它鎖。當一個事務取得到了某一行的排它鎖,則其他事務將無法再取得這行記錄的共用鎖定和排它鎖。
意向鎖定
在InnoDB中,意向鎖定是一種表格層級鎖定,分為共享鎖定和排他鎖定:
- ##意圖共享鎖定:將要去取得某一行的共享鎖定
- 意向排它鎖定:將要去取得某一行的排它鎖定 ##交易在取得共享/排它鎖之前必須先獲取意向共享/排它鎖,意向鎖不會阻塞其他任何對錶的操作,他只是告訴其他事務他將要去獲取某一行的共享鎖或者排他鎖。
記錄鎖定
記錄是是作用在索引上的一種鎖,他鎖住的是某一筆記錄的索引而非記錄本身,如果目前表沒有索引那麼InnoDB將會為其建立一個隱藏的聚集索引,而Record Locks將會鎖定這個隱藏的聚集索引。
間隙鎖定
間隙鎖和記錄鎖一樣也是作用在索引上,不同的是記錄鎖定只作用於一條索引記錄而間隙鎖可以鎖住一個範圍內的索引。間隙鎖在InnoDB的唯一功能就是防止其他事務的插入操作,以防止幻讀的發生。
自增鎖
自增鎖是一種特殊的表級鎖,他只作用在包含自增列的插入操作時。當一個事務正在插入一條資料時,其他的任何事務都必須等待整個事務完成插入操作,在取獲取鎖定來執行插入操作。
事務ACID
交易是資料庫作為OLTP最重要的特性,說起事務不得不提起ACID四個基本特性:
- 原子性(Atomicity) :事務最小工作單元,要麼全成功,要麼全失敗
- 一致性(Consistency): 事務開始與結束後,資料庫的完整性不會被破壞
- 隔離性(Isolation) :不同交易之間互不影響,四種隔離等級為RU(讀未提交)、RC(讀取已提交)、RR(可重複讀取)、SERIALIZABLE (串行化)
- 持久性(Durability) :交易提交後,對資料的修改是永久性的,即使系統故障也不會遺失
- InnoDB的原子性、持久性和一致性主要是透過Redo Log、Undo Log和Force Log at Commit機制機制來完成的。 Redo Log用於在崩潰時恢復數據,Undo Log用於對事務的影響進行撤銷,也可以用於多版本控制。而Force Log at Commit機制保證交易提交後Redo Log日誌都已經持久化。隔離性則是由鎖和MVCC來保證的。
隔離等級
在MySQL中,交易有4種隔離級別,分別是:
- Read Uncommitted 未提交讀取
- Repeatable Read 可重複讀取
- Serializable 可序列化
- 在理解四個隔離等級之前,我們需要先了解另外三個名詞:
- #髒讀
- a事務會讀取到b事務尚未提交的數據,但是b事務由於某種原因進行回滾操作,這樣,a事務讀取的數據是不可用的,進而會造成一些異常結果。
- 無法重複讀取
- a事務週期內對某一資料多次查詢,同時這些資料在b事務中進行了update或delete操作。那麼a事務每次查詢出來的結果可能都不一樣。
- 幻讀
- 幻讀的結果其實和不可重複讀是一樣的表現,差異在於不可重複讀主要是針對其他事務進行了編輯(update)和刪除(delete)操作。而幻讀主要是針對插入(insert)操作。也就是在一個事務生命週期內,會查詢到另外一個事務新插入的資料。
Read uncommitted 未提交讀取
未提交讀取,這種情況下,一個事務a可以看到另一個事務b未提交的數據,如果此時事務b發生回滾,那麼事務a拿到的就是髒數據,這也就是髒讀的意思。
此隔離等級在MySQL InnoDB一般不建議使用。
Read Committed 已提交讀取
已提交讀取,一個交易從開始直到提交之前,所做的任何修改對其他交易都是不可見的。解決了髒讀問題,但是有幻讀現象。
Repeatable Read 可重複讀取
可重複讀,該等級保證在同一交易中多次讀取同樣記錄的結果是一致的,在InnoDB儲存引擎中同時解決了幻讀和不可重複讀問題。
InnoDB引擎透過使用Next-Key Lock
解決了幻讀的問題。 Next-Key Lock
是行鎖定和間隙鎖定的組合,當InnoDB掃描索引記錄的時候,會先對索引記錄加上行鎖(Record Lock),再對索引記錄兩邊的間隙加上間隙鎖(Gap Lock)。加上間隙鎖之後,其他事務就不能在這個間隙修改或插入記錄。
Serializable 可串行化
Serializable 是最高的隔離級別,它透過強制事務串行執行,避免了幻讀的問題,但是Serializable 會在讀取的每一行資料上都加鎖,所以可能導致大量的超時和鎖爭用的問題,因此並發度急劇下降,在MySQL InnoDB同樣不被建議使用。
開啟交易
BEGIN、BEGIN WORK、START TRANSACTION
執行BEGIN指令不會真正在引擎層開啟新事務,只是為目前執行緒設定標記,表示為明確開啟的事務。
START TRANSACTION READ ONLY
# 開啟只讀事務,當MySQL Server接收到任何資料變更的SQL時,都會直接拒絕修改並回傳錯誤,此錯我不會進入引擎層。
START TRANSACTION READ WRITE
# 允許super使用者在目前執行緒只讀狀態為true的情況下啟動讀取和寫入事務。
START TRANSACTION WITH CONSISTENT SNAPSHOT
開啟事務會進入引擎層,並開啟一個readview
。只有在RR隔離等級下,這種操作才有效,否則會報錯。
Undo log
在資料進行修改時會記錄對應的undo日誌,如果交易失敗或回滾,可以藉助記錄的undo日誌進行回溯。 Undo log是邏輯日誌,記錄變更前的資料鏡像。在修改時如果同時需要讀取目前資料的時候,它可以根據版本資訊分析出該行記錄先前版本的資料。另外Undo log也會產生重做日誌,因為Undo log也要進行持久化保護。
事務提交
使用全域事務ID產生器產生交易NO,將目前連接的事務指標(
trx_t
)新增至全域提交事務鍊錶(trx_serial_list
)中標記undo,如果這個交易只使用了一個UndoPage且使用量小於3/4個Page,則把這個Page標記為
TRX_UNDO_CACHED
,如果不滿足且是insert undo
則標記為TRX_UNDO_TO_FREE
,否則undo為update undo則標記為TRX_UNDO_TO_PURGE
。標示為TRX_UNDO_CACHED
的undo會被引擎回收。把
update undo
放入所在undo segment
的history list
,並遞增rseg_history_len
(全域)。同時更新Page上的TRX_UNDO_TRX_NO
, 如果刪除了數據,則重置delete_mark
- ##把
undate undo
從
update_undo_list中刪除,如果被標記為
TRX_UNDO_CACHED,則加入到
update_undo_cached佇列中
- ##mtr_commit
(日誌undo/redo寫入公共緩衝區),至此,在檔案層級事務提交。這時候即使crash,重啟後仍能保證事務是被提交的。接下來要做的是記憶體資料狀態的更新(
trx_commit_in_memory
) 只讀交易只需要把 - readview
從全域
readview
鍊錶移除,然後重置trx_t
結構體裡面的資訊即可。讀寫事務首先需要是設定交易狀態為TRX_STATE_COMMITTED_IN_MEMORY
,釋放所有行鎖定並且將trx_t
從rw_trx_list
中移除,readview
#從全域readview
鍊錶移除。如果有insert undo
則在這裡移除,如果有update undo
則喚醒Purge執行緒進行垃圾清理,最後重置trx_t
裡的訊息,便於下一個事務使用 回滾
- 如果是唯讀事務,則直接傳回
- 判斷目前是回滾整個事務還是部分事務,如果是部分事務,則記錄下需要保留多少個Undo log,多餘的全進行回滾
- 從
- update undo
和
insert undo
中找出最後一條undo,從這條undo開始回滾 如果是 - update undo
則將標記為刪除的記錄清理標記,更新過的資料回滾到最老的版本。如果是
insert undo
則直接刪除聚集索引和二級索引 如果所有undo都已經被回滾或回滾到了指定的undo則停止,把Undo log刪除
索引
InnoDB引擎使用B 樹作為索引結構,主鍵索引的葉子節點data域保存了完整的字段數據,非主鍵索引的葉子節點保存了指向主鍵的值數據。
上圖是 InnoDB 主索引(同時也是資料檔案)的示意圖,可以看到葉節點包含了完整的資料記錄,這種索引叫做聚集索引。因為InnoDB 的資料檔案本身要按主鍵聚集,所以InnoDB 要求表必須有主鍵,如果沒有明確指定,則MySQL 系統會自動選擇一個可以唯一標識資料記錄的列作為主鍵,如果不存在這種列,則MySQL 會自動為InnoDB 表產生一個隱含欄位作為主鍵,這個欄位長度為6個位元組,類型為長整形。
InnoDB 的輔助索引 data 網域儲存對應記錄主鍵的值而不是位址。換句話說,InnoDB 的所有輔助索引都引用主鍵作為 data 域。聚集索引這種實作方式使得按主鍵的搜尋十分高效,但是輔助索引搜尋需要擷取兩遍索引:先擷取輔助索引取得主鍵,然後用主鍵到主索引中擷取取得記錄。
#以上是MySQL中InnoDB儲存引擎的詳細介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

InnoDBBufferPool通過緩存數據和索引頁來減少磁盤I/O,提升數據庫性能。其工作原理包括:1.數據讀取:從BufferPool中讀取數據;2.數據寫入:修改數據後寫入BufferPool並定期刷新到磁盤;3.緩存管理:使用LRU算法管理緩存頁;4.預讀機制:提前加載相鄰數據頁。通過調整BufferPool大小和使用多個實例,可以優化數據庫性能。

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

MySQL值得學習,因為它是強大的開源數據庫管理系統,適用於數據存儲、管理和分析。 1)MySQL是關係型數據庫,使用SQL操作數據,適合結構化數據管理。 2)SQL語言是與MySQL交互的關鍵,支持CRUD操作。 3)MySQL的工作原理包括客戶端/服務器架構、存儲引擎和查詢優化器。 4)基本用法包括創建數據庫和表,高級用法涉及使用JOIN連接表。 5)常見錯誤包括語法錯誤和權限問題,調試技巧包括檢查語法和使用EXPLAIN命令。 6)性能優化涉及使用索引、優化SQL語句和定期維護數據庫。

MySQL適合初學者學習數據庫技能。 1.安裝MySQL服務器和客戶端工具。 2.理解基本SQL查詢,如SELECT。 3.掌握數據操作:創建表、插入、更新、刪除數據。 4.學習高級技巧:子查詢和窗口函數。 5.調試和優化:檢查語法、使用索引、避免SELECT*,並使用LIMIT。

MySQL通過表結構和SQL查詢高效管理結構化數據,並通過外鍵實現表間關係。 1.創建表時定義數據格式和類型。 2.使用外鍵建立表間關係。 3.通過索引和查詢優化提高性能。 4.定期備份和監控數據庫確保數據安全和性能優化。

MySQL是一個開源的關係型數據庫管理系統,廣泛應用於Web開發。它的關鍵特性包括:1.支持多種存儲引擎,如InnoDB和MyISAM,適用於不同場景;2.提供主從復制功能,利於負載均衡和數據備份;3.通過查詢優化和索引使用提高查詢效率。

SQL用於與MySQL數據庫交互,實現數據的增、刪、改、查及數據庫設計。 1)SQL通過SELECT、INSERT、UPDATE、DELETE語句進行數據操作;2)使用CREATE、ALTER、DROP語句進行數據庫設計和管理;3)複雜查詢和數據分析通過SQL實現,提升業務決策效率。

MySQL的基本操作包括創建數據庫、表格,及使用SQL進行數據的CRUD操作。 1.創建數據庫:CREATEDATABASEmy_first_db;2.創建表格:CREATETABLEbooks(idINTAUTO_INCREMENTPRIMARYKEY,titleVARCHAR(100)NOTNULL,authorVARCHAR(100)NOTNULL,published_yearINT);3.插入數據:INSERTINTObooks(title,author,published_year)VA


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

記事本++7.3.1
好用且免費的程式碼編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。