PostgreSQL 緩存


PostgreSQL physical storage inter db    值得閱讀

數據在物理介質上存儲是以page的形式,大小為8K,如下:

  • tuple或an item是行的同義詞
  • relation是表的同義詞
  • filenode是表示對表或索引的引用的id。
  • blockpage是等於它們代表存儲表的文件的8kb段信息。

PostgreSQL會把table數據和index以page的形式存儲在緩存中,同時在某些情況下(使用 prepared)也會把查詢計划緩存下來,但是不會去緩存具體的查詢結果。它是把查詢到的數據頁緩存起來,這個頁會包含連續的數據,即不僅僅是你所要的查詢的數據。

緩存指的是共享緩存,shared_buffers,所代表的內存區域可以看成是一個以8KB的block為單位的數組,即最小的分配單位是8KB。當Postgres想要從disk獲取(主要是table和index)數據(page)時,他會(根據page的元數據)先搜索shared_buffers,確認該page是否在shared_buffers中,如果存在,則直接命中,返回緩存的數據以避免I/O。如果不存在,Postgres才會通過I/O訪問disk獲取數據。

緩沖區的分配

我們知道Postgres是基於進程工作的系統,即對於每一個服務器的connection,Postgres主進程都會向操作系統fork一個新的子進程(backend)去提供服務。同時,Postgres本身除了主進程之外也會起一些輔助的進程。

因此,對於每一個connection的數據請求,對應的后端進程(backend)都會首先向LRU cache中請求數據頁page(這個數據請求不一定指的是SQL直接查詢的表或者視圖的page,比如index和系統表),這個時候就發起了一次緩沖區的分配請求。那么,這個時候我們就要抉擇了。如果要請求的block就在cache中,那最好,我們"pinned"這個block,並且返回cache中的數據。所謂的"pinned"指的是增加這個block的"usage count"。

當"usage count"為0時,我們就認為這個block沒用了,在后面cache滿的時候,它就該挪挪窩了。

那也就是說,只有當buffers/slots已滿的情況下,才會引發緩存區的換出操作。

緩存區的換出

決定哪個page該從內存中換出並寫回到disk中,這是一個經典的計算機科學的問題。

一個最簡單的LRU算法在實際情況下基本上很難work起來。因為LRU是要把最近最少使用的page換出去,但是我們沒有記錄上次運行時的狀態。

因此,作為一個折中和替代,我們追蹤並記錄每個page的"usage count",在有需要時,將那些"usage count"為0的page換出並寫回到disk中。后面也會提到,臟頁面也會被寫回disk。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM