MySQL源碼學習(六):線性預讀

      網友投稿 774 2025-03-31

      InnoDB為了盡可能的讓用戶經常讀取的數據都放在內存中,以減少磁盤的IO次數,提高讀性能,加入了預讀特性。這個特性會將用戶很有可能使用到的數據預先加載到buffer pool中,當用戶使用到這個數據時,就不必再從磁盤上讀入,從而提升了數據的讀取性能。


      然而一般數據庫存儲的數據量都會遠遠大于內存,innodb不可能全部都加載到內存中,對加載數據的選擇,決定了預讀是否能夠有效提升整體性能。

      預讀的模式

      Innodb一共提供了兩種預讀模式:線性預讀和隨機預讀。兩種模式使用不同的算法來預測用戶可能用到的數據,并把這些數據異步地從磁盤中加載到buffer pool中,以備使用。

      MySQL源碼學習(六):線性預讀

      ·???????? 線性預讀

      線性預讀是以extend為單位的。通過判斷當前的extend中的數據是否是連續訪問的,并以此來預測是否有必要把下一個extend提前從磁盤文件中讀取出來,加載到buffer pool中。本文主要分析線性預讀的使用和原理。

      ·???????? 隨機預讀

      隨機預讀針對的是當前extend,通過判斷當前extend中的page被讀取的次數,來預測是否有必要把當前extend的數據加載到buffer pool中。在MySQL 5.5之后基本已經廢棄了隨機預讀,因此后面的版本隨機預讀默認是關閉的。

      預讀的使用

      MySQL5.5之后的版本安裝好以后默認使用的是線性預讀模式。因此無需額外配置就能使用。

      與線性預讀相關的配置參數,是innodb_read_ahead_threshold,這個參數表示:當一個extend中,大于等于innodb_read_ahead_threshold個page是被連續訪問的時候,就預先加載下一個extend的數據。默認值是56,最大值64,最小值0。如果設置為0,則關閉線性預讀。(除非顯式打開隨機預讀,否則如果關閉了線性預讀,也不會自動打開隨機預讀,此時整個預讀功能就關閉了)。

      線性預讀的原理

      從上面的說明中,大家可能大概了解了線性預讀的使用,然而對于像筆者一樣的初學者來說,很多概念其實并沒有真正了解其中的含義,因此也就不能指導我們更好的使用預讀功能。比如:什么叫做“數據是被連續訪問的”,為什么innodb_read_ahead_threshold的最大值是64等等,下面通過對線性預讀的源碼,來看這個深入理解功能是如何運作的。

      線性預讀入口函數在:storage/innobase/buf目錄下的buf0rea.cc文件中,函數名:buf_read_ahead_linear。

      ·???????? Extend的邊界

      我們知道innodb對數據的組織,是:tablespace -> segment -> extend -> page -> row這樣的組織順序。1個extend的大小固定為1M,1個page的默認大小是16K,那么1個extend最大可以容納64個Page,并且extend中的page一定是連續存儲的。這也就是為什么innodb_read_ahead_threshold的最大值是64,同時也可以看到,對數據連續訪問的判斷,也僅限制在一個extend中,不會跨越extend.

      那么代碼中如何區分extend的呢(此處吐槽一下MySQL源代碼,如果不事先了解這些概念就,會發現代碼中連extend這個關鍵字都沒有)

      請看圖1,532和534行就是mysql獲取當前extend的邊界。

      圖1 找到當前extend

      圖2 gdb調試結果

      通過圖2的GDB調試中可以看到,其中buf_read_ahead_linear_area為64(因為page大小是可以更改的,因此并不是一個常量,而是計算出來的)。Page number是201,通過532和534兩行簡單的就計算出extend的上下邊界。上圖page 201所在的extend,就是由Page 192到Page 255(這里要減1,一共64個)這些Page組成的(這里居然不封裝為一個函數。。。)。

      同時,從537行的判斷可以知道,如果page不是extend的上邊界或者下邊界,是不執行預讀的。也就是說,只有讀取到了extend的上、下邊界page,才有可能觸發預讀。

      ·???????? 預讀不會跨域表

      如圖3代碼所示,innodb會獲取page所在tablespace,并且判斷extend是否跨越了tablespace(561行,extend上限page大于space_size),如果跨越,則不會執行預讀。

      圖3 對tablespace的判斷

      ·???????? 數據被連續訪問的意義

      如圖4所示,這里就是innodb判斷數據是否是被連續訪問的算法。

      圖4 判斷連續訪問的算法

      590行,這里就是innodb_read_ahead_threshold產生作用的地方,如圖5和圖6所示:

      圖5 將innodb_read_ahead_threshold設置為2

      圖6 serv_read_ahead_threshold的值為2

      innodb_read_ahead_threshold表示了只要2個page是被連續訪問的,就進行預讀,那么此處就是計算出能夠允許(64 - 2)=62個page是沒有被連續訪問的。另外與BUF_READ_AHEAD_AREA(buf_pool)取最小值的原因是page可能不是16K,那么每個extend的page數量就一定是64了。同時,從這個邏輯也能分析出,如果page不是1K,那么innodb_read_ahead_threshold就沒有作用了。

      接下來先介紹613和614行的buf_page_is_accessed函數,從圖7中可以看到,所謂的順序依據,實際上是page的access time,也就是上一次訪問時間。

      圖7 buf_page_is_accessed函數

      再看582~586行:low是extend的第一個page位置,如果page是extend的第一個page,那么順序就是遞減(-1),如果是最后一個,那么就是遞增(1)。

      那么,595~630行的的循環邏輯相信任何一個編程者都能理解:

      如果當前page是extend的第一個,那么就看后面的63個page中,相鄰page訪問時間遞減的個數,是否≥innodb_read_ahead_threshold個。如果是,則認為可以執行線性預讀,加載上一個extend。否則不進行預讀。

      反之如果當前page是extend的最后一個,那么久看前面的63個page中,相鄰page訪問時間遞增的個數,是否≥innodb_read_ahead_threshold個。

      小結:

      線性預讀其背后的邏輯,實際上就是:如果我們在讀第一份數據的時候發現,之前的數據讀取順序是從后向前讀的,那么我們就把前一個區域的數據都加載進來。如果在讀最后一份數據的時候發現,之前的數據讀取順序是從前向后讀的,那么我們就把后面一個區域的數據加載進來。而innodb_read_ahead_threshold,就是我們認為滿足這個順序的程度。

      通過以上的解讀,我們也發現,只有在對一個表進行頻繁的的順序、或者逆序查詢時,預讀才有較好的效果。在隨機讀取的情況下,線性預讀并不能產生太大作用。

      RDS-MYSQL 云數據庫 MySQL RDS MySQL MySQL

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:average函數 excel(average函數和round函數連用)
      下一篇:excel減法(excel減法怎么操作)
      相關文章
      国产亚洲福利一区二区免费看| 久久亚洲AV无码精品色午夜| 亚洲天堂在线视频| 久热综合在线亚洲精品| 久久亚洲精品国产亚洲老地址| 亚洲精品乱码久久久久久中文字幕| 亚洲日韩AV一区二区三区四区| 亚洲精品国产品国语在线| 亚洲熟女一区二区三区| 亚洲欧美在线x视频| 亚洲宅男精品一区在线观看| 国产av无码专区亚洲av桃花庵| 久久亚洲精品无码gv| 亚洲国产AV一区二区三区四区| 亚洲人成激情在线播放| 国产亚洲精品xxx| 亚洲国产成人精品无码区在线观看| 亚洲国产a∨无码中文777| 亚洲av中文无码乱人伦在线r▽| 亚洲AV无码乱码在线观看富二代| 亚洲Av无码精品色午夜| 久久精品国产亚洲77777| 亚洲综合综合在线| 亚洲AV无码成人网站久久精品大 | 亚洲国产成人一区二区精品区| 亚洲AV成人精品网站在线播放| 亚洲美日韩Av中文字幕无码久久久妻妇| 亚洲乱码在线卡一卡二卡新区 | 亚洲一区二区女搞男| 久久久久亚洲av无码尤物| 久久久久亚洲AV无码麻豆| 久久精品国产亚洲av四虎| 久久丫精品国产亚洲av不卡| 亚洲天堂2016| 色窝窝亚洲AV网在线观看| 国产亚洲精aa成人网站| 中文字幕亚洲电影| 亚洲AV永久无码精品水牛影视| 亚洲黄色在线播放| 伊人久久五月丁香综合中文亚洲 | 亚洲国产成人精品无码区在线网站|