Skip to content

Commit eace269

Browse files
committed
Repair assert failure in tuple-chain-moving logic (introduced by yours
truly, I'm afraid).
1 parent 7c6bac0 commit eace269

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

src/backend/commands/vacuum.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.144 2000/03/17 02:36:06 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.145 2000/04/06 00:29:51 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1510,6 +1510,8 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15101510
ItemPointerSetInvalid(&Ctid);
15111511
for (ti = 0; ti < num_vtmove; ti++)
15121512
{
1513+
VPageDescr destvpd = vtmove[ti].vpd;
1514+
15131515
/* Get tuple from chain */
15141516
tuple.t_self = vtmove[ti].tid;
15151517
Cbuf = ReadBuffer(onerel,
@@ -1521,7 +1523,7 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15211523
tuple.t_data = (HeapTupleHeader) PageGetItem(Cpage, Citemid);
15221524
tuple_len = tuple.t_len = ItemIdGetLength(Citemid);
15231525
/* Get page to move in */
1524-
cur_buffer = ReadBuffer(onerel, vtmove[ti].vpd->vpd_blkno);
1526+
cur_buffer = ReadBuffer(onerel, destvpd->vpd_blkno);
15251527

15261528
/*
15271529
* We should LockBuffer(cur_buffer) but don't, at the
@@ -1530,9 +1532,24 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15301532
* to get t_infomask of inserted heap tuple !!!
15311533
*/
15321534
ToPage = BufferGetPage(cur_buffer);
1533-
/* if this page was not used before - clean it */
1535+
/*
1536+
* If this page was not used before - clean it.
1537+
*
1538+
* This path is different from the other callers of
1539+
* vc_vacpage, because we have already incremented the
1540+
* vpd's vpd_offsets_used field to account for the
1541+
* tuple(s) we expect to move onto the page. Therefore
1542+
* vc_vacpage's check for vpd_offsets_used == 0 is wrong.
1543+
* But since that's a good debugging check for all other
1544+
* callers, we work around it here rather than remove it.
1545+
*/
15341546
if (!PageIsEmpty(ToPage) && vtmove[ti].cleanVpd)
1535-
vc_vacpage(ToPage, vtmove[ti].vpd);
1547+
{
1548+
int sv_offsets_used = destvpd->vpd_offsets_used;
1549+
destvpd->vpd_offsets_used = 0;
1550+
vc_vacpage(ToPage, destvpd);
1551+
destvpd->vpd_offsets_used = sv_offsets_used;
1552+
}
15361553
heap_copytuple_with_tuple(&tuple, &newtup);
15371554
RelationInvalidateHeapTuple(onerel, &tuple);
15381555
TransactionIdStore(myXID, (TransactionId *) &(newtup.t_data->t_cmin));
@@ -1543,17 +1560,16 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15431560
InvalidOffsetNumber, LP_USED);
15441561
if (newoff == InvalidOffsetNumber)
15451562
{
1546-
elog(ERROR, "\
1547-
moving chain: failed to add item with len = %u to page %u",
1548-
tuple_len, vtmove[ti].vpd->vpd_blkno);
1563+
elog(ERROR, "moving chain: failed to add item with len = %u to page %u",
1564+
tuple_len, destvpd->vpd_blkno);
15491565
}
15501566
newitemid = PageGetItemId(ToPage, newoff);
15511567
pfree(newtup.t_data);
15521568
newtup.t_datamcxt = NULL;
15531569
newtup.t_data = (HeapTupleHeader) PageGetItem(ToPage, newitemid);
1554-
ItemPointerSet(&(newtup.t_self), vtmove[ti].vpd->vpd_blkno, newoff);
1555-
if (((int) vtmove[ti].vpd->vpd_blkno) > last_move_dest_block)
1556-
last_move_dest_block = vtmove[ti].vpd->vpd_blkno;
1570+
ItemPointerSet(&(newtup.t_self), destvpd->vpd_blkno, newoff);
1571+
if (((int) destvpd->vpd_blkno) > last_move_dest_block)
1572+
last_move_dest_block = destvpd->vpd_blkno;
15571573

15581574
/*
15591575
* Set t_ctid pointing to itself for last tuple in

0 commit comments

Comments
 (0)