diff options
Diffstat (limited to 'src/backend/access/heap/hio.c')
-rw-r--r-- | src/backend/access/heap/hio.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index d41d318eef9..a9c8ec43a7b 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -246,8 +246,14 @@ RelationAddExtraBlocks(Relation relation, BulkInsertState bistate) * Immediately update the bottom level of the FSM. This has a good * chance of making this page visible to other concurrently inserting * backends, and we want that to happen without delay. + * + * Since we know the table will end up with extraBlocks additional + * pages, we pass the final number to avoid possible unnecessary + * system calls and to make sure the FSM is created when we add the + * first new page. */ - RecordPageWithFreeSpace(relation, blockNum, freespace); + RecordPageWithFreeSpace(relation, blockNum, freespace, + firstBlock + extraBlocks); } while (--extraBlocks > 0); @@ -384,20 +390,9 @@ RelationGetBufferForTuple(Relation relation, Size len, * We have no cached target page, so ask the FSM for an initial * target. */ - targetBlock = GetPageWithFreeSpace(relation, len + saveFreeSpace); - - /* - * If the FSM knows nothing of the rel, try the last page before we - * give up and extend. This avoids one-tuple-per-page syndrome during - * bootstrapping or in a recently-started system. - */ - if (targetBlock == InvalidBlockNumber) - { - BlockNumber nblocks = RelationGetNumberOfBlocks(relation); - - if (nblocks > 0) - targetBlock = nblocks - 1; - } + targetBlock = GetPageWithFreeSpace(relation, + len + saveFreeSpace, + false); } loop: @@ -504,6 +499,13 @@ loop: { /* use this page as future insert target, too */ RelationSetTargetBlock(relation, targetBlock); + + /* + * In case we used an in-memory map of available blocks, reset it + * for next use. + */ + FSMClearLocalMap(); + return buffer; } @@ -563,9 +565,12 @@ loop: /* * Check if some other backend has extended a block for us while - * we were waiting on the lock. + * we were waiting on the lock. We only check the FSM -- if there + * isn't one we don't recheck the number of blocks. */ - targetBlock = GetPageWithFreeSpace(relation, len + saveFreeSpace); + targetBlock = GetPageWithFreeSpace(relation, + len + saveFreeSpace, + true); /* * If some other waiter has already extended the relation, we @@ -670,5 +675,11 @@ loop: */ RelationSetTargetBlock(relation, BufferGetBlockNumber(buffer)); + /* + * In case we used an in-memory map of available blocks, reset it for next + * use. + */ + FSMClearLocalMap(); + return buffer; } |