Mark Rae <[EMAIL PROTECTED]> writes:
> ERROR:  copy: line 26501638, insert_fsm_page_entry: failed to insert entry!

Ugh.  I think I see the problem: silly oversight in this routine.
Please apply the attached patch and see if it fixes the failure.

                        regards, tom lane

*** src/backend/storage/freespace/freespace.c.orig      Mon Nov  5 14:44:10 2001
--- src/backend/storage/freespace/freespace.c   Thu Jan 24 10:31:43 2002
***************
*** 8,14 ****
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   * IDENTIFICATION
!  *      $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.10 
2001/11/05 17:46:27 momjian Exp $
   *
   *
   * NOTES:
--- 8,14 ----
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   * IDENTIFICATION
!  *      $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.11 
2002/01/24 15:31:43 tgl Exp $
   *
   *
   * NOTES:
***************
*** 841,904 ****
  insert_fsm_page_entry(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail,
                                          FSMChunk *chunk, int chunkRelIndex)
  {
!       FSMChunk   *newChunk;
!       int                     newChunkRelIndex;
! 
!       if (fsmrel->numPages >= fsmrel->numChunks * CHUNKPAGES)
        {
!               /* No free space within chunk list, so need another chunk */
!               if ((newChunk = FreeSpaceMap->freeChunks) == NULL)
!                       return false;           /* can't do it */
!               FreeSpaceMap->freeChunks = newChunk->next;
!               FreeSpaceMap->numFreeChunks--;
!               newChunk->next = NULL;
!               newChunk->numPages = 0;
!               if (fsmrel->relChunks == NULL)
!                       fsmrel->relChunks = newChunk;
!               else
                {
!                       FSMChunk   *priorChunk = fsmrel->relChunks;
  
!                       while (priorChunk->next != NULL)
!                               priorChunk = priorChunk->next;
!                       priorChunk->next = newChunk;
                }
!               fsmrel->numChunks++;
!               if (chunk == NULL)
!               {
!                       /* Original search found that new page belongs at end */
!                       chunk = newChunk;
!                       chunkRelIndex = 0;
                }
-       }
  
!       /* Try to insert it the easy way, ie, just move down subsequent data */
!       if (chunk &&
!               push_fsm_page_entry(page, spaceAvail, chunk, chunkRelIndex))
!       {
!               fsmrel->numPages++;
!               fsmrel->nextPage++;             /* don't return same page twice 
running */
!               return true;
        }
- 
-       /*
-        * There is space available, but evidently it's before the place where
-        * the page entry needs to go.  Compact the list and try again. This
-        * will require us to redo the search for the appropriate place.
-        */
-       compact_fsm_page_list(fsmrel);
-       if (lookup_fsm_page_entry(fsmrel, page, &newChunk, &newChunkRelIndex))
-               elog(ERROR, "insert_fsm_page_entry: entry already exists!");
-       if (newChunk &&
-               push_fsm_page_entry(page, spaceAvail, newChunk, newChunkRelIndex))
-       {
-               fsmrel->numPages++;
-               fsmrel->nextPage++;             /* don't return same page twice 
running */
-               return true;
-       }
-       /* Shouldn't get here given the initial if-test for space available */
-       elog(ERROR, "insert_fsm_page_entry: failed to insert entry!");
-       return false;                           /* keep compiler quiet */
  }
  
  /*
--- 841,899 ----
  insert_fsm_page_entry(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail,
                                          FSMChunk *chunk, int chunkRelIndex)
  {
!       /* Outer loop handles retry after compacting rel's page list */
!       for (;;)
        {
!               if (fsmrel->numPages >= fsmrel->numChunks * CHUNKPAGES)
                {
!                       /* No free space within chunk list, so need another chunk */
!                       FSMChunk   *newChunk;
  
!                       if ((newChunk = FreeSpaceMap->freeChunks) == NULL)
!                               return false;           /* can't do it */
!                       FreeSpaceMap->freeChunks = newChunk->next;
!                       FreeSpaceMap->numFreeChunks--;
!                       newChunk->next = NULL;
!                       newChunk->numPages = 0;
!                       if (fsmrel->relChunks == NULL)
!                               fsmrel->relChunks = newChunk;
!                       else
!                       {
!                               FSMChunk   *priorChunk = fsmrel->relChunks;
! 
!                               while (priorChunk->next != NULL)
!                                       priorChunk = priorChunk->next;
!                               priorChunk->next = newChunk;
!                       }
!                       fsmrel->numChunks++;
!                       if (chunk == NULL)
!                       {
!                               /* Original search found that new page belongs at end 
*/
!                               chunk = newChunk;
!                               chunkRelIndex = 0;
!                       }
                }
! 
!               /* Try to insert it the easy way, ie, just move down subsequent data */
!               if (chunk &&
!                       push_fsm_page_entry(page, spaceAvail, chunk, chunkRelIndex))
!               {
!                       fsmrel->numPages++;
!                       fsmrel->nextPage++;             /* don't return same page 
twice running */
!                       return true;
                }
  
!               /*
!                * There is space available, but evidently it's before the place where
!                * the page entry needs to go.  Compact the list and try again. This
!                * will require us to redo the search for the appropriate place.
!                * Furthermore, compact_fsm_page_list deletes empty end chunks, so
!                * we may need to repeat the action of grabbing a new end chunk.
!                */
!               compact_fsm_page_list(fsmrel);
!               if (lookup_fsm_page_entry(fsmrel, page, &chunk, &chunkRelIndex))
!                       elog(ERROR, "insert_fsm_page_entry: entry already exists!");
        }
  }
  
  /*

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Reply via email to