欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL InnoDB中的Buffer Pool用法及說明

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

1、背景

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

2、Buffer Pool

【1】含義

在mysql服務(wù)啟動時會申請一塊存儲頁的連續(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是由控制塊和緩存頁組成,一個控制塊對應(yīng)一個緩存頁,控制塊包含對應(yīng)緩存頁的表空間編號、頁號、緩存頁在Buffer Pool中的地址、鏈表節(jié)點信息、鎖、LSN信息, innodb_buffer_pool_size的大小并不包含控制塊的空間,所以再給Buffer Pool申請一塊連續(xù)的內(nèi)存時會額外申請5%的空間用于存儲控制塊,其組成圖如下:

在這里插入圖片描述

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

【3】free鏈表

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

在這里插入圖片描述

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

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

【4】哈希查找緩存頁

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

【5】flush鏈表

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

【6】LRU鏈表

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

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

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

但是有兩種情況,

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

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

在這里插入圖片描述

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)磁盤上的某個頁初次加載到Buffer Pool時,就會放到old區(qū)域的頭部,如果該頁的訪問頻率低就會在old后移最終被移除。

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

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

時間間隔配置為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】刷新臟頁到磁盤

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

第一種是BUF_FLUSH_LRU

就是定時從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

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

【8】Buffer Pool實例

可以通過innodb_buffer_pool_instances配置Buffer Pool的實例,提高并發(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)

每個Buffer Pool實例的大小為:

innodb_buffer_pool_size/innodb_buffer_pool_instances。

【9】chunk

一個Buffer Pool實例可以由多個chunk組成,一個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運行過程中的一些狀態(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]
...

各個字段含義如下:

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可以存儲緩存頁的數(shù)量
Free buffers空閑緩存頁數(shù)量,也就是free鏈表節(jié)點數(shù)量
Database pagesLRU鏈中節(jié)點數(shù)量,包含young區(qū)域和old區(qū)域的節(jié)點
Old database pagesold區(qū)域節(jié)點的數(shù)量
Modified db pages臟頁數(shù)量,也就是flush鏈表節(jié)點數(shù)量
Pending reads正在等待從磁盤上加載到Buffer Pool中的頁面數(shù)量
Pending writes: LRU從LRU鏈表刷新到磁盤中的頁數(shù)
Pending writes: flush list從flush鏈表刷新到磁盤中的頁數(shù)
Page made youngLRU鏈表中從old區(qū)域移動到y(tǒng)oung區(qū)域頭部的節(jié)點數(shù)量
Page made not young訪問old區(qū)域在innodb_old_blocks_time時間間隔內(nèi)訪問不能移動到y(tǒng)oung區(qū)域的數(shù)量
young/s每秒從old區(qū)域移動到y(tǒng)oung區(qū)域頭部節(jié)點數(shù)量
non-young/s每秒由于不滿足時間限制不能從old區(qū)域移動到y(tǒng)oung區(qū)域節(jié)點數(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某段時間平均訪問1000次頁面,有多少次頁面已經(jīng)被緩存到了Buffer Pool中
young-making rate某段時間平均訪問1000次頁面,有多少次訪問使頁面移動到了young區(qū)域,包含old、young區(qū)域移動到y(tǒng)oung區(qū)域
not某段時間平均訪問1000次頁面,有多少次訪問沒有使頁面移動到了young區(qū)域
LRU sumLRU鏈表中節(jié)點數(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)性能。

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

相關(guān)文章

  • 詳解Mysql兩表?join?查詢方式

    詳解Mysql兩表?join?查詢方式

    這篇文章主要介紹了Mysql兩表?join?查詢方式,主要包括SQL基本語法格式j(luò)i3種join方式,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • MySQL用戶和權(quán)限及破解root口令的方法示例

    MySQL用戶和權(quán)限及破解root口令的方法示例

    這篇文章主要介紹了詳解MySQL用戶和權(quán)限及破解root口令,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • Mysql主從GTID與binlog的區(qū)別及說明

    Mysql主從GTID與binlog的區(qū)別及說明

    MySQL GTID(全局事務(wù)標(biāo)識符)與binlog(二進(jìn)制日志)是搭建主從復(fù)制的兩種機(jī)制,GTID為每個事務(wù)分配唯一標(biāo)識,確保復(fù)制無數(shù)據(jù)沖突或丟失,便于復(fù)制配置和管理;binlog記錄所有數(shù)據(jù)庫更改,用于數(shù)據(jù)恢復(fù)和復(fù)制,GTID基于事務(wù)標(biāo)識
    2024-10-10
  • Mysql ERROR 1577錯誤解決方法

    Mysql ERROR 1577錯誤解決方法

    這篇文章主要介紹了Mysql ERROR 1577錯誤解決方法,一般是在升級mysql后會發(fā)生這個錯誤,錯誤原因是需要升級MySQL系統(tǒng)表,需要的朋友可以參考下
    2014-08-08
  • MySQL敏感數(shù)據(jù)進(jìn)行加密的幾種方法小結(jié)

    MySQL敏感數(shù)據(jù)進(jìn)行加密的幾種方法小結(jié)

    本文介紹了在MySQL中對敏感數(shù)據(jù)進(jìn)行加密的幾種方法,每種方法都有其適用場景和特點,可以根據(jù)具體需求選擇合適的方法來保護(hù)數(shù)據(jù)安全,感興趣的可以了解一下
    2024-11-11
  • 詳解MySQL的用戶密碼過期功能

    詳解MySQL的用戶密碼過期功能

    這篇文章主要為大家詳細(xì)介紹了MySQL的用戶密碼過期功能的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • 使用Dify訪問mysql數(shù)據(jù)庫詳細(xì)代碼示例

    使用Dify訪問mysql數(shù)據(jù)庫詳細(xì)代碼示例

    這篇文章主要介紹了使用Dify訪問mysql數(shù)據(jù)庫的相關(guān)資料,并詳細(xì)講解了如何在本地搭建數(shù)據(jù)庫訪問服務(wù),使用ngrok暴露到公網(wǎng),并創(chuàng)建知識庫、數(shù)據(jù)庫訪問工作流和智能體,需要的朋友可以參考下
    2025-03-03
  • 如何使用MySQL一個表中的字段更新另一個表中字段

    如何使用MySQL一個表中的字段更新另一個表中字段

    這篇文章主要介紹了如何使用MySQL一個表中的字段更新另一個表中字段,需要的朋友可以參考下
    2018-11-11
  • MySQL實現(xiàn)數(shù)據(jù)更新的示例詳解

    MySQL實現(xiàn)數(shù)據(jù)更新的示例詳解

    這篇文章主要為大家詳細(xì)介紹了MySQL實現(xiàn)數(shù)據(jù)更新的相關(guān)資料,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 將舊版MySQL替換為8.0及以上版本保姆級教學(xué)

    將舊版MySQL替換為8.0及以上版本保姆級教學(xué)

    在部署項目的時候MySQL就會報錯,這個時候就要換MySQL的版本了,這篇文章主要給大家介紹了關(guān)于將舊版MySQL替換為8.0及以上版本的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05

最新評論