Mysql學習 InnoDB快取

2021-10-19 17:48:31 字數 3274 閱讀 8179

innodb是基於磁碟儲存的,其中的儲存記錄按照頁的方式進行管理,可將其視為基於磁碟的資料系統。由於磁碟讀寫速度與cpu計算速度之間的鴻溝,innodb對資料庫的讀寫操作都要通過快取來實現。在資料庫進行讀取操作時,先將從磁碟讀取到的資料放到快取池中,這個過程稱為將頁「fix」到快取池,下一次再讀取相同的頁時,會先讀取快取中的頁,沒有命中才讀取磁碟。在寫操作時,先修改快取中的頁,再以一定的頻率刷到磁碟中。

mysql通過innodb_buffer_pool_size設定innodb的快取池大小:

# 檢視

show variables like

'innodb_buffer_pool_size'

;# 修改

set innodb_buffer_pool_size=

1000000

;

快取池中儲存的資料有:索引頁、資料頁、undo頁、插入快取、自適應雜湊索引、鎖資訊、資料字典

為了減少資料庫內部的資源競爭,mysql 1.0 之後的版本允許有多個快取例項,每個頁根據hash值分布到不通的快取例項中(另乙個因素是mysql 1.0 之後,innodb使用了aio,支援多執行緒讀寫)。

# 檢視innodb的快取池例項數量

show variables like

'innodb_buffer_pool_instance'

;

資料庫中的快取池通過lru演算法進行管理,將最頻繁使用的頁放到lru列表的頭部,最少使用的放在尾部,當快取池記憶體不足,不能存放新頁時,淘汰尾部的頁。

快取池中的頁有預設的16kb(由lru管理)和壓縮的1kb、2kb、4kb、8kb(由unzip_lru管理)。

innobd對lru演算法做了優化:在lru列表中加入了midpoint位置,當讀取到新頁時,將新頁存放到midpoint位置。又innodb_old_blocks_pct控制,預設為37,即lru列表中前37%的為new列表,之後的為old列表。

show variables like

'innodb_old_blocks_pct'

;

另外,innodb通過innodb_old_blocks_time來進一步管理lru列表,新讀到的頁要在這個時間之內再次被讀取才會插入到lru列表中。

show variables like

'innodb_old_blocks_time'

;

這樣做的好處是一些偶然的讀取操作不會將lru列表中的熱點資料移出,尤其是一些大的讀取操作,如定時任務進行全表讀取。為unzip_lru列表分配記憶體和一般的分配記憶體有所不同(因為頁的大小不同,而mysql預設的頁為16kb)。比從快取池中申請乙個4kb的頁,要進行以下步驟:

檢查4kb的unzip_lru列表是否有可用的空閒頁

若有,直接使用

若無,檢查8kb的unzip_lru列表是否有可用的空閒頁

若有,將頁分為2個4kb的頁,存放到4kb的unzip_lru列表中

若無,從lru列表中申請乙個16kb的頁,分為1個8kb的頁和兩個4kb的頁,分布存放到相應的unzip_lru列表中

**寫入快取:**執行寫如操作後,新插入或被修改的頁(髒頁)會同時存在lru列表和flush列表中,lru列表用來管理快取池中頁的可用性,flush列表用來管理將頁刷如磁碟,二者互不影響。

檢視快取池狀態:(非實時)

mysql> show engine innodb status;

----------------------

buffer pool and memory

----------------------

total large memory allocated 137428992

dictionary memory allocated 449278

buffer pool size 8191 #快取池中的頁數,占用大小:8191*16kb

free buffers 7089 #free列表中的頁數

database pages 1095 #lru列表中的頁數

old database pages 423 #舊lru sublist的頁數

modified db pages 0 #髒頁

pending reads 0

pending writes: lru 0, flush list 0, single page 0

pages made young 0, not young 0 #插入lru列表的新頁,尚未插入的頁

0.00 youngs/s, 0.00 non-youngs/s #頻率

pages read 948, created 147, written 320

0.00 reads/s, 0.00 creates/s, 0.00 writes/s

no buffer pool page gets since the last printout #這裡會有快取命中率,因為我沒查庫,所以沒資料

pages read ahead 0.00/s, evicted without access 0.00/s, random read ahead 0.00/s

lru len: 1095, unzip_lru len: 0 #lru列表的頁數和unzip_lru列表的頁數,前者包含後者

i/o sum[0]:cur[0], unzip sum[0]:cur[0]

innodb先將undo log放到重做日誌快取,再刷到重做日誌檔案。重做日誌快取的大小由innodb_log_buffer_size控制,預設為8m。一般不用設定的太大,因為master thread每秒都會將重做日誌刷到檔案。

show variables like

'innodb_log_buffer_size'

;

將重做日誌刷入到檔案的情況:

master thread每秒刷一次

每次事務提交刷一次

重做日誌快取池剩餘記憶體不足1/2時刷一次

MySQL 5 7 Innodb事務物件快取

在5.7中,innodb引入了乙個pool結構來專門做物件快取重用。這可能會提公升短連線場景的效能。本文的目的主要是理清其 結構。當然主要是作為乙個c 小白,學習下c 的一些 style。版本 mysql 5.7.5 我們這裡以事務物件池為例 1.初始化的過程如下 trx pools ut new ...

mysql的Innodb儲存引擎學習

總是記不住事情,已經看過好幾本mysql的書了,但是不經常用,很多基礎性的東西又都忘了,從今天開始,將重新看mysql的書籍,並做相應的記錄 innodb儲存引擎 1.支援事務安裝 innodb 在功能方面最重要的一點就是對事務安全的支援,這無疑是讓 innodb 成為 mys ql最為流行的儲存引...

學習筆記 mysql索引原理之InnoDB

innodb是事務安全的mysql儲存引擎,在oltp的應用中,innodb應該作為核心應用表的首選儲存引擎。1 執行緒 後台的執行緒主要負責 重新整理記憶體池中的資料,保證緩衝池中的記憶體快取的是最近的資料 將已修改的資料檔案重新整理到磁碟檔案 保證在資料庫發生異常情況下innodb能恢復到正常狀...