vacuum (7)

HeapTupleSatisfiesVacuum

Vacuumを実行するためにタプルの状態をチェックする。タプルが実行中の全てのトランザクションから参照できない場合、HEAPTUPLE_DEADを返す。HEAPTUPLE_DEADだったらVacuumが削除できる。
タプルがdeleteされているが、実行中のいくつかのトランザクションから参照可能な場合は、HEAPTUPLE_RECENTLY_DEADを返す。

    if (!TransactionIdPrecedes(HeapTupleHeaderGetXmax(tuple), OldestXmin))
    {
        /* deleting xact is too recent, tuple could still be visible */
        return HEAPTUPLE_RECENTLY_DEAD;
    }

scan_heap (続き)

HeapTupleSatisfiesVacuumがHEAPTUPLE_RECENTLY_DEADを返したとき、タプルがupdateで更新されたタプルだったら、vtlinksに登録する。(タプルがupdateされるとtuple.t_data->t_ctidにupdate後のタプルのTIDが設定されるので、自分のTID(tuple.t_self)と比較して違っていたらupdateされたタプルだと判定できる)
update後のタプルの位置を移動するとき、update前のタプルからのリンクも考慮する必要があるため、更新前後のTIDを記録している。

                    if (do_shrinking &&
                        !(ItemPointerEquals(&(tuple.t_self),
                                            &(tuple.t_data->t_ctid))))
                    {
                        if (free_vtlinks == 0)
                        {
                            free_vtlinks = 1000;
                            vtlinks = (VTupleLink) repalloc(vtlinks,
                                           (free_vtlinks + num_vtlinks) *
                                                 sizeof(VTupleLinkData));
                        }
                        vtlinks[num_vtlinks].new_tid = tuple.t_data->t_ctid;
                        vtlinks[num_vtlinks].this_tid = tuple.t_self;
                        free_vtlinks--;
                        num_vtlinks++;
                    }