バッファ管理。バッファの読み書き
バッファプールの初期化を見てみる
- InitBufferPool
- バッファの領域(BufferDescriptorsとかBufferBlocks)を初期化。共有メモリから割り当てている。
- BufferBlocksって単なるcharのポインタ。
バッファのデータがwrite()されるまでを見てみる
- FlushBuffer
- トランザクションログをフラッシュする処理(XLogFlush)を呼んでいるけどなぜここにあるのか?XLogFlushされるべきものがこの時点でまだされていないケースがわからない。
- BufferDescの情報からバッファのポインタを得ている。
- smgrwrit
- mdwrite
- セグメント(ファイルあたりのブロック数だと思う)を元にseekの位置や書き込み先のファイルを調整。
- FileWrite
- ブロックのサイズ(デフォルトだと8192)が指定されていて、確かにブロック単位で書き込みしてる。
- write
バッファからデータが読まれるまでを見てみる
- ExecutePlan
- 実行計画で組み立てたノードを使って実際にクエリ処理を実行。
- タプルをとってきて処理、とってきて処理の繰り返し。ステートメント単位のトリガの実行もここにある。
- ExecProcNode
- さまざまなスキャン方法があるが実行計画に従って進む。
- ExecSeqScan
- シーケンススキャン。
- ExecScan
- SeqNext
- TupleTableSlotにタプルを詰める。
- heap_getnext
- タプルを返す。
- heapgettup_pagemode
- HeapScanDescにタプルを詰める。
- タプルごとにこの関数が呼ばれるが、ページ上にまだ処理していないタプルがある限りはheapgetpage関数を呼び出さない。すべてのタプルを読んだら、次のページをheapgetpage関数から取得。
- heapgetpageでチェックして見えていいとされたタプルだけを扱う。
- heapgetpage
- バッファ上のページから全てのタプルを取り出してこのトランザクションから見えていいのかどうかのチェックをしている。ここは後で要チェック。
- ReadBufferWithStrategy
- strategy指定で呼び出している。strategyがあるかどうかでバッファ管理のされ方が異なるので注意。
- ReadBuffer_common
- バッファを返す。ローカルのバッファとグローバルのバッファどちらを読むか場合分けしてる。
- BufferAlloc
- バッファ記述子をキャッシュから読んだり。今回はキャッシュでヒットした場合しか見ていないけど、ほかにもいろいろしてる。
- BufTableLookup
- ハッシュテーブルからバッファのIDを探す。
BufferAllocでキャッシュにヒットする場合を見たので、明日移行はヒットしない場合を見てみる。