vacuum (4)

vac_open_indexes

relに指定したテーブルのindexを全てopenする。テーブルと同じlock modeを使う。

vac_close_indexes

vac_open_indexesでopenしたindexをcloseする。

vpage_insert

vacpagelist配列にvacpageを追加する。vacpagelist配列が初期化されていないときは、PG_NPAGEDESC(=1024)の大きさの配列を作成して、vacpageを追加する。vacpagelist配列が一杯になっていたら、repallocで配列サイズを2倍にしてからvacpageを追加する。

copy_vac_page

vacpageのコピーを作成する。コピー元のvacpageはscan_heapやrepair_flagで作成され、vacpage->offsets配列にはMaxOffsetNumberの数のoffsetを登録できるようにメモリを確保している。コピーするときは配列に登録されているoffsetの数(vacpage->offsets_free)のメモリを確保してコピーするので、コピーしたvacpageのサイズはコピー元よりも小さくなることが多い。

vacuum_rel

relidで指定したテーブルをvacuumする。vacuumが成功したらtrueを返す。permissionなどの理由でvacuumできなかったらfalseを返す。falseが返されたときは、トランザクションIDの状態を変更できない(commit logをtruncateできない)

(1)StgartTransactionCommandでトランザクションを開始。StrategyHintVacuumをtrueにする。

(2)テーブルが削除されていたらtrueを返して終了。

(3)ロックモードを決める。full vacuumのときはAccessExclusiveLock、その他はShareUpdateExclusiveLock。

(4)テーブルをopenして、テーブルのpermissionをチェックする。
vacuumを実行したユーザーがsuper user, tableのowner, databaseのownerのいづれかであれば、vacuumできる。

(5)テーブルの種類をチェックする。この関数では、通常のテーブルかTOASTテーブルのみvacuumできる。

(6)テーブルが他のバックエンドが使用している一時テーブルの場合、vacuumを実行せずにtrueを返す。

(7)LockRelationForSessionでセッションロック(commitしても開放されないロック)を取得する。テーブルにTOASTテーブルがある場合、TOASTテーブルをvacuumするまで、ロックを保持するためにこのロックを取得している。

(8)full vacuumのときはfull_vacuum_rel、その他はlazy_vacuum_relを実行する

(9)テーブルをcloseしてcommitする。

(10)StrategyHintVacuumをfalseにする。

(11)TOASTテーブルがある場合、vacuum_relを再帰的に呼び出してTOASTテーブルをvacuumする。

(12)セッションロックを開放する。

strategy_hint_vacuum

vacuumの実行中にtrueに設定されるフラグ。このフラグはバッファマネージャのUnpinBufferの動作に影響を与える。UnpinBufferはバッファを参照する必要がなくなったときに実行され、バッファの参照カウンタを減らす。
vacuumが実行されていないときは、使用回数をインクリメントし、バッファが最近使用されたことを記録する。
vacuum実行中は参照カウンタ(refcount)と使用回数(usage_count)が0で、trashOKにtrueが指定された場合、vacuum以外のトランザクションではこのバッファはすぐに必要にならないと判定し、バッファをfreelistに登録して別のページのために使用できるようにする。

       if (!strategy_hint_vacuum)
       {
           if (buf->usage_count < BM_MAX_USAGE_COUNT)
               buf->usage_count++;
       }
       else if (trashOK && 
                buf->refcount == 0 &&
                buf->usage_count == 0)
           trash_buffer = true;