aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-04-06 00:29:51 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-04-06 00:29:51 +0000
commiteace269b4737806465a15d1ef314f02ff618ffc3 (patch)
tree5dd15adc6ab529d7b86e743a70d771452fbd932c
parent7c6bac0071c8ed0e47f63a88ed4f3a4e9a04edaa (diff)
downloadpostgresql-eace269b4737806465a15d1ef314f02ff618ffc3.tar.gz
postgresql-eace269b4737806465a15d1ef314f02ff618ffc3.zip
Repair assert failure in tuple-chain-moving logic (introduced by yours
truly, I'm afraid).
-rw-r--r--src/backend/commands/vacuum.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 32e72c4316e..c8498eddbce 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