diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 32e72c4316..c8498eddbc 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.144 2000/03/17 02:36:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.145 2000/04/06 00:29:51 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1510,6 +1510,8 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel, ItemPointerSetInvalid(&Ctid); for (ti = 0; ti < num_vtmove; ti++) { + VPageDescr destvpd = vtmove[ti].vpd; + /* Get tuple from chain */ tuple.t_self = vtmove[ti].tid; Cbuf = ReadBuffer(onerel, @@ -1521,7 +1523,7 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel, tuple.t_data = (HeapTupleHeader) PageGetItem(Cpage, Citemid); tuple_len = tuple.t_len = ItemIdGetLength(Citemid); /* Get page to move in */ - cur_buffer = ReadBuffer(onerel, vtmove[ti].vpd->vpd_blkno); + cur_buffer = ReadBuffer(onerel, destvpd->vpd_blkno); /* * We should LockBuffer(cur_buffer) but don't, at the @@ -1530,9 +1532,24 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel, * to get t_infomask of inserted heap tuple !!! */ ToPage = BufferGetPage(cur_buffer); - /* if this page was not used before - clean it */ + /* + * If this page was not used before - clean it. + * + * This path is different from the other callers of + * vc_vacpage, because we have already incremented the + * vpd's vpd_offsets_used field to account for the + * tuple(s) we expect to move onto the page. Therefore + * vc_vacpage's check for vpd_offsets_used == 0 is wrong. + * But since that's a good debugging check for all other + * callers, we work around it here rather than remove it. + */ if (!PageIsEmpty(ToPage) && vtmove[ti].cleanVpd) - vc_vacpage(ToPage, vtmove[ti].vpd); + { + int sv_offsets_used = destvpd->vpd_offsets_used; + destvpd->vpd_offsets_used = 0; + vc_vacpage(ToPage, destvpd); + destvpd->vpd_offsets_used = sv_offsets_used; + } heap_copytuple_with_tuple(&tuple, &newtup); RelationInvalidateHeapTuple(onerel, &tuple); TransactionIdStore(myXID, (TransactionId *) &(newtup.t_data->t_cmin)); @@ -1543,17 +1560,16 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel, InvalidOffsetNumber, LP_USED); if (newoff == InvalidOffsetNumber) { - elog(ERROR, "\ -moving chain: failed to add item with len = %u to page %u", - tuple_len, vtmove[ti].vpd->vpd_blkno); + elog(ERROR, "moving chain: failed to add item with len = %u to page %u", + tuple_len, destvpd->vpd_blkno); } newitemid = PageGetItemId(ToPage, newoff); pfree(newtup.t_data); newtup.t_datamcxt = NULL; newtup.t_data = (HeapTupleHeader) PageGetItem(ToPage, newitemid); - ItemPointerSet(&(newtup.t_self), vtmove[ti].vpd->vpd_blkno, newoff); - if (((int) vtmove[ti].vpd->vpd_blkno) > last_move_dest_block) - last_move_dest_block = vtmove[ti].vpd->vpd_blkno; + ItemPointerSet(&(newtup.t_self), destvpd->vpd_blkno, newoff); + if (((int) destvpd->vpd_blkno) > last_move_dest_block) + last_move_dest_block = destvpd->vpd_blkno; /* * Set t_ctid pointing to itself for last tuple in