aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/heap/hio.c5
-rw-r--r--src/backend/storage/freespace/freespace.c19
2 files changed, 19 insertions, 5 deletions
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index a9c8ec43a7b..69a7a23874f 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -675,10 +675,7 @@ loop:
*/
RelationSetTargetBlock(relation, BufferGetBlockNumber(buffer));
- /*
- * In case we used an in-memory map of available blocks, reset it for next
- * use.
- */
+ /* This should already be cleared by now, but make sure it is. */
FSMClearLocalMap();
return buffer;
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index d3f207b8540..849685f5a07 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -97,7 +97,16 @@ typedef struct
/* Address of the root page. */
static const FSMAddress FSM_ROOT_ADDRESS = {FSM_ROOT_LEVEL, 0};
-/* Local map of block numbers for small heaps with no FSM. */
+/*
+ * For small relations, we don't create FSM to save space, instead we use
+ * local in-memory map of pages to try. To locate free space, we simply try
+ * pages directly without knowing ahead of time how much free space they have.
+ *
+ * Note that this map is used to the find the block with required free space
+ * for any given relation. We clear this map when we have found a block with
+ * enough free space, when we extend the relation, or on transaction abort.
+ * See src/backend/storage/freespace/README for further details.
+ */
typedef struct
{
BlockNumber nblocks;
@@ -1175,5 +1184,13 @@ fsm_local_search(void)
return target_block;
} while (target_block > 0);
+ /*
+ * If we didn't find any available block to try in the local map, then
+ * clear it. This prevents us from using the map again without setting it
+ * first, which would otherwise lead to the same conclusion again and
+ * again.
+ */
+ FSMClearLocalMap();
+
return InvalidBlockNumber;
}