最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL InnoDB中的Buffer Pool用法及說明

 更新時(shí)間:2025年06月26日 11:18:30   作者:在成都搬磚的鴨鴨  
這篇文章主要介紹了MySQL InnoDB中的Buffer Pool用法及說明,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1、背景

mysql數(shù)據(jù)是存儲(chǔ)在磁盤上的,但是從磁盤上讀取數(shù)據(jù)的速度太慢,所以就需要把數(shù)據(jù)從磁盤讀取在內(nèi)存中,申請的這塊內(nèi)存就叫Buffer Pool,也就是緩存池的意思,接下來我們就來講一下Buffer Pool。

2、Buffer Pool

【1】含義

在mysql服務(wù)啟動(dòng)時(shí)會(huì)申請一塊存儲(chǔ)頁的連續(xù)內(nèi)存,這快內(nèi)存就叫Buffer Pool,Buffer Pool的大小可以通過配置文件指定,linux上的配置文件為my.cnf,windows上的配置文件為my.ini,windows上的默認(rèn)配置如下,可以根據(jù)內(nèi)存大小進(jìn)行修改,最小值為5M:

cat my.ini | grep 'innodb_buffer_pool_size'
innodb_buffer_pool_size=128M

【2】組成

Buffer Pool是由控制塊和緩存頁組成,一個(gè)控制塊對應(yīng)一個(gè)緩存頁,控制塊包含對應(yīng)緩存頁的表空間編號、頁號、緩存頁在Buffer Pool中的地址、鏈表節(jié)點(diǎn)信息、鎖、LSN信息, innodb_buffer_pool_size的大小并不包含控制塊的空間,所以再給Buffer Pool申請一塊連續(xù)的內(nèi)存時(shí)會(huì)額外申請5%的空間用于存儲(chǔ)控制塊,其組成圖如下:

在這里插入圖片描述

如果申請的連續(xù)內(nèi)存剩余空間不足以方法一個(gè)控制塊和對應(yīng)的緩存頁,這個(gè)剩余的空間就叫碎片,如果剛好能放下控制塊和對應(yīng)的緩存,碎片就不存在。

【3】free鏈表

從磁盤讀數(shù)據(jù)寫到Buffer Pool中時(shí),需要從Buffer Pool中找到空閑的緩存頁去寫入,為了方便快速找到哪些緩存頁是空閑的,就有了free鏈表,也就是所有空閑緩存頁對應(yīng)的控制塊組成的鏈表,其組成圖如下:

在這里插入圖片描述

free鏈表由鏈表基節(jié)點(diǎn)和控制塊組成,鏈表基節(jié)點(diǎn)是額外的空間,不屬于Buffer Pool,鏈表基節(jié)點(diǎn)存儲(chǔ)了空閑緩存頁對應(yīng)的控制塊的首地址和尾地址,還有空閑緩存頁的個(gè)數(shù),所有空閑緩存頁對應(yīng)的控制塊組成一個(gè)雙向鏈表。

通過free鏈表就可以很方便從中取出一個(gè)空閑緩存頁,將其對應(yīng)的控制塊填入對應(yīng)信息,然后從free鏈表中移除,再寫數(shù)據(jù)到緩存頁。

【4】哈希查找緩存頁

查找數(shù)據(jù)時(shí)需要判斷數(shù)據(jù)所在的頁是否在Buffer Pool上,為了方便查找,將表空間編號和頁號作為key與對應(yīng)的控制模塊做一個(gè)哈希表,這樣就能很方便判斷緩存頁是否在Buffer Pool。

【5】flush鏈表

修改了Buffer Pool中緩存頁的數(shù)據(jù),就需要更新磁盤,每次都更新磁盤就對性能有損耗,所以可以把要更新緩存頁收集起來一次性更新,需要更新的緩存頁就叫臟頁,所有的臟頁對應(yīng)的控制塊可以組成一個(gè)鏈表叫flush鏈表,和free鏈表類似,都是由基節(jié)點(diǎn)和控制塊組成,參考上面的free鏈表圖。

【6】LRU鏈表

當(dāng)free鏈表中找不到空閑緩存頁時(shí),就需要釋放不經(jīng)常使用的頁,所以可以把使用評率高的緩存頁放在前面,頻率低的緩存頁放在后面組成一個(gè)LRU鏈表,這個(gè)鏈表的插入和更新方式如下:

1、如果訪問的頁不在Buffer Pool中,就從磁盤加載到Buffer Pool中時(shí),把緩存頁對應(yīng)的控制塊放到鏈表的頭部,

2、如果訪問的頁在Buffer Pool中,就直接把緩存頁對應(yīng)的控制塊移動(dòng)鏈表的頭部。

但是有兩種情況,

  • 第一是InnoDB提供了預(yù)讀功能,會(huì)提前讀取認(rèn)為可能會(huì)訪問的頁到Buffer Pool中,但可能最終都沒被訪問;
  • 另一種情況全表掃描會(huì)把所有頁都加載到Buffer Pool,但很多頁后面可能不會(huì)被訪問。

所以為了解決這兩種情況把LRU鏈表分為兩部分:熱數(shù)據(jù)和冷數(shù)據(jù),也可以叫young區(qū)域和old區(qū)域,young區(qū)域存儲(chǔ)使用頻率高的緩存頁,old區(qū)域存儲(chǔ)使用頻率不是很高的緩存頁,如圖:

在這里插入圖片描述

LRU鏈表中的young區(qū)域和old區(qū)域的比例系統(tǒng)變量innodb_old_blocks_pct的值來確定,innodb_old_blocks_pct值代表old區(qū)域的百分比比例,如下:

mysql> SHOW VARIABLES LIKE 'innodb_old_blocks_pct';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_old_blocks_pct | 37    |
+-----------------------+-------+
1 row in set, 1 warning (0.00 sec)

通過young區(qū)域和old區(qū)域我們就可以對預(yù)讀和全表掃描進(jìn)行優(yōu)化,預(yù)讀優(yōu)化如下:

當(dāng)磁盤上的某個(gè)頁初次加載到Buffer Pool時(shí),就會(huì)放到old區(qū)域的頭部,如果該頁的訪問頻率低就會(huì)在old后移最終被移除。

全表掃描優(yōu)化如下:

全表掃描一樣也是初次會(huì)將所有頁放到old區(qū)域的頭部,但是后續(xù)讀取所有記錄代表訪問了頁多次,就會(huì)將頁放到y(tǒng)oung區(qū)域,但是全表掃描的數(shù)據(jù)讀取是一次性的,間隔很短,所以需要設(shè)置一個(gè)時(shí)間間隔,此間隔內(nèi)的訪問不會(huì)將頁移動(dòng)young區(qū)域。

時(shí)間間隔配置為innodb_old_blocks_time,單位為毫秒,配置如下:

mysql> SHOW VARIABLES LIKE 'innodb_old_blocks_time';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_old_blocks_time | 1000  |
+------------------------+-------+
1 row in set, 1 warning (0.00 sec)

【7】刷新臟頁到磁盤

后臺(tái)會(huì)有專門的線程會(huì)將Buffer Pool上修改過頁,也就是臟頁刷新到磁盤,刷新方式有兩種:

第一種是BUF_FLUSH_LRU

就是定時(shí)從LRU鏈表尾部掃描一些頁,發(fā)現(xiàn)臟頁就更新到磁盤,掃描頁的數(shù)量可以通過innodb_lru_scan_depth來指定。

查看配置如下:

mysql> SHOW VARIABLES LIKE 'innodb_lru_scan_depth';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024  |
+-----------------------+-------+
1 row in set, 1 warning (0.00 sec)

第二種刷新方式叫BUF_FLUSH_LIST

也就是定時(shí)從flush鏈表中刷新一部分頁到磁盤。

【8】Buffer Pool實(shí)例

可以通過innodb_buffer_pool_instances配置Buffer Pool的實(shí)例,提高并發(fā)處理速度,配置如下:

mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_instances';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 1     |
+------------------------------+-------+
1 row in set, 1 warning (0.00 sec)

每個(gè)Buffer Pool實(shí)例的大小為:

innodb_buffer_pool_size/innodb_buffer_pool_instances。

【9】chunk

一個(gè)Buffer Pool實(shí)例可以由多個(gè)chunk組成,一個(gè)chunk的大小可以如下查看,單位是字節(jié):

mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_chunk_size';
+-------------------------------+-----------+
| Variable_name                 | Value     |
+-------------------------------+-----------+
| innodb_buffer_pool_chunk_size | 134217728 |
+-------------------------------+-----------+
1 row in set, 1 warning (0.00 sec)

需要注意的是innodb_buffer_pool_size的大小得是innodb_buffer_pool_instances*innodb_buffer_pool_chunk_size的整數(shù)倍。

【10】Buffer Pool狀態(tài)信息

可以通過show engine innodb statu語句來查看InnoDB運(yùn)行過程中的一些狀態(tài)信息,其中就有Buffer Pool的狀態(tài),如下:

mysql> show engine innodb status;
...
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 1107296256
Dictionary memory allocated 6746952
Buffer pool size   64832
Free buffers       55706
Database pages     9126
Old database pages 3348
Modified db pages  8971
Percent of dirty pages(LRU & free pages): 13.837
Max dirty pages percent: 90.000
Pending reads 0
Pending writes: LRU 0, flush list 0
Pages made young 14, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 165, created 8961, written 0
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 9126, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
...

各個(gè)字段含義如下:

Buffer Pool狀態(tài)字段含義
Total memory allocated給Buffer Pool向操作系統(tǒng)申請的連續(xù)內(nèi)存空間大小,由控制塊、碎片、緩存頁組成
Dictionary memory allocated給數(shù)據(jù)字典信息分配的內(nèi)存空間大小,和Buffer Pool沒什么關(guān)系
Buffer pool sizeBuffer Pool可以存儲(chǔ)緩存頁的數(shù)量
Free buffers空閑緩存頁數(shù)量,也就是free鏈表節(jié)點(diǎn)數(shù)量
Database pagesLRU鏈中節(jié)點(diǎn)數(shù)量,包含young區(qū)域和old區(qū)域的節(jié)點(diǎn)
Old database pagesold區(qū)域節(jié)點(diǎn)的數(shù)量
Modified db pages臟頁數(shù)量,也就是flush鏈表節(jié)點(diǎn)數(shù)量
Pending reads正在等待從磁盤上加載到Buffer Pool中的頁面數(shù)量
Pending writes: LRU從LRU鏈表刷新到磁盤中的頁數(shù)
Pending writes: flush list從flush鏈表刷新到磁盤中的頁數(shù)
Page made youngLRU鏈表中從old區(qū)域移動(dòng)到y(tǒng)oung區(qū)域頭部的節(jié)點(diǎn)數(shù)量
Page made not young訪問old區(qū)域在innodb_old_blocks_time時(shí)間間隔內(nèi)訪問不能移動(dòng)到y(tǒng)oung區(qū)域的數(shù)量
young/s每秒從old區(qū)域移動(dòng)到y(tǒng)oung區(qū)域頭部節(jié)點(diǎn)數(shù)量
non-young/s每秒由于不滿足時(shí)間限制不能從old區(qū)域移動(dòng)到y(tǒng)oung區(qū)域節(jié)點(diǎn)數(shù)量
Page read從磁盤讀取寫的Buffer Pool中的頁數(shù)
Page createdBuffer Pool中創(chuàng)建的頁數(shù)
Page written刷新臟頁到磁盤的頁數(shù)
reads/s、creates/s、writes/s相關(guān)速度
Buffer pool hit rate某段時(shí)間平均訪問1000次頁面,有多少次頁面已經(jīng)被緩存到了Buffer Pool中
young-making rate某段時(shí)間平均訪問1000次頁面,有多少次訪問使頁面移動(dòng)到了young區(qū)域,包含old、young區(qū)域移動(dòng)到y(tǒng)oung區(qū)域
not某段時(shí)間平均訪問1000次頁面,有多少次訪問沒有使頁面移動(dòng)到了young區(qū)域
LRU sumLRU鏈表中節(jié)點(diǎn)數(shù)量
I/O sum最近50s讀取磁盤頁的總數(shù)
I/O cur正在讀取的磁盤頁數(shù)量

3、總結(jié)

Buffer Pool用作緩存,主要用于數(shù)據(jù)寫入、數(shù)據(jù)讀取、數(shù)據(jù)刷新,目的是為了減少磁盤I/O,增加讀寫速率,提高數(shù)據(jù)的訪問速度和系統(tǒng)性能。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MySQL的觸發(fā)器全解析(創(chuàng)建、查看觸發(fā)器)

    MySQL的觸發(fā)器全解析(創(chuàng)建、查看觸發(fā)器)

    MySQL觸發(fā)器是與表關(guān)聯(lián)的存儲(chǔ)程序,當(dāng)INSERT/UPDATE/DELETE事件發(fā)生時(shí)自動(dòng)執(zhí)行,用于維護(hù)數(shù)據(jù)一致性、日志記錄和校驗(yàn),優(yōu)點(diǎn)包括自動(dòng)執(zhí)行,缺點(diǎn)是可讀性差且維護(hù)難,注意外鍵約束可能影響觸發(fā)器激活,下面跟隨小編一起學(xué)習(xí)mysql的觸發(fā)器知識,感興趣的朋友一起看看吧
    2025-08-08
  • 解壓版MYSQL中文亂碼問題解決方案

    解壓版MYSQL中文亂碼問題解決方案

    這篇文章主要介紹了解壓版MYSQL中文亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • MySQL的MaxIdleConns不合理,會(huì)變成短連接的原因

    MySQL的MaxIdleConns不合理,會(huì)變成短連接的原因

    這篇文章主要介紹了MySQL的MaxIdleConns不合理,會(huì)變成短連接的原因,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下
    2021-01-01
  • 同時(shí)運(yùn)行多個(gè)MySQL服務(wù)器的方法

    同時(shí)運(yùn)行多個(gè)MySQL服務(wù)器的方法

    在同一臺(tái)機(jī)器上運(yùn)行多個(gè)有些情況下你可能想要在同一臺(tái)機(jī)器上運(yùn)行多個(gè)服務(wù)器。例如,你可能想要測試一個(gè)新的MySQL版本而讓你現(xiàn)有生產(chǎn)系統(tǒng)的設(shè)置不受到干擾, 或你可能是想要為不同的客戶提供獨(dú)立的MySQL安裝一個(gè)因特網(wǎng)服務(wù)供應(yīng)商。
    2008-05-05
  • MySQL解決字符集編碼問題

    MySQL解決字符集編碼問題

    MySQL的默認(rèn)編碼方式是?拉丁文,如果想要設(shè)置一些漢字的數(shù)據(jù).可能會(huì)報(bào)錯(cuò).這篇文章中主要介紹了解決這個(gè)問題的方法,需要的朋友可以參考一下
    2023-04-04
  • mysql中如何設(shè)置大小寫不敏感

    mysql中如何設(shè)置大小寫不敏感

    這篇文章主要介紹了mysql中如何設(shè)置大小寫不敏感問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Mysql是如何實(shí)現(xiàn)事務(wù)的以及相關(guān)擴(kuò)展知識總結(jié)

    Mysql是如何實(shí)現(xiàn)事務(wù)的以及相關(guān)擴(kuò)展知識總結(jié)

    在mysql中事務(wù)是一種機(jī)制、一個(gè)操作序列,是訪問和更新數(shù)據(jù)庫的程序執(zhí)行單元,下面這篇文章主要介紹了Mysql是如何實(shí)現(xiàn)事務(wù)的以及相關(guān)擴(kuò)展知識總結(jié)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-05-05
  • Mysql中如何刪除某個(gè)字段的最后四個(gè)字符

    Mysql中如何刪除某個(gè)字段的最后四個(gè)字符

    這篇文章主要介紹了Mysql中如何刪除某個(gè)字段的最后四個(gè)字符,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • MySQL之索引結(jié)構(gòu)解讀

    MySQL之索引結(jié)構(gòu)解讀

    這篇文章主要介紹了MySQL之索引結(jié)構(gòu)解讀,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 關(guān)于@NotNull注解失效的原因之一

    關(guān)于@NotNull注解失效的原因之一

    這篇文章主要介紹了關(guān)于@NotNull注解失效的原因之一,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評論

丰城市| 加查县| 丰县| 甘肃省| 中江县| 邯郸县| 图木舒克市| 博湖县| 百色市| 霍林郭勒市| 新兴县| 乌海市| 青州市| 当雄县| 卓资县| 赣榆县| 灵璧县| 金寨县| 高青县| 新兴县| 松江区| 连云港市| 蒙阴县| 邯郸市| 手游| 鄂托克前旗| 新巴尔虎右旗| 吴川市| 金湖县| 牙克石市| 沛县| 都兰县| 隆尧县| 泾阳县| 宁阳县| 霍林郭勒市| 玛多县| 奇台县| 元氏县| 怀宁县| 长沙县|