More Related Content
More from Satoshi Nagayasu (20)
PostgreSQL Internals - Buffer Management
- 2. bufmgr関連データ
• 1つ以上のバックエンドによって参照されて
いるバッファ(プール)のハッシュテーブル
– SharedBufHash
• どこからも参照されていない(されなくなっ
た)バッファのリスト(環状リスト)
– SharedFreeList
• いずれも共有メモリ内の領域
2003/06/20 Satoshi Nagayasu
- 4. 初期化直後のBufferDescriptorリスト(NBuffers=8)
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
InitBufferPool()
InitFreeList()
NBuffers(GUC)+1のBufferDescriptorを確保する。
最後の1個を空きバッファリストの先頭要素とする。
freeNextを辿ると、「8→1→2→3→4→5→6→7→0→8」
2003/06/20 Satoshi Nagayasu
- 5. ディスクからバッファへの読込み
• バッファに読み込むディスクブロックの指定
– BufferTag
• fileNode(テーブルOID)とブロック番号
• バッファプールの中に存在するか?
– BufTableLookup()
• BufferPoolのHashテーブルを検索
• 存在しなければディスクから読み込み
– GetFreeBuffer() & smgrread()
2003/06/20 Satoshi Nagayasu
- 6. ディスクからバッファへの読込み
• ReadBuffer() / ReadBufferInternal()
– BufferAlloc()
• BufTableLookup() でHashテーブルを検索
• 見つからなければ GetFreeBuffer() でバッファ取得
• Hashテーブルに追加
– Hash 内にあれば BufferDescriptorGetBuffer()
– 無ければ smgrread()
2003/06/20 Satoshi Nagayasu
- 7. GetFreeBuffer()
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
buf = &(BufferDescriptors[SharedFreeList->freeNext]);
2003/06/20 Satoshi Nagayasu
- 8. GetFreeBuffer()
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
BufferDescriptors[buf->freeNext].freePrev = buf->freePrev;
2003/06/20 Satoshi Nagayasu
- 9. GetFreeBuffer()
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
BufferDescriptors[buf->freePrev].freeNext = buf->freeNext;
2003/06/20 Satoshi Nagayasu
- 10. GetFreeBuffer()
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
buf->freeNext = buf->freePrev = INVALID_DESCRIPTOR;
2003/06/20 Satoshi Nagayasu
- 13. SharedFreeList
• バッファを取得する場合には、freelistの先
頭(SharedFreeListの次)から取る
– GetFreeBuffer()
• バッファを開放する場合には、freelistの最
後尾(SharedFreeListの前)に追加
– BufferDesc->refcountが0になると、freeListに
追加される。
– UnpinBuffer(), AddBufferToFreeList()
2003/06/20 Satoshi Nagayasu
- 14. SharedFreeList
• 有効なブロックが読み込まれているバッ
ファは、ハッシュテーブルに登録される
• どのバックエンドにも参照されていないバッ
ファは、freelistの最後尾に登録される
• freelistから取り出したものが、以前使われ
ていたdirtyなバッファの場合は、前のデー
タをまずディスクにwriteしてから使われる
2003/06/20 Satoshi Nagayasu
- 15. AddBufferToFreeList ()
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
bf->freePrev = SharedFreeList->FreePrev;
2003/06/20 Satoshi Nagayasu
- 16. AddBufferToFreeList ()
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
bf->freeNext = Free_List_Descriptor;
2003/06/20 Satoshi Nagayasu
- 17. AddBufferToFreeList ()
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
BufferDescriptors[bf->freeNext].freePrev = bf->buf_id;
2003/06/20 Satoshi Nagayasu
- 18. AddBufferToFreeList ()
freeNext freeNext
freeNext
freeNext freeNext freeNext freeNext
freeNext
SharedFreeList
0 1 2 3 4 5 6 7 8
freePrev freePrev freePrev freePrev freePrev freePrev
freePrev
freePrev
BufferDescriptors[bf->freePrev].freeNext = bf->buf_id;
2003/06/20 Satoshi Nagayasu
- 19. bufmgrイメージ
• ブロックが読み込まれてるバッファは
SharedBufHashに
• 参照されなくなったバッファはSharedFreeList
に
• 両方に存在することも shmem
SharedBufHash
postgres
postgres SharedFreeList
Buffer
postgres Buffer
Buffer
2003/06/20 Buffer
postgres Nagayasu
Satoshi
- 21. bufmgr - GetFreeBuffer()
• ディスクからブロックが読み込まれると、
SharedFreeListの先頭から取り出され、
SharedBufHashに登録される
(GetFreeBuffer()&BufTableInsert())。
SharedFreeList SharedBufHash
Buffer
2003/06/20 Satoshi Nagayasu
- 22. bufmgr - UnpinBuffer()
• どこからも参照されなくなる(refcount==0)と、
SharedFreeListの最後尾に登録される。この
段階では、SharedBufHashの中でも見つかる
し、SharedFreeListにも含まれる。
SharedFreeList SharedBufHash
Buffer
参照されてない。でもdirty(かもしれない)。
2003/06/20 Satoshi Nagayasu
- 23. bufmgr - PinBuffer()
• 再度参照されると、SharedFreeListから切り
離される。
SharedFreeList SharedBufHash
Buffer
2003/06/20 Satoshi Nagayasu
- 24. bufmgr - BufTableDelete()
• そのまま参照されずに、再度別ブロックの
バッファとして取得されると、以前のdirtyな
データをディスクに反映させて、
SharedBufHashから一旦削除される(新しい
ブロックとして再登録)。
SharedFreeList SharedBufHash
Buffer
2003/06/20 Satoshi Nagayasu