中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL中InnoDB存儲引擎是如何設計的

發布時間:2021-09-26 15:01:05 來源:億速云 閱讀:116 作者:小新 欄目:數據庫

小編給大家分享一下MySQL中InnoDB存儲引擎是如何設計的,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

  MySQL 中的兩個成員 binlog 和 redo log。然而,這只是 MySQL 家族里的兩個小嘍啰,Mysql 可以做到高性能高可靠,靠的絕對不只有他們倆。

  MySQL 里還有什么其他成員呢?

  這其中,最底下的存儲引擎層(Storage Engines),它決定了 MySQL 會怎樣存儲數據,怎樣讀取和寫入數據,也在很大程度上決定了 MySQL 的讀寫性能和數據可靠性。

  對于這么重要的一層能力,MySQL 提供了極強的擴展性,你可以定義自己要使用什么樣的存儲引擎:InnoDB、MyISAM、MEMORY、CSV,甚至可以自己開發一個存儲引擎然后使用它。

  通常我們說 Mysql 高性能高可靠,都是指基于 InnoDB 存儲引擎的 Mysql,所以,這一講,先讓我們來看看,除了 redo log,InnoDB 里還有哪些成員,他們都有什么能力,承擔了什么樣的角色,他們之間又是怎么配合的?

  InnoDB 內存架構

  InnoDB 主要分為兩大塊:內存和磁盤,讓我們先從內存開始。

  1、Buffer Pool

  正如之前提到的,MySQL 不會直接去修改磁盤的數據,因為這樣做太慢了,MySQL 會先改內存,然后記錄 redo log,等有空了再刷磁盤,如果內存里沒有數據,就去磁盤 load。

  而這些數據存放的地方,就是 Buffer Pool。

  我們平時開發時,會用 redis 來做緩存,緩解數據庫壓力,其實 MySQL 自己也做了一層類似緩存的東西。

  MySQL 是以「頁」(page)為單位從磁盤讀取數據的,Buffer Pool 里的數據也是如此,實際上,Buffer Pool 是a linked list of pages,一個以頁為元素的鏈表。

  為什么是鏈表?因為和緩存一樣,它也需要一套淘汰算法來管理數據。

  Buffer Pool 采用基于 LRU(least recently used) 的算法來管理內存。

  2、Change Buffer

  上面提到過,如果內存里沒有對應「頁」的數據,MySQL 就會去把數據從磁盤里 load 出來,如果每次需要的「頁」都不同,或者不是相鄰的「頁」,那么每次 MySQL 都要去 load,這樣就很慢了。

  于是如果 MySQL 發現你要修改的頁,不在內存里,就把你要對頁的修改,先記到一個叫 Change Buffer 的地方,同時記錄 redo log,然后再慢慢把數據 load 到內存,load 過來后,再把 Change Buffer 里記錄的修改,應用到內存(Buffer Pool)中,這個動作叫做 merge;而把內存數據刷到磁盤的動作,叫 purge:

  merge:Change Buffer -> Buffer Pool

  purge:Buffer Pool -> Disk

  上面是 MySQL 官網對 Change Buffer 的定義,仔細看的話,你會發現里面提到:Change Buffer 只在操作「二級索引」(secondary index)時才使用,原因是「聚簇索引」(clustered indexes)必須是「唯一」的,也就意味著每次插入、更新,都需要檢查是否已經有相同的字段存在,也就沒有必要使用 Change Buffer 了;另外,「聚簇索引」操作的隨機性比較小,通常在相鄰的「頁」進行操作,比如使用了自增主鍵的「聚簇索引」,那么 insert 時就是遞增、有序的,不像「二級索引」,訪問非常隨機。

  3、Adaptive Hash Index

  MySQL 索引,不管是在磁盤里,還是被 load 到內存后,都是 B+ 樹,B+ 樹的查找次數取決于樹的深度。你看,數據都已經放到內存了,還不能“一下子”就找到它,還要“幾下子”,這空間犧牲的是不是不太值得?

  尤其是那些頻繁被訪問的數據,每次過來都要走 B+ 樹來查詢,這時就會想到,我用一個指針把數據的位置記錄下來不就好了?

  這就是「自適應哈希索引」(Adaptive Hash Index)。自適應,顧名思義,MySQL 會自動評估使用自適應索引是否值得,如果觀察到建立哈希索引可以提升速度,則建立。

  4、Log Buffer

  Log Buffer 里的 redo log,會被刷到磁盤里。

  Operating System Cache

  在內存和磁盤之間,你看到 MySQL 畫了一層叫做 Operating System Cache 的東西,其實這個不屬于 InnoDB 的能力,而是操作系統為了提升性能,在磁盤前面加的一層高速緩存,這里不展開細講,感興趣的同學可以參考下維基百科:Page Cache

  InnoDB 磁盤架構

  磁盤里有什么呢?除了表結構定義和索引,還有一些為了高性能和高可靠而設計的角色,比如 redo log、undo log、Change Buffer,以及 Doublewrite Buffer 等等。

  1、表空間(Tablespaces)

  可以看到,Tablespaces 分為五種:The System Tablespace;File-Per-Table Tablespaces;General Tablespace;Undo Tablespaces;Temporary Tablespaces。

  其中,我們平時創建的表的數據,可以存放到 The System Tablespace 、File-Per-Table Tablespaces、General Tablespace 三者中的任意一個地方,具體取決于你的配置和創建表時的 sql 語句。

  2、Doublewrite Buffer

  如果說 Change Buffer 是提升性能,那么 Doublewrite Buffer 就是保證數據頁的可靠性。

  前面提到過,MySQL 以「頁」為讀取和寫入單位,一個「頁」里面有多行數據,寫入數據時,MySQL 會先寫內存中的頁,然后再刷新到磁盤中的頁。

  這時問題來了,假設在某一次從內存刷新到磁盤的過程中,一個「頁」刷了一半,突然操作系統或者 MySQL 進程奔潰了,這時候,內存里的頁數據被清除了,而磁盤里的頁數據,刷了一半,處于一個中間狀態,不尷不尬,可以說是一個「不完整」,甚至是「壞掉的」的頁。

  有同學說,不是有 Redo Log 么?其實這個時候 Redo Log 也已經無力回天,Redo Log 是要在磁盤中的頁數據是正常的、沒有損壞的情況下,才能把磁盤里頁數據 load 到內存,然后應用 Redo Log。而如果磁盤中的頁數據已經損壞,是無法應用 Redo Log 的。

  所以,MySQL 在刷數據到磁盤之前,要先把數據寫到另外一個地方,也就是 Doublewrite Buffer,寫完后,再開始寫磁盤。Doublewrite Buffer 可以理解為是一個備份(recovery),萬一真的發生 crash,就可以利用 Doublewrite Buffer 來修復磁盤里的數據。

以上是“MySQL中InnoDB存儲引擎是如何設計的”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

梁山县| 铁力市| 西乡县| 南汇区| 梓潼县| 道孚县| 和田县| 开平市| 松滋市| 神农架林区| 瑞安市| 达拉特旗| 基隆市| 烟台市| 贵溪市| 神农架林区| 治多县| 陇南市| 宁明县| 香河县| 奈曼旗| 开鲁县| 桓台县| 海口市| 渝中区| 临泽县| 毕节市| 肃北| 林西县| 河间市| 营口市| 女性| 班玛县| 屯昌县| 通州市| 清水县| 怀远县| 湘潭县| 淮阳县| 长武县| 浮梁县|