aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/heap/hio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/heap/hio.c')
-rw-r--r--src/backend/access/heap/hio.c45
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;
}