最近最少使用的替換策略 - 引腳數儲存在哪裡?
我正在閱讀一本關於數據庫的書,其中的一章討論了緩衝區管理器及其替代策略。
提到的兩個流行的替代策略是
least recently used - LRU
和clock replacement
。我對有關LRU
.LRU
是通過隊列實現的。當 apin count
設置為 0 時,記憶體中的頁面被添加到隊列中。當需要補充時,使用隊列開頭的記憶體頁。這本書沒有描述
pin count
頁面的儲存方式(和臟位)。它是否儲存在隊列條目中?它是否作為頭部的一部分儲存在緩衝池幀中?此外,如果在隊列中訪問頁面會發生什麼?它是否立即從隊列中刪除?
(我沒聽說過
pin count
; “pin”代表什麼?)對於每個條目,事物的記憶體需要以下某些子集:
- 上次使用時的時間戳或序列號。或者這可以通過鍊錶來實現。(這可能是您所指的 LRU 隊列。)
- 到期日期(罕見)。
- 一個“臟”標誌,表明它已被更改。更具體地說,它與磁碟不一致,因此必須在釋放之前將其寫出。
- 引用計數——這表明有多少執行緒(或其他)已鎖定到該項目。(並不總是存在。)
- 鎖——在項目上或整個桌子上。這用於避免修改數據、連結、標誌等,而不是釋放項目。當另一個執行緒正在使用該項目時,您不能允許一個執行緒釋放該項目。(這種解決了你的最後一個問題。)
- 指向其他項目的前向和後向連結。(如果項目是可變長度的,則特別有用。)
- 該項目可能是完全獨立的(例如,當使用 RAM 時),或者在使用磁碟時可能涉及兩個資訊塊——將連結、臟位等保存在 RAM 中。這樣您就不必為跟踪連結或檢查/設置臟位進行昂貴的 I/O。(因此,臟位的位置“取決於”。)
我漫不經心的回答指出,有很多方法可以實現 LRU 記憶體。你的問題表明你開始理解這個基本結構的複雜性。
由於您使用mysql標記了此問題,因此對於 InnoDB 的緩衝池,您可以在此處閱讀一些相關資訊:https ://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-pool.html
InnoDB 維護兩個獨立的頁面隊列。最近訪問的頁面是“年輕的”或“新的”,它們有自己的 LRU 隊列。訪問距離較遠的頁面是“舊的”。我覺得這些術語不是很直覺,但我沒有編造它們。
第一次載入頁面時,它被放在“舊”隊列的頭部。頁面可以從一個隊列移動到另一個隊列。例如,如果使用者查詢訪問舊隊列中的頁面,則將其移動到新隊列。
然後,當頁面被驅逐時,它們更願意從“舊”隊列中取出。這使得緩衝池中的快速周轉更有可能影響只訪問過一次的頁面。因此,即使是像 table-scan 這樣導致 LRU 緩衝區完全周轉的操作也會一次又一次地只驅逐舊隊列中的頁面,並且不會干擾新隊列中的頁面。