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

Commit9ea7388

Browse files
committed
Second try at fixing no-room-to-move-down PANIC in compact_fsm_storage.
Ward's report that it can still happen in RC2 forces me to realize thatthis is not a can't-happen condition after all, and that the compactioncode had better cope rather than panicking.
1 parent5392e73 commit9ea7388

File tree

1 file changed

+47
-17
lines changed

1 file changed

+47
-17
lines changed

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

Lines changed: 47 additions & 17 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.24 2003/10/29 17:36:57 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.25 2003/11/26 20:50:11 tgl Exp $
1212
*
1313
*
1414
* NOTES:
@@ -1394,6 +1394,7 @@ static void
13941394
compact_fsm_storage(void)
13951395
{
13961396
intnextChunkIndex=0;
1397+
booldid_push= false;
13971398
FSMRelation*fsmrel;
13981399

13991400
for (fsmrel=FreeSpaceMap->firstRel;
@@ -1419,16 +1420,15 @@ compact_fsm_storage(void)
14191420
newAllocPages=newAlloc*INDEXCHUNKPAGES;
14201421
else
14211422
newAllocPages=newAlloc*CHUNKPAGES;
1422-
newChunkIndex=nextChunkIndex;
1423-
nextChunkIndex+=newAlloc;
14241423

14251424
/*
14261425
* Determine current size, current and new locations
14271426
*/
14281427
curChunks=fsm_current_chunks(fsmrel);
14291428
oldChunkIndex=fsmrel->firstChunk;
1430-
newLocation=FreeSpaceMap->arena+newChunkIndex*CHUNKBYTES;
14311429
oldLocation=FreeSpaceMap->arena+oldChunkIndex*CHUNKBYTES;
1430+
newChunkIndex=nextChunkIndex;
1431+
newLocation=FreeSpaceMap->arena+newChunkIndex*CHUNKBYTES;
14321432

14331433
/*
14341434
* It's possible that we have to move data down, not up, if the
@@ -1440,10 +1440,16 @@ compact_fsm_storage(void)
14401440
* more than once, so pack everything against the end of the arena
14411441
* if so.
14421442
*
1443-
* In corner cases where roundoff has affected our allocation, it's
1444-
* possible that we have to move down and compress our data too.
1445-
* Since this case is extremely infrequent, we do not try to be smart
1446-
* about it --- we just drop pages from the end of the rel's data.
1443+
* In corner cases where we are on the short end of a roundoff choice
1444+
* that we were formerly on the long end of, it's possible that we
1445+
* have to move down and compress our data too. In fact, even after
1446+
* pushing down the following rels, there might not be as much space
1447+
* as we computed for this rel above --- that would imply that some
1448+
* following rel(s) are also on the losing end of roundoff choices.
1449+
* We could handle this fairly by doing the per-rel compactions
1450+
* out-of-order, but that seems like way too much complexity to deal
1451+
* with a very infrequent corner case. Instead, we simply drop pages
1452+
* from the end of the current rel's data until it fits.
14471453
*/
14481454
if (newChunkIndex>oldChunkIndex)
14491455
{
@@ -1455,21 +1461,44 @@ compact_fsm_storage(void)
14551461
fsmrel->storedPages=newAllocPages;
14561462
curChunks=fsm_current_chunks(fsmrel);
14571463
}
1464+
/* is there enough space? */
14581465
if (fsmrel->nextPhysical!=NULL)
14591466
limitChunkIndex=fsmrel->nextPhysical->firstChunk;
14601467
else
14611468
limitChunkIndex=FreeSpaceMap->totalChunks;
14621469
if (newChunkIndex+curChunks>limitChunkIndex)
14631470
{
1464-
/* need to push down additional rels */
1465-
push_fsm_rels_after(fsmrel);
1466-
/* recheck for safety */
1471+
/* not enough space, push down following rels */
1472+
if (!did_push)
1473+
{
1474+
push_fsm_rels_after(fsmrel);
1475+
did_push= true;
1476+
}
1477+
/* now is there enough space? */
14671478
if (fsmrel->nextPhysical!=NULL)
14681479
limitChunkIndex=fsmrel->nextPhysical->firstChunk;
14691480
else
14701481
limitChunkIndex=FreeSpaceMap->totalChunks;
14711482
if (newChunkIndex+curChunks>limitChunkIndex)
1472-
elog(PANIC,"insufficient room in FSM");
1483+
{
1484+
/* uh-oh, forcibly cut the allocation to fit */
1485+
newAlloc=limitChunkIndex-newChunkIndex;
1486+
/*
1487+
* If newAlloc < 0 at this point, we are moving the rel's
1488+
* firstChunk into territory currently assigned to a later
1489+
* rel. This is okay so long as we do not copy any data.
1490+
* The rels will be back in nondecreasing firstChunk order
1491+
* at completion of the compaction pass.
1492+
*/
1493+
if (newAlloc<0)
1494+
newAlloc=0;
1495+
if (fsmrel->isIndex)
1496+
newAllocPages=newAlloc*INDEXCHUNKPAGES;
1497+
else
1498+
newAllocPages=newAlloc*CHUNKPAGES;
1499+
fsmrel->storedPages=newAllocPages;
1500+
curChunks=fsm_current_chunks(fsmrel);
1501+
}
14731502
}
14741503
memmove(newLocation,oldLocation,curChunks*CHUNKBYTES);
14751504
}
@@ -1504,6 +1533,7 @@ compact_fsm_storage(void)
15041533
memmove(newLocation,oldLocation,curChunks*CHUNKBYTES);
15051534
}
15061535
fsmrel->firstChunk=newChunkIndex;
1536+
nextChunkIndex+=newAlloc;
15071537
}
15081538
Assert(nextChunkIndex <=FreeSpaceMap->totalChunks);
15091539
FreeSpaceMap->usedChunks=nextChunkIndex;
@@ -1544,8 +1574,8 @@ push_fsm_rels_after(FSMRelation *afterRel)
15441574
oldChunkIndex=fsmrel->firstChunk;
15451575
if (newChunkIndex<oldChunkIndex)
15461576
{
1547-
/*trouble... */
1548-
elog(PANIC,"insufficient room in FSM");
1577+
/*we're pushing down, how can it move up? */
1578+
elog(PANIC,"inconsistent entry sizes in FSM");
15491579
}
15501580
elseif (newChunkIndex>oldChunkIndex)
15511581
{
@@ -1758,14 +1788,14 @@ fsm_current_chunks(FSMRelation *fsmrel)
17581788
{
17591789
intchunkCount;
17601790

1791+
/* Make sure storedPages==0 produces right answer */
1792+
if (fsmrel->storedPages <=0)
1793+
return0;
17611794
/* Convert page count to chunk count */
17621795
if (fsmrel->isIndex)
17631796
chunkCount= (fsmrel->storedPages-1) /INDEXCHUNKPAGES+1;
17641797
else
17651798
chunkCount= (fsmrel->storedPages-1) /CHUNKPAGES+1;
1766-
/* Make sure storedPages==0 produces right answer */
1767-
if (chunkCount<0)
1768-
chunkCount=0;
17691799
returnchunkCount;
17701800
}
17711801

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp