站長資訊網
        最全最豐富的資訊網站

        MySQL存儲引擎詳解之InnoDB架構

        本篇文章給大家帶來了關于mysql的相關知識,其中主要介紹了關于存儲引擎InnoDB架構的相關內容,InnoDB是MySQL的默認引擎,一個支持事務安全的存儲引擎,下面一起來看一下,希望對大家有幫助。

        MySQL存儲引擎詳解之InnoDB架構

        程序員必備接口測試調試工具:立即使用
        Apipost = Postman + Swagger + Mock + Jmeter
        Api設計、調試、文檔、自動化測試工具
        后端、前端、測試,同時在線協作,內容實時同步

        推薦學習:mysql視頻教程

        目前MySQL8.x版本數據庫已經支持了很多存儲引擎了,但是一般我們常用的就幾種,容易形成思維固化不會輕易采取其他存儲引擎,從而錯失很多優化存儲的功能。因此對現支持的九種數據庫存儲引擎的功能有個清楚的理解是個值得學習的事情。本篇文章將這八種數據庫存儲引擎的功能和作用以及使用場景都講清楚。

        此系列文章將被納入我的專欄一文速學SQL各類數據庫操作,基本覆蓋到使用SQL處理日常業務以及常規的查詢建庫分析以及復雜操作方方面面的問題。從基礎的建庫建表逐步入門到處理各類數據庫復雜操作,以及專業的SQL常用函數講解都花費了大量時間和心思創作,如果大家有需要從事數據分析或者數據開發的朋友推薦訂閱專欄,將在第一時間學習到最實用常用的知識。此篇博客篇幅較長,值得細讀實踐一番,我會將精華部分挑出細講實踐。博主會長期維護博文,有錯誤或者疑惑可以在評論區指出,感謝大家的支持。

        一、支持的存儲引擎

        進入MySQL的數據庫查看存儲引擎就可以看到MySQL數據庫所有支持的存儲引擎:

        SHOW ENGINES
        登錄后復制

        MySQL存儲引擎詳解之InnoDB架構

        目前有一個引擎Federated不支持,我們只需要清楚其他八種數據庫存儲就好。

        MySQL中常見的數據庫引擎有MyISAM、InnoDB、Memory。那么我們就先清楚這三種引擎。

        二、InnoDB引擎

        InnoDB是MySQL的默認引擎,一個支持事務安全的存儲引擎。mysql中數據是存儲在物理磁盤上的,而真正的數據處理又是在內存中執行的。由于磁盤的讀寫速度非常慢,如果每次操作都對磁盤進行頻繁讀寫的話,那么性能就會非常差。

        為了上述問題,InnoDB將數據劃分為若干頁,以頁作為磁盤與內存交互的基本單位,一般頁的大小為16KB。這樣的話,一次性至少讀取1頁數據到內存中或者將1頁數據寫入磁盤。通過減少內存與磁盤的交互次數,從而提升性能。

        這本質上就是一種典型的緩存設計思想,一般緩存的設計基本都是從時間維度或者空間維度進行考量的:

        • 時間維度:如果一條數據正在在被使用,那么在接下來一段時間內大概率還會再被使用。可以認為熱點數據緩存都屬于這種思路的實現。

        • 空間維度:如果一條數據正在在被使用,那么存儲在它附近的數據大概率也會很快被使用。InnoDB的數據頁和操作系統的頁緩存則是這種思路的體現。

        下面是官方的InnoDB引擎結構圖,主要分為內存結構和磁盤結構兩大部分。

        MySQL存儲引擎詳解之InnoDB架構

        內存結構主要包括Buffer Pool、Change Buffer、Adaptive Hash Index和Log Buffer四大組件。

        1.Buffer Pool

        Buffer Pool由包含數據、索引、insert buffer ,adaptive hash index,lock 信息及數據字典。緩沖池,簡稱BP。BP以Page頁為單位,默認大小16K,BP的底層采用鏈表數據結構管理Page。在InnoDB訪問表記錄和索引時會在Page頁中緩存,以后使用可以減少磁盤IO操作,提升效率。

        緩沖池簡單來說就是一塊內存區域,通過內存的速度來彌補磁盤速度較慢對數據庫性能的影響。在數據庫中進行讀取頁的操作,首先將從磁盤讀到的頁存放在緩沖池中,這個過程稱為將頁"FIX"在緩沖池中。下一次再讀取相同的頁時,首先判斷該頁是否在緩沖池中。若在緩沖池中,稱該頁在緩沖池中被命中。直接讀取該頁。否則讀取磁盤上的頁。對于數據庫中頁的修改操作,則首先修改在緩沖池中的頁,然后再以一定的頻率刷新到磁盤上。這里需要注意的是,頁從緩沖池刷新回磁盤的操作并不是每次頁發生更新時觸發,而是通過一種稱為Checkpoint的機制刷新回磁盤。同樣這也是為了提高數據庫的整體性能。

        傳統LUR算法

        緩沖池是通過LRU(Latest Recent Used,最近最少使用)算法來進行管理的,即最頻繁使用的頁在LRU列表的最前段,而最少使用的頁在LRU列表的尾端,當緩沖池不能存放新讀取到的頁時,首先釋放LRU列表尾端的頁:

        (1)頁已經在緩沖池里,那就只做“移至”LRU頭部的動作,而沒有頁被淘汰;

        (2)頁不在緩沖池里,除了做“放入”LRU頭部的動作,還要做“淘汰”LRU尾部頁的動作;

        但是InnoDB的LUR算法并不是傳統的LUR算法。

        這里有兩個問題:

        (1)預讀失效;

        (2)緩沖池污染;

        我們先了解什么是預讀;

        預讀

        磁盤讀寫,并不是按需讀取,而是按頁讀取,一次至少讀一頁數據(一般是4K),如果未來要讀取的數據就在頁中,就能夠省去后續的磁盤IO,提高效率。數據訪問,通常都遵循“集中讀寫”的原則,使用一些數據,大概率會使用附近的數據,這就是所謂的“局部性原理”,它表明提前加載是有效的,確實能夠減少磁盤IO。

        預讀失效

        由于預讀(Read-Ahead),提前把頁放入了緩沖池,但最終MySQL并沒有從頁中讀取數據,稱為預讀失效。

        要優化預讀失效,思路是:

        (1)讓預讀失敗的頁,停留在緩沖池LRU里的時間盡可能短;

        (2)讓真正被讀取的頁,才挪到緩沖池LRU的頭部;

        以保證,真正被讀取的熱數據留在緩沖池里的時間盡可能長。

        具體方法是:

        (1)將LRU分為兩個部分:

        新生代(new sublist)

        老生代(old sublist)

        (2)新老生代收尾相連,即:新生代的尾(tail)連接著老生代的頭(head);

        (3)新頁(例如被預讀的頁)加入緩沖池時,只加入到老生代頭部:

        如果數據真正被讀取(預讀成功),才會加入到新生代的頭部

        如果數據沒有被讀取,則會比新生代里的“熱數據頁”更早被淘汰出緩沖池

        新老生代改進版LRU仍然解決不了緩沖池污染的問題。

        2.Log Buffer

        Log Buffer用來緩存重做日志。

        InnoDB有兩個非常重要的日志:undo log、redo log

        (1)通過undo log可以看到數據較早版本,實現MVCC,或回滾事務等功能。

        (2)通過redo log用來保證事務持久性。

        MySQL存儲引擎詳解之InnoDB架構

        redo日志緩沖區是內存存儲區域,用于保存要寫入磁盤上的日志文件的數據。日志緩沖區大小由innodb_log_buffer_size 變量定義,默認大小為16MB。

        日志緩沖區的內容定期刷新到磁盤。較大的日志緩沖區可以運行大型事務,而無需在事務提交之前將重做日志數據寫入磁盤。因此,如果有更新,插入或刪除許多行的事務,則增加日志緩沖區的大小可以節省磁盤I/O。

        innodb_flush_log_at_trx_commit :控制如何將日志緩沖區的內容寫入并刷新到磁盤。

        innodb_flush_log_at_timeout :控制日志刷新頻率。

        如果磁盤I/O導致性能問題,則需要觀察事務,例如涉及許多BLOB條目的事務。只要InnoDB日志緩沖區已滿,便會將其刷新到磁盤,因此增加緩沖區大小可以減少I/O。

        日志文件的缺省數量為兩個: ib_logfile0 和 ib_logfile1 。

        日志具有固定大小,默認大小取決于MySQL版本。

        3.Adaptive Hash Index

        Adaptive Hash Index自適應hash索引是一種鍵值對的存儲結構,存儲的是熱點頁所在的記錄。InnoDB存儲引擎會自動根據訪問的頻率和模式 來為某些頁建立哈希索引。

        MySQL存儲引擎詳解之InnoDB架構

        上面的圖就是區分B+樹索引和自適應hash索引的區別。 通過參數innodb_adaptive_hash_index來禁用或啟動此特性,默認為開啟。

        4.Change Buffer

        Change Buffer:MySQL中數據分為內存和磁盤兩個部分;在buffer pool中緩存熱的數據頁和索引頁,減少磁盤讀;通過change buffer就是為了緩解磁盤寫的一種手段。

        當需要更新一個數據頁時,如果數據頁在內存中就直接更新。如果數據頁不在內存中。在不影響數據一致性的前下,InooDB 會將這些更新操作緩存在 change buffer 中,這樣就不需要從磁盤中讀入這個數據頁了。在下次查詢需要訪問這個數據頁的時候,將數據頁讀入內存,然后執行 change buffer 中與這個頁有關的操作。通過這種方式就能保證這個數據邏輯的正確性。

        雖然名字叫作 change buffer,實際上它是可以持久化的數據。也就是說,change buffer 在內存中有拷貝,也會被寫入到磁盤上(ibdata)。

        ?將 change buffer 中的操作合并到原數據頁,得到最新結果的過程稱為 merge。以下情況會觸發merge:

        • 訪問這個數據頁;

        • 后臺master線程會定期 merge;

        • 數據庫緩沖池不夠用時;

        • 數據庫正常關閉時;

        • redo log寫滿時;

        change buffer就是在非唯一普通索引頁不在buffer pool中時,對頁進行了寫操作的情況下,先將記錄變更緩沖,等未來數據被讀取時,再將 change buffer 中的操作merge到原數據頁的技術。在MySQL5.5之前,叫插入緩沖(insert buffer),只針對insert做了優化;現在對delete和update也有效,叫做寫緩沖(change buffer)。

        推薦學習:mysql視頻教程

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 无码8090精品久久一区| 人人妻人人澡人人爽人人精品| 久久久精品无码专区不卡| 国内精品久久久久久99蜜桃 | 国产精品H片在线播放| 日韩国产成人精品视频| 久久精品国产一区二区电影| 五月花精品视频在线观看| 国内精品久久久久影院一蜜桃| 四虎精品成人免费视频| 国产精品乱视频| 日韩麻豆国产精品欧美| 国产精品精品自在线拍| 亚洲中文字幕久久精品无码APP | 精品成人一区二区三区四区| 久久综合九色综合精品| 国产午夜精品久久久久免费视 | 欧美日韩国产精品| 国语自产精品视频| 国产精品久久久99| 成人精品一区二区三区| 精品综合久久久久久97超人| A级精品国产片在线观看| 人妻少妇精品无码专区二区| 亚洲精品乱码久久久久66| 亚洲精品WWW久久久久久| 日韩三级精品| 亚洲国产成人精品无码久久久久久综合 | 四虎最新永久在线精品免费| 国产日韩精品在线| 国产韩国精品一区二区三区久久| 国产精品福利自产拍在线观看| 精品免费久久久久久久| 老司机亚洲精品影院| 日韩精品无码免费一区二区三区| 亚洲线精品一区二区三区影音先锋| 日本精品久久久久影院日本| 男人的天堂精品国产一区| 日韩欧美国产精品第一页不卡| 亚洲精品美女久久久久99小说| 亚洲欧美日韩国产一区二区三区精品 |