Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit386f180

Browse files
committed
Fix logic error in insert_fsm_page_entry: because compact_fsm_page_list
removes any empty chunks, the chunk previously added won't be thereanymore, so it's possible there is zero free space in the rel's page listafterwards. Must loop back and rerun the part that adds a chunk tothe list.
1 parentcf77a2a commit386f180

File tree

1 file changed

+46
-51
lines changed

1 file changed

+46
-51
lines changed

‎src/backend/storage/freespace/freespace.c

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.10 2001/11/05 17:46:27 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.11 2002/01/24 15:31:43 tgl Exp $
1212
*
1313
*
1414
* NOTES:
@@ -841,64 +841,59 @@ static bool
841841
insert_fsm_page_entry(FSMRelation*fsmrel,BlockNumberpage,SizespaceAvail,
842842
FSMChunk*chunk,intchunkRelIndex)
843843
{
844-
FSMChunk*newChunk;
845-
intnewChunkRelIndex;
846-
847-
if (fsmrel->numPages >=fsmrel->numChunks*CHUNKPAGES)
844+
/* Outer loop handles retry after compacting rel's page list */
845+
for (;;)
848846
{
849-
/* No free space within chunk list, so need another chunk */
850-
if ((newChunk=FreeSpaceMap->freeChunks)==NULL)
851-
return false;/* can't do it */
852-
FreeSpaceMap->freeChunks=newChunk->next;
853-
FreeSpaceMap->numFreeChunks--;
854-
newChunk->next=NULL;
855-
newChunk->numPages=0;
856-
if (fsmrel->relChunks==NULL)
857-
fsmrel->relChunks=newChunk;
858-
else
847+
if (fsmrel->numPages >=fsmrel->numChunks*CHUNKPAGES)
859848
{
860-
FSMChunk*priorChunk=fsmrel->relChunks;
849+
/* No free space within chunk list, so need another chunk */
850+
FSMChunk*newChunk;
851+
852+
if ((newChunk=FreeSpaceMap->freeChunks)==NULL)
853+
return false;/* can't do it */
854+
FreeSpaceMap->freeChunks=newChunk->next;
855+
FreeSpaceMap->numFreeChunks--;
856+
newChunk->next=NULL;
857+
newChunk->numPages=0;
858+
if (fsmrel->relChunks==NULL)
859+
fsmrel->relChunks=newChunk;
860+
else
861+
{
862+
FSMChunk*priorChunk=fsmrel->relChunks;
861863

862-
while (priorChunk->next!=NULL)
863-
priorChunk=priorChunk->next;
864-
priorChunk->next=newChunk;
864+
while (priorChunk->next!=NULL)
865+
priorChunk=priorChunk->next;
866+
priorChunk->next=newChunk;
867+
}
868+
fsmrel->numChunks++;
869+
if (chunk==NULL)
870+
{
871+
/* Original search found that new page belongs at end */
872+
chunk=newChunk;
873+
chunkRelIndex=0;
874+
}
865875
}
866-
fsmrel->numChunks++;
867-
if (chunk==NULL)
876+
877+
/* Try to insert it the easy way, ie, just move down subsequent data */
878+
if (chunk&&
879+
push_fsm_page_entry(page,spaceAvail,chunk,chunkRelIndex))
868880
{
869-
/* Original search found that new page belongs at end */
870-
chunk=newChunk;
871-
chunkRelIndex=0;
881+
fsmrel->numPages++;
882+
fsmrel->nextPage++;/* don't return same page twice running */
883+
return true;
872884
}
873-
}
874885

875-
/* Try to insert it the easy way, ie, just move down subsequent data */
876-
if (chunk&&
877-
push_fsm_page_entry(page,spaceAvail,chunk,chunkRelIndex))
878-
{
879-
fsmrel->numPages++;
880-
fsmrel->nextPage++;/* don't return same page twice running */
881-
return true;
882-
}
883-
884-
/*
885-
* There is space available, but evidently it's before the place where
886-
* the page entry needs to go.Compact the list and try again. This
887-
* will require us to redo the search for the appropriate place.
888-
*/
889-
compact_fsm_page_list(fsmrel);
890-
if (lookup_fsm_page_entry(fsmrel,page,&newChunk,&newChunkRelIndex))
891-
elog(ERROR,"insert_fsm_page_entry: entry already exists!");
892-
if (newChunk&&
893-
push_fsm_page_entry(page,spaceAvail,newChunk,newChunkRelIndex))
894-
{
895-
fsmrel->numPages++;
896-
fsmrel->nextPage++;/* don't return same page twice running */
897-
return true;
886+
/*
887+
* There is space available, but evidently it's before the place where
888+
* the page entry needs to go.Compact the list and try again. This
889+
* will require us to redo the search for the appropriate place.
890+
* Furthermore, compact_fsm_page_list deletes empty end chunks, so
891+
* we may need to repeat the action of grabbing a new end chunk.
892+
*/
893+
compact_fsm_page_list(fsmrel);
894+
if (lookup_fsm_page_entry(fsmrel,page,&chunk,&chunkRelIndex))
895+
elog(ERROR,"insert_fsm_page_entry: entry already exists!");
898896
}
899-
/* Shouldn't get here given the initial if-test for space available */
900-
elog(ERROR,"insert_fsm_page_entry: failed to insert entry!");
901-
return false;/* keep compiler quiet */
902897
}
903898

904899
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp