From: Tom Lane Date: Wed, 29 Oct 2003 17:36:57 +0000 (+0000) Subject: compact_fsm_storage() does need to handle the case where a relation's X-Git-Url: http://waps.l3s.uni-hannover.de/gitweb/?a=commitdiff_plain;h=4882b28e58758f5655fd1bd7d6dc35759c0e67b9;p=users%2Fbernd%2Fpostgres.git compact_fsm_storage() does need to handle the case where a relation's FSM data has to be both moved down and compressed. Per report from Dror Matalon. --- diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index a172c4aa48..4ce97778ac 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -1432,19 +1432,29 @@ compact_fsm_storage(void) /* * It's possible that we have to move data down, not up, if the - * allocations of previous rels expanded. This should mean that + * allocations of previous rels expanded. This normally means that * our allocation expanded too (or at least got no worse), and - * ditto for later rels. So there should be room --- but we might - * have to push down following rels to make it. We don't want to - * do the push more than once, so pack everything against the end - * of the arena if so. + * ditto for later rels. So there should be room to move all our + * data down without dropping any --- but we might have to push down + * following rels to acquire the room. We don't want to do the push + * more than once, so pack everything against the end of the arena + * if so. + * + * In corner cases where roundoff has affected our allocation, it's + * possible that we have to move down and compress our data too. + * Since this case is extremely infrequent, we do not try to be smart + * about it --- we just drop pages from the end of the rel's data. */ if (newChunkIndex > oldChunkIndex) { int limitChunkIndex; if (newAllocPages < fsmrel->storedPages) - elog(PANIC, "can't juggle and compress too"); + { + /* move and compress --- just drop excess pages */ + fsmrel->storedPages = newAllocPages; + curChunks = fsm_current_chunks(fsmrel); + } if (fsmrel->nextPhysical != NULL) limitChunkIndex = fsmrel->nextPhysical->firstChunk; else @@ -1459,7 +1469,7 @@ compact_fsm_storage(void) else limitChunkIndex = FreeSpaceMap->totalChunks; if (newChunkIndex + curChunks > limitChunkIndex) - elog(PANIC, "insufficient room"); + elog(PANIC, "insufficient room in FSM"); } memmove(newLocation, oldLocation, curChunks * CHUNKBYTES); } @@ -1535,7 +1545,7 @@ push_fsm_rels_after(FSMRelation *afterRel) if (newChunkIndex < oldChunkIndex) { /* trouble... */ - elog(PANIC, "out of room"); + elog(PANIC, "insufficient room in FSM"); } else if (newChunkIndex > oldChunkIndex) {