Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 26d138f

Browse files
committed
Refactor how heap_prune_chain() updates prunable_xid
In preparation of freezing and counting tuples which are not candidates for pruning, split heap_prune_record_unchanged() into multiple functions, depending the kind of line pointer. That's not too interesting right now, but makes the next commit smaller. Recording the lowest soon-to-be prunable xid is one of the actions we take for unchanged LP_NORMAL item pointers but not for others, so move that to the new heap_prune_record_unchanged_lp_normal() function. The next commit will add more actions to these functions. Author: Melanie Plageman <melanieplageman@gmail.com> Discussion: https://www.postgresql.org/message-id/20240330055710.kqg6ii2cdojsxgje@liskov
1 parent be2f073 commit 26d138f

File tree

1 file changed

+92
-33
lines changed

1 file changed

+92
-33
lines changed

src/backend/access/heap/pruneheap.c

+92-33
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ static void heap_prune_record_redirect(PruneState *prstate,
7878
static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum, bool was_normal);
7979
static void heap_prune_record_dead_or_unused(PruneState *prstate, OffsetNumber offnum, bool was_normal);
8080
static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum, bool was_normal);
81-
static void heap_prune_record_unchanged(PruneState *prstate, OffsetNumber offnum);
81+
82+
static void heap_prune_record_unchanged_lp_unused(Page page, PruneState *prstate, OffsetNumber offnum);
83+
static void heap_prune_record_unchanged_lp_normal(Page page, int8 *htsv, PruneState *prstate, OffsetNumber offnum);
84+
static void heap_prune_record_unchanged_lp_dead(Page page, PruneState *prstate, OffsetNumber offnum);
85+
static void heap_prune_record_unchanged_lp_redirect(PruneState *prstate, OffsetNumber offnum);
8286

8387
static void page_verify_redirects(Page page);
8488

@@ -311,7 +315,7 @@ heap_page_prune(Relation relation, Buffer buffer,
311315
/* Nothing to do if slot doesn't contain a tuple */
312316
if (!ItemIdIsUsed(itemid))
313317
{
314-
heap_prune_record_unchanged(&prstate, offnum);
318+
heap_prune_record_unchanged_lp_unused(page, &prstate, offnum);
315319
continue;
316320
}
317321

@@ -324,7 +328,7 @@ heap_page_prune(Relation relation, Buffer buffer,
324328
if (unlikely(prstate.mark_unused_now))
325329
heap_prune_record_unused(&prstate, offnum, false);
326330
else
327-
heap_prune_record_unchanged(&prstate, offnum);
331+
heap_prune_record_unchanged_lp_dead(page, &prstate, offnum);
328332
continue;
329333
}
330334

@@ -434,7 +438,7 @@ heap_page_prune(Relation relation, Buffer buffer,
434438
}
435439
}
436440
else
437-
heap_prune_record_unchanged(&prstate, offnum);
441+
heap_prune_record_unchanged_lp_normal(page, presult->htsv, &prstate, offnum);
438442
}
439443

440444
/* We should now have processed every tuple exactly once */
@@ -652,9 +656,6 @@ heap_prune_chain(Page page, BlockNumber blockno, OffsetNumber maxoff,
652656
*/
653657
chainitems[nchain++] = offnum;
654658

655-
/*
656-
* Check tuple's visibility status.
657-
*/
658659
switch (htsv_get_valid_status(htsv[offnum]))
659660
{
660661
case HEAPTUPLE_DEAD:
@@ -670,9 +671,6 @@ heap_prune_chain(Page page, BlockNumber blockno, OffsetNumber maxoff,
670671
case HEAPTUPLE_RECENTLY_DEAD:
671672

672673
/*
673-
* This tuple may soon become DEAD. Update the hint field so
674-
* that the page is reconsidered for pruning in future.
675-
*
676674
* We don't need to advance the conflict horizon for
677675
* RECENTLY_DEAD tuples, even if we are removing them. This
678676
* is because we only remove RECENTLY_DEAD tuples if they
@@ -681,8 +679,6 @@ heap_prune_chain(Page page, BlockNumber blockno, OffsetNumber maxoff,
681679
* tuple by virtue of being later in the chain. We will have
682680
* advanced the conflict horizon for the DEAD tuple.
683681
*/
684-
heap_prune_record_prunable(prstate,
685-
HeapTupleHeaderGetUpdateXid(htup));
686682

687683
/*
688684
* Advance past RECENTLY_DEAD tuples just in case there's a
@@ -693,24 +689,8 @@ heap_prune_chain(Page page, BlockNumber blockno, OffsetNumber maxoff,
693689
break;
694690

695691
case HEAPTUPLE_DELETE_IN_PROGRESS:
696-
697-
/*
698-
* This tuple may soon become DEAD. Update the hint field so
699-
* that the page is reconsidered for pruning in future.
700-
*/
701-
heap_prune_record_prunable(prstate,
702-
HeapTupleHeaderGetUpdateXid(htup));
703-
goto process_chain;
704-
705692
case HEAPTUPLE_LIVE:
706693
case HEAPTUPLE_INSERT_IN_PROGRESS:
707-
708-
/*
709-
* If we wanted to optimize for aborts, we might consider
710-
* marking the page prunable when we see INSERT_IN_PROGRESS.
711-
* But we don't. See related decisions about when to mark the
712-
* page prunable in heapam.c.
713-
*/
714694
goto process_chain;
715695

716696
default:
@@ -757,8 +737,15 @@ heap_prune_chain(Page page, BlockNumber blockno, OffsetNumber maxoff,
757737
* No DEAD tuple was found, so the chain is entirely composed of
758738
* normal, unchanged tuples. Leave it alone.
759739
*/
760-
for (int i = 0; i < nchain; i++)
761-
heap_prune_record_unchanged(prstate, chainitems[i]);
740+
int i = 0;
741+
742+
if (ItemIdIsRedirected(rootlp))
743+
{
744+
heap_prune_record_unchanged_lp_redirect(prstate, rootoffnum);
745+
i++;
746+
}
747+
for (; i < nchain; i++)
748+
heap_prune_record_unchanged_lp_normal(page, htsv, prstate, chainitems[i]);
762749
}
763750
else if (ndeadchain == nchain)
764751
{
@@ -784,7 +771,7 @@ heap_prune_chain(Page page, BlockNumber blockno, OffsetNumber maxoff,
784771

785772
/* the rest of tuples in the chain are normal, unchanged tuples */
786773
for (int i = ndeadchain; i < nchain; i++)
787-
heap_prune_record_unchanged(prstate, chainitems[i]);
774+
heap_prune_record_unchanged_lp_normal(page, htsv, prstate, chainitems[i]);
788775
}
789776
}
790777

@@ -894,9 +881,81 @@ heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum, bool was_norm
894881
prstate->ndeleted++;
895882
}
896883

897-
/* Record a line pointer that is left unchanged */
884+
/*
885+
* Record an unused line pointer that is left unchanged.
886+
*/
887+
static void
888+
heap_prune_record_unchanged_lp_unused(Page page, PruneState *prstate, OffsetNumber offnum)
889+
{
890+
Assert(!prstate->processed[offnum]);
891+
prstate->processed[offnum] = true;
892+
}
893+
894+
/*
895+
* Record LP_NORMAL line pointer that is left unchanged.
896+
*/
897+
static void
898+
heap_prune_record_unchanged_lp_normal(Page page, int8 *htsv, PruneState *prstate, OffsetNumber offnum)
899+
{
900+
HeapTupleHeader htup;
901+
902+
Assert(!prstate->processed[offnum]);
903+
prstate->processed[offnum] = true;
904+
905+
switch (htsv[offnum])
906+
{
907+
case HEAPTUPLE_LIVE:
908+
case HEAPTUPLE_INSERT_IN_PROGRESS:
909+
910+
/*
911+
* If we wanted to optimize for aborts, we might consider marking
912+
* the page prunable when we see INSERT_IN_PROGRESS. But we
913+
* don't. See related decisions about when to mark the page
914+
* prunable in heapam.c.
915+
*/
916+
break;
917+
918+
case HEAPTUPLE_RECENTLY_DEAD:
919+
case HEAPTUPLE_DELETE_IN_PROGRESS:
920+
921+
htup = (HeapTupleHeader) PageGetItem(page, PageGetItemId(page, offnum));
922+
923+
/*
924+
* This tuple may soon become DEAD. Update the hint field so that
925+
* the page is reconsidered for pruning in future.
926+
*/
927+
heap_prune_record_prunable(prstate,
928+
HeapTupleHeaderGetUpdateXid(htup));
929+
break;
930+
931+
932+
default:
933+
934+
/*
935+
* DEAD tuples should've been passed to heap_prune_record_dead()
936+
* or heap_prune_record_unused() instead.
937+
*/
938+
elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result %d", htsv[offnum]);
939+
break;
940+
}
941+
}
942+
943+
944+
/*
945+
* Record line pointer that was already LP_DEAD and is left unchanged.
946+
*/
947+
static void
948+
heap_prune_record_unchanged_lp_dead(Page page, PruneState *prstate, OffsetNumber offnum)
949+
{
950+
Assert(!prstate->processed[offnum]);
951+
prstate->processed[offnum] = true;
952+
}
953+
954+
/*
955+
* Record LP_REDIRECT that is left unchanged.
956+
*/
898957
static void
899-
heap_prune_record_unchanged(PruneState *prstate, OffsetNumber offnum)
958+
heap_prune_record_unchanged_lp_redirect(PruneState *prstate, OffsetNumber offnum)
900959
{
901960
Assert(!prstate->processed[offnum]);
902961
prstate->processed[offnum] = true;

0 commit comments

Comments
 (0)